美文网首页
快速排序、希尔排序

快速排序、希尔排序

作者: 何文杰啊 | 来源:发表于2017-09-03 20:22 被阅读0次

参考博客:http://www.cnblogs.com/0201zcr/p/4763806.html

·快速排序

        将一个数作为关键字(如第一个),一趟快排之后得到这个关键字排序后应该处于的位置,而这个位置之前的所有数将都比此关键字小(降序则大),之后的所有数都比关键字大(降序则小)。


第一趟快排流程:

快排全过程:


代码实现:

1.获取关键字(中轴)排序后位置

/**

* 查找出中轴(默认是最低位low)的在numbers数组排序后所在位置

*

* @param numbers 带查找数组

* @param low  开始位置

* @param high  结束位置

* @return  中轴所在位置

*/

public static int getMiddle(int[] numbers, int low,int high){

int temp = numbers[low]; //数组的第一个作为中轴

while(low < high){

while(low < high && numbers[high] > temp){

high--;

 }

numbers[low] = numbers[high];//比中轴小的记录移到低端

while(low < high && numbers[low] < temp){

low++;

 }

numbers[high] = numbers[low] ; //比中轴大的记录移到高端

 }

numbers[low] = temp ; //中轴记录到尾

return low ; // 返回中轴的位置

}

2.递归的进行分组排序

/**

*

* @param numbers 带排序数组

* @param low  开始位置

* @param high 结束位置

*/

public static void quickSort(int[] numbers,int low,int high)

{

if(low < high)

{

int middle = getMiddle(numbers,low,high); //将numbers数组进行一分为二

quickSort(numbers, low, middle-1);  //对低字段表进行递归排序

quickSort(numbers, middle+1, high); //对高字段表进行递归排序

 }

}


分析:

        快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录。快速排序是一个不稳定的排序方法。

·希尔排序

    先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

    1.选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;

    2.按增量序列个数k,对序列进行k 趟排序;

    3.每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

示例:

算法:

/**希尔排序的原理:根据需求,如果你想要结果从大到小排列,它会首先将数组进行分组,然后将较大值移到前面,较小值

* 移到后面,最后将整个数组进行插入排序,这样比起一开始就用插入排序减少了数据交换和移动的次数,可以说希尔排序是加强

* 版的插入排序

* 拿数组5, 2, 8, 9, 1, 3,4来说,数组长度为7,当increment为3时,数组分为两个序列

* 5,2,8和9,1,3,4,第一次排序,9和5比较,1和2比较,3和8比较,4和比其下标值小increment的数组值相比较

* 此例子是按照从大到小排列,所以大的会排在前面,第一次排序后数组为9, 2, 8, 5, 1, 3,4

* 第一次后increment的值变为3/2=1,此时对数组进行插入排序,

*实现数组从大到小排

*/

public static void shellSort(int[] data)

{

int j = 0;

int temp = 0;

//每次将步长缩短为原来的一半

for (int increment = data.length / 2; increment > 0; increment /= 2)

{

for (int i = increment; i < data.length; i++)

{

temp = data[i];

for (j = i; j >= increment; j -= increment)

{

if(temp > data[j - increment])//如想从小到大排只需修改这里

{

data[j] = data[j - increment];

 }

else

{

break;

 }

 }

data[j] = temp;

 }

 }

}

时间复杂度:O(n^2)

相关文章

网友评论

      本文标题:快速排序、希尔排序

      本文链接:https://www.haomeiwen.com/subject/atbjjxtx.html