常用的基础算法使用总结
1.冒泡排序
通过两两比较,每次将无序序列中最大的一个数交换到数组末尾。如1,9,6,2,8,4.
第一趟
第一次比较 1与9,因为9>1,无需交换
第二次比较 9与6,6<9,需交换,将9往后移,此时序列变为1,6,9,2,8,4
··········
一共需比较5次,既数组长度-1次
第二趟
因为此时数组最后一位已确定,为上一趟中无序序列中最大的一个数,所以只需要比较前面的五个数就好,对比过程和之前一样。
所以第二趟共需进行5-1次的比较
后面的每一趟所需要比较的无序序列都比前一趟少一个数
1 public static void bubbleSort(int[] a){ 2 int i,j; 3 for(i=0;i<a.length-1;i++){ 4 for(j=0;j<a.length-i-1;j++){ 5 if(a[j]>=a[j+1]){ 6 int temp=a[j]; 7 a[j]=a[j+1]; 8 a[j+1]=temp; 9 } 10 } 11 } 12 13 }
2.插入排序
插入排序算法的原理和玩扑克牌摸牌时的想法类似。打扑克摸牌时,手上的牌总是有序的,这时候摸进一张新牌,根据手上有序的手牌就能正确找出这张新牌插入的合适位置。
插入排序通常将数组的第一个元素当成是有序的序列,从数组的第二个元素开始,根据已经有序的序列寻找插入的位置。如一个无序数组1,6,2,9,8,4,将{1}当成是有序的序列,此时要插入的元素为第二个元素6,如果需要按照从小到大的顺序排序的话,因为此时6>1,所以1后面的位置就是6需要插入的位置。那么此时的有序序列就变成了{1,6},而需要插入的元素变成了2,那么先将2与6比较,显然2<6,说明还需要继续往前寻找插入的位置,此时需将元素6往后移一位,以腾出位置提供给插入元素2进行插入。那么此时变成{1,空,6},可见2的位置被6占用了,所以在比较之前就需要将2存放在一个临时变量里。继续将2与1比较,2>1,说明已找到正确的插入位置,既为元素1后一位的空的位置,进行插入。序列变为1,2,6。每次插入完成后所得到的都是一个有序序列,当将最后一个元素插入完毕后意味着排序结束。
1 public static void insertsort(int[] a){ 2 int i,j,temp; 3 for(i=1;i<a.length;i++){ 4 temp=a[i]; 5 j=i-1; 6 while(j>=0 && temp>=a[j]){ 7 a[j+1]=a[j]; 8 j--; 9 } 10 a[j+1]=temp; 11 } 12 13 14 }
3.希尔排序
希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。希尔排序是记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
我们分割待排序记录的目的是减少待排序记录的个数,并使整个序列向基本有序发展。而如上面这样分完组后,就各自排序的方法达不到我们的要求。因此,我们需要采取跳跃分割的策略:将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。
操作方法
操作流程图:
操作步骤:
初始时,有一个大小为 10 的无序序列。
(1)在第一趟排序中,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。
(2)接下来,按照直接插入排序的方法对每个组进行排序。
在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。
(3)按照直接插入排序的方法对每个组进行排序。
(4)在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。
(5)按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。
转载自http://blog.csdn.net/qq845579063/article/details/51447404
1 public static void shellSort(int[] a){ 2 int d = a.length; 3 while(true){ 4 d=d/2; 5 //x代表所分的组 6 for(int x=0;x<d;x++) 7 { 8 /*开始插入排序,与一般插入排序不同的是一般的插 入排序是一个个递增的, 9 而希尔排序所用的插入排序是按增量递增,这里的增量d相当于普通插入排序的1 10 */ 11 for(int i=x+d;i<a.length;i=i+d){ 12 int temp = a[i]; 13 int j = i-d; 14 for(;j>=0 && temp <= a[j];j=j-d){ 15 a[j+d] = a[j]; //与插入排序一般,在未找到插入位置时将数组向后移一位 16 } 17 a[j+d] = temp; 18 } 19 } 20 if(d==1) //说明按增量分只能分成一组了,既排序已经完成 21 break; 22 } 23 }
4.快速排序
一种采用分治法的排序算法,定一个基准数(通常为数组第一个元素),将比基准数小的元素放在左边,比基准数大的放在右边,这样将数组分为{小序列,基准数,大序列},三部分的序列。然后继续在小序列和大序列中采取同样的方法(既将序列分为小,基准数,大三部分)。
1 public static int total = 0; 2 3 public static int position(int[] a,int l,int r) 4 { 5 int temp = a[l]; 6 while(l<r) 7 { 8 while(l<r && a[r]>=temp) 9 r--; 10 a[l]=a[r]; 11 while(l<r && a[l]<=temp) 12 l++; 13 a[r]=a[l]; 14 } 15 a[l]=temp; 16 return l; 17 } 18 19 public static void quickSort(int[] a,int l,int r) 20 { 21 total++; 22 System.out.println("这是第几次 : " + total); 23 if(l<r) 24 { 25 int temp = position(a, l, r); 26 quickSort(a, l, temp-1); 27 quickSort(a, temp+1, r); 28 } 29 }