TheAlgorithms / Go

Algorithms and Data Structures implemented in Go for beginners, following best practices.
https://the-algorithms.com/language/go
MIT License
14.79k stars 2.49k forks source link

Use generics in sorting algorithms #419

Open meetvalani opened 2 years ago

meetvalani commented 2 years ago

Description IMO algorithm should be working on data type float64 instead of int.

For enhancement:

siriak commented 2 years ago

Why should it be float instead of int? The only thing we need from the type is a linear order, so both of them should be perfectly fine.

raklaptudirm commented 2 years ago

I believe they think then the functions can be used in more cases, like where the numbers to be sorted are decimals.

meetvalani commented 2 years ago

To make sorting algorithms more usable it should be able to sort fractional numbers too. By using int we're limiting the scope of use to some use cases only.

raklaptudirm commented 2 years ago

A simple type change should work, and it may reduce the number of type conversions we have to do for using float64 functions, and, as mentioned, more use cases.

siriak commented 2 years ago

Wouldn't we need to convert integers to float if we want to sort them? If so, where's the benefit? In any case, we need to do some conversion.

meetvalani commented 2 years ago

We should provide support for the data type that has highest precision, float64 in golang. That way we can guarantee support for all the data types with less precision such as int, float32 etc, of course with additional conversation. But using only int won't allow us to use fractional numbers. Go devs are also following same practices of using float64. ex: https://pkg.go.dev/math#Max

tjgurwara99 commented 2 years ago

Honestly, the implementation of the sorting algorithms should not be changed right now because generics are coming to GO 🔥 next year.

But if you want to make the algorithms more general, I don't think the approach is to use float. The general idea I use in my personal projects is something along the lines of this:

package sort

import  (
    "fmt"
    "reflect"
)

...

func Bubble(data interface{}, swap func(i, j int), less func(i, j int) bool) error {
    s := reflect.ValueOf(data)
    if s.Kind() != reflect.Slice {
        // in this case it is actually valid to panic as well but I'm just returning an error
        return fmt.Errorf("Given data is not of Slice type.") 
    }
    for i := 0; i < s.Len(); i++ {
        for j := 0; j < s.Len(); j++ {
            if less(i, j) {
                swap(i, j)
            }
        }
    }
    return nil
}

working example is here: Go playground

Here you can pass in whatever type you want (yes even custom types would work - I use this approach in my personal projects a lot) and it would work as expected. In fact, you don't even need to write a swapper function, there is one that reflect package provides. But this is going too much into the territory of generics and I personally think that this repository needs to be as simple as possible because its mainly for learners. Personally I think since this is for learning purposes only, having sorting algorithms (as simple as possible and) only work for ints is perfectly acceptable.

EDIT: Here's the working example without explicitly defined swapper - uses reflect package: Go Playground

tjgurwara99 commented 2 years ago

We should provide support for the data type that has highest precision, float64 in golang. That way we can guarantee support for all the data types with less precision such as int, float32 etc, of course with additional conversation. But using only int won't allow us to use fractional numbers. Go devs are also following same practices of using float64. ex: https://pkg.go.dev/math#Max

The problem with this is that if I have a slice of type int the whole slice would need to be converted before I even begin to sort the slices, this is more computationally expensive and also take memory that should not be taken for converting to and from float64. converting a slice of float64 to slice of int takes O(n) time which adds to the cost of computation.

raklaptudirm commented 2 years ago

We should wait for the generics to be implemented and then revamp all the sorts.

tjgurwara99 commented 2 years ago

In case someone wants to experiment with generics here is the link to the GoTip playground to test out new features 😄 Here's my example of bubble sort

UPDATE: Syntax for generics changed. Bubble sort using new syntax

tjgurwara99 commented 2 years ago

closed in #483

tjgurwara99 commented 2 years ago

Closed by mistake, we still have three sorting algorithms that need to be modified to use the generic. Heap sort, radix sort and pigeonhole sort all require some refactoring for us to be able to convert them to generic sorting algorithms.

m4salah commented 1 year ago

@tjgurwara99 can you assign this to me

tjgurwara99 commented 1 year ago

You don't need an assignment of issues. Feel free to open a PR and we would review it 😄

VUHAILAM commented 1 year ago

I researched radix sort can apply for string: https://www.quora.com/How-can-I-sort-strings-using-Radix-Sort. But our radix sort is only for Integer. Should we implement another radix sort can apply both??

tjgurwara99 commented 1 year ago

But our radix sort is only for Integer.

Yes, therefore we have this issue to convert it to a generic one.

Should we implement another radix sort can apply both??

Radix sort is Radix sort, therefore there is really no difference in them unless you take a radically novel approach to writing this algorithm. Therefore, my suggestion is to modify the existing one, unless your implementation is resulting in a difference in complexity (either space or time)

badsector998 commented 3 months ago

But our radix sort is only for Integer.

Yes, therefore we have this issue to convert it to a generic one.

I'd like to collaborate more on this. By converting integer to generic, do you mean we want to apply radix sort that can accept other data type beside integer?

siriak commented 3 months ago

Yes. As it was already mentioned, it can be applied to strings. Integers are numbers base 10 and this sort can apply to numbers with any base, but representing them is problematic. We could use strings for that though like we use strings to represent hex numbers.

badsector998 commented 3 months ago

I have been thinking, since it can sort string and integer or any base number type, can we try to sort them by their binary representation? If we sort them by keeping the native data type I think the implementation wouldn't be generic. I am planning to dig deep on this and may be trying some implementation too by this weekend.