java中几种简单排序

来源:互联网 发布:怎么破解软件密码 编辑:程序博客网 时间:2024/05/22 02:06

冒泡排序

冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。

冒泡排序算法的运作如下:(从后往前)
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

这里写图片描述
这里写图片描述
从上图我们可以很清楚的看出来,在排序的过程中,键值较小的记录好比气泡一样向上漂浮,键值较大的记录则向下沉。


代码实现:

package simpleSort;public class BubbleSort {   public static void bubbleSort(int[] a){       int out,in;       int temp = 0;       for(out=a.length-1;out>1;out--)      //外循环       {           for(in=0;in<out;in++)            //内循环           {               if (a[in+1]<a[in])               {                   temp = a[in];                   a[in] = a[in+1];                   a[in+1] = temp;               }           }       }   }   public static void main(String[] args){       int[] a={77,99,44,55,22,88,11,0,66,33};       System.out.println("排序前");       for(int number:a){           System.out.print(number+" ");       }       System.out.println();       bubbleSort(a);       System.out.println("排序后");       for(int number:a){           System.out.print(number+" ");       }   }}

这里写图片描述


结果如下:这里写图片描述

根据上面这种冒泡实现,若原数组本身就是有序的(这是最好情况),仅需n-1次比较就可完成;若是倒序,比较次数为 n-1+n-2+…+1=n(n-1)/2,交换次数和比较次数等值。所以,其时间复杂度依然为O(n²)


选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。

选择排序改进了冒泡排序,将必要的交换次数从O(n²)减少到O(n),但是比较次数仍是O(n²)。然而,选择排序仍然为大记录量的排序提出了一个非常重要的改进,因为这些大量的记录需要在内存中移动,这就使交换的时间和比较的时间相比起来,交换的时间更为重要。

选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。比较次数O(n²),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+…+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

在算法实现时,每一趟确定最小元素的时候会通过不断地比较交换来使得首位置为当前最小,交换是个比较耗时的操作。其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。我们可以通过设置一个变量min,每一次比较仅存储较小元素的数组下标,当轮循环结束之后,那这个变量存储的就是当前最小元素的下标,此时再执行交换操作即可。
这里写图片描述
选择排序的示例动画。红色表示当前最小值,黄色表示已排序序列,蓝色表示当前位置。
这里写图片描述

其时间复杂度和冒泡排序一样,依然为O(n²)

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。

简单选择排序
代码如下:

package simpleSort;public class SimpleSelelctionSort {   public static void simpleSelectionSort(int arr[]){       int i, j, min, temp, len = arr.length;        for(i=0;i<len-1;i++){            min = i;            for (j = i + 1; j < len; j++){                      if (arr[min]>arr[j]){                             min = j;                    temp = arr[min];                   arr[min] = arr[i];                   arr[i] = temp;               }           }           }   }   public static void main(String[] args){       int[] a={77,99,44,55,22,88,11,0,66,33};       System.out.println("排序前");       for(int number:a){           System.out.print(number+" ");       }       System.out.println();       simpleSelectionSort(a);       System.out.println("排序后");       for(int number:a){           System.out.print(number+" ");       }   }}

结果和冒泡排序是一样的,如下:
这里写图片描述


直接插入排序

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

直接插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

步骤如下:
①从第一个元素开始,该元素可以认为已经被排序
②取出下一个元素,在已经排序的元素序列中从后向前扫描
③如果该元素(已排序)大于新元素,将该元素移到下一位置
④重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⑤将新元素插入到该位置后
⑥重复步骤②~⑤

这里写图片描述

动态图:
这里写图片描述
使用插入排序为一列数字进行排序的过程:
这里写图片描述

直接插入排序算法复杂度为O(n²)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。

代码如下:

这里写代码片
原创粉丝点击