常见排序java实现

1.冒泡排序

  冒泡排序是不是稳定的主要根据 IF 判断的条件进行判断,若相同元素不发生交换,那么这就是稳定的

 1 public static void maopao(int[] arr)
 2         {
 3             for (int i = 0; i < arr.Length; i++)
 4             {
 5                 for (int j = 0; j < arr.Length - 1 - i; j++)
 6                 {
 7                     if (arr[j] > arr[j + 1])
 8                     {
 9                         int temp = arr[j + 1];
10                         arr[j + 1] = arr[j];
11                         arr[j] = temp;
12                     }
13                 }
14             }
15         }

2.快速排序

  快速排序是不稳定的,主要发生的原因在基准值与左右游动的下标元素之间,例如:3 3 7 2 8 9 ,在这里第一个 3 会与 2 发生交换,导致两个 3 的相对位置发生变化。

我这里是使用递归实现,用循环也可以实现。

 1 public static void quickSort(int[] arr, int begin, int end)
 2         {
 3             if (begin >= end) return;
 4             int a = begin;
 5             int b = end;
 6             int jizhun = arr[begin];
 7             int index = end;
 8             while (begin < end)
 9             {
10                 //如果基准值大于元素值,元素值要插入到起始位
11                 if (jizhun > arr[index])
12                 {
13                     arr[begin] = arr[index];
14                     begin++;
15                     index = begin;
16                 }
17                 else {
18                     arr[end] = arr[index];
19                     end--;
20                     index = end;
21                 }
22                 if (begin == end)
23                 {
24                     arr[begin] = jizhun;
25                 }
26             }
27             quickSort(arr, a, index - 1);
28             quickSort(arr, index + 1, b);
29         }

3.插入排序

  插入排序是稳定的排序,因为这种排序每次比较的步长只有1 ,不会出现跳跃的情况,有人可能会觉得插入排序和冒泡排序简直就是一摸一样,有什么区别的?这个疑问一开始我也有,后来根据资料,插入排序与冒泡排序的区别主要在内层循环 ,如果需要排序的集合是有序的,那么插入排序的内层比较的次数相对于冒泡排序将会大大较少。但是冒泡排序可以优化,当不发生交换的时候结束内层 for 循环,这样的话两种的区别就基本没有了。

public static void insertSort(int[] arr)
        {
            for (int i = 0; i < arr.Length - 1; i++)
            {
                int begin = i;

                while (arr[begin + 1] < arr[begin])
                {
                    int temp = arr[begin + 1];
                    arr[begin + 1] = arr[begin];
                    arr[begin] = temp;
                    begin--;
                    if (begin < 0) break;
                }


            }
        }

4.希尔排序

  希尔排序其本质就是插入排序,只是插入排序每次的步长都是1,而希尔排序的步长是在逐步缩减,可以将位置变化大的数据迅速放到前面或者后面,相对于插入排序来说减少了移动的次序。但是由于这个特性,导致希尔排序变成不稳定的,在大幅度移动的过程中,其稳定性被破坏,例如 98 98 1 34 5 在这个例子中,第一个98 在步长为2 的情况下会被移动到5的位置,这样相对第二个98 ,他从前面移动到了后面,丢失稳定性。

  

public static void xierSort(int[] arr, int step)
        {
            if (step == 0) return;
            for (int i = 0; i < arr.Length - step; i++)
            {
                int begin = i;
                while (arr[begin] > arr[begin + step])
                {
                    int temp = arr[begin + step];
                    arr[begin + step] = arr[begin];
                    arr[begin] = temp;
                    begin = begin - step;
                    if (begin < 0) break;
                }
            }
            show(arr);
            xierSort(arr, step / 2);
        }

5.选择排序

  选择排序的思想是在一次循环中找到最小的元素下标,然后和起始元素进行交换,这种也是不稳定的,例如 5 5 1 6 7 在这个集合中 第一个5会在第一次交换中与 1 发生教会,稳定性丢失

  

 public static void selectSort(int[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                int minIndex = i;
                for (int j = i; j < arr.Length; j++)
                {
                    //  > 正序 < 倒叙
                    if (arr[minIndex] > arr[j])
                    {
                        minIndex = j;
                    }
                }
                int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }

 

6.归并排序

  归并排序的思想是永远保证左右是有序的,这是前提,如果不是有序的就递归下去,知道左右各有1个元素时,进行交换,归并排序是稳定的。

public static void guibingSort(int[] arr, int low, int high)
        {
            if (low == high) return ;
            int middle = (high + low - 1) / 2;
            guibingSort(arr, low, middle);
            guibingSort(arr, middle + 1, high);

            int[] temp = new int[high - low+1];
            //前一个数组的指针
            int i = low;
            //后一个数组的指针
            int j = middle + 1;
            //临时数组指针
            int index = 0;

            while (i <= middle && j <= high)
            {
                temp[index++] = arr[i] <= arr[j] ? arr[i++]:arr[j++] ;  
            }

            //多余元素写入
            while (i <= middle)
            {
                temp[index++] = arr[i++];
            }
            while (j <= high)
            {
                temp[index++] = arr[j++];
            }

            for (int m = 0; m < temp.Length; m++)
            {
                arr[low + m] = temp[m];
            }
        }

7.基数排序

  空间换时间的排序方式,是稳定的,用队列实现,如果用数组实现,需要记录桶中元素的个数,才能保证先进先出

  

public static void jizhuSort(int[] arr)
        {
            //产生10个桶
            queue[] bar = new queue[10];
            for (int i = 0; i < bar.Length; i++)
            {
                bar[i] = new queue();
            }
            bool go = true;
            for (int k = 0; go ; k++)
            {
                int O = 0;
                //所有数字存入桶中,第一次
                for (int i = 0; i < arr.Length; i++)
                {
                    for (int j = 0; j < bar.Length; j++)
                    {
                        int a = (int)(arr[i] / Math.Pow(10, k)) % 10;
                        if (a == j)
                        {
                            if (j != 0) O = j;
                            bar[j].add(arr[i]);
                        }
                    }
                }

                //取出所有数字
                for (int i = 0,m = 0; i < bar.Length; i++)
                {
                    while (!bar[i].isempty())
                    {
                        arr[m++] = bar[i].push();
                    }
                }
                if (O == 0) go = false;
            }



        }

 

posted @ 2021-03-04 09:09  二五树  阅读(54)  评论(0编辑  收藏  举报