排序算法介绍

来源:互联网 发布:济南泉方数据库 编辑:程序博客网 时间:2024/05/21 05:41

1、直接插入排序

原理:将一数组values(长度为n)从values[i](i=1...n)开始将values[i]作为标志位pivotpivot<values[i-1],则将values[i-1]直接放在values[i]的位置,然后继续比较values[i-2]与pivot比较,pivot<values[i-2],则将values[i-2]直接放values[i-1]的位置。。。。依次类推,当某次比较的结果为pivot大或者i-k(k=1...i)的值小于0了就停止比较,并将pivot赋值给停止比较时的后一位即values[i-k+1]=pivot

//直接插入排序private void insertsort(int[] values){for(int i = 1; i < values.length;i++){if(values[i] < values[i-1]){int tmp = values[i];int p = i-1;do{values[p+1] = values[p];p--;}while(p > -1 && values[p] > tmp);values[++p] = tmp;}}}

2、希尔排序

原理:希尔排序其实是直接插入排序的升级版,希尔排序会将数组values(长度为n)按照间隔d(d1<n)分成若干小数组,即从values[0]到values[d1-1]开始间隔d1的元素组合d1-1个小数组,对每个小数组进行直接插入排序,然后再继续把数组按照间隔d(d2<d1)分成d2-1个小数组进行直接插入排序,依次类推到间隔为dn(dn=1)的1个数组,进行直接插入排序。


//希尔排序private void shellsort(int[] jiange, int[] values){for(int j = 0; j < jiange.length; j++){for(int i = jiange[j]; i < values.length;){if(values[i] < values[i-jiange[j]]){int tmp = values[i];int p = i-jiange[j];do{values[p+jiange[j]] = values[p];p-=jiange[j];}while(p > -1 && values[p] > tmp);values[p+jiange[j]] = tmp;}i+=jiange[j];}}}



希尔排序之所以事先对小数组进行直接插入排序,是为了使整个数组处于基本有序的状态,这样最后一次的直接插入排序将因为数组已经基本有序而大大提高效率。


3、冒泡排序

原理:对数组values(长度为n)从0开始相邻两数values[i]与values[i+1](i=0....n-2)两两比较,并将较大的值排在后面,即每次比较后使得values[i+1]>values[i],这样保证一趟比较下来value[n-j](j=n-1,n-2....0,j代表第几趟)的值总是(0,n-j)中最大的。


//冒泡排序private void bubblesort(int[] values){for(int i = 0; i < values.length - 1;i++){for(int j = 0; j < values.length - 1 - i;j++){if(values[j] > values[j+1]){int tmp = values[j];values[j] = values[j+1];values[j+1] = tmp;}}}}


 4、快速排序

原理:在数组values(长度n)中从values[low...high](0<=low < hight <=n-1)中得到一个基准下表pivot,保证values[low...povit-1]的值都小于values[povit],values[povit+1...high]的值都大于values[povit],当low=0,high=n-1时就是对整个数组进行快速排序

//快速排序private void quicksort(int[] values, int low, int high){if(low < high){int pivotpos = getPivotpos(values, low, high);quicksort(values, low, pivotpos - 1);quicksort(values, pivotpos+1, high);}}

而获取基准下标的原理在于先取出keyword = values[low],让keyword与values[high]比较,若values[high]大,则high--,并继续与values[high]比较,若keyword比较大,则将此时的values[high]赋值给values[low],然后low++,此时keyword再接着与values[low]比较,若values[low]较小,则low++,keyword继续与values[low]比较,若values[low]大,则将values[low]赋值给values[high],并换成keyword与values[high]比较,这种比较在low与high相等时停止比较,并将keyword赋值到values[low]。

获取基准下标的核心在于将数组第一个值与数组中每个值比较过去,大的值通通放数组靠后位置,小的值通通放数组靠前的位置,直到只剩下一个位置后那个位置就是基准下标

private int getPivotpos(int[] values, int low, int high){int type = 0;//比较类型 0-与下标大的比,1-与下标小的比int pivot = values[low];while(low < high){if(type == 0){if(pivot < values[high]){high--;}else{values[low] = values[high];low++;type = 1;}}else{if(values[low] < pivot){low++;}else{values[high] = values[low];high--;type = 0;}}}values[low] = pivot;return low;}