您的位置:首页 > 其它

排序算法个人总结(2)

2016-05-21 10:35 155 查看
/*

*希尔排序

*/

希尔排序属于内部排序中的插入排序,它是不稳定的排序,时间复杂度为O(n2/3)n的2/3次幂,具体的算法步骤不再赘述,看图说话

比如有一串数字为:9,13,8,2,5,13,7,1,15,11

d1=[10/2]=5 d2=[5/2]=3 d3=[3/2]=1 第一趟五五分,第二趟三三分,第三趟增量必须为1



第一趟排序结果为9,7,1,2,5,13,13,8,15,11



第二趟排序结果:2 5 1 9 7 13 11 8 15 13



第三趟:1 2 5 7 8 9 11 13 13 15

/*

*快速排序

*/

先看一看C程序代码

/*    快  速  排  序    */
#include "stdio.h"

void QuickSort(int e[], int first, int end)
{
int i=first,j=end,temp=e[first];
while(i<j)
{
while(i<j && e[j]>=temp)
j--;
e[i]=e[j];
while(i<j && e[i]<=temp)
i++;
e[j]=e[i];
}
e[i]=temp;
if(first<i-1)
QuickSort(e,first,i-1);
if(end>i+1)
QuickSort(e,i+1,end);
}

void main()
{
int arr[] = {49, 38, 65, 97, 76, 13, 27, 49};
int len = 8;
int i;
printf("before sort\n");
for(i=0; i<len; i++)
printf("%d  ", arr[i]);
printf("\n");

QuickSort(arr, 0, len-1);

printf("after sorted\n");
for(i=0; i<len; i++)
printf("%d  ", arr[i]);
printf("\n");
}
首先介绍一下思想:

1.设置两个变量I、J,排序开始的时候I:=1,J:=N;

2.以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

3.从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

4.从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

5.重复第3、4步,直到I=J;

实战:比如使用快速排序下列一串数组:49 38 65 97 76 13 27

49 38 65 97 76 13 27

i j

j对应的元素比i对应的元素小,所以交换,j不变,i后移

27 38 65 97 76 13 49

i j

i小于j,不能交换,i继续后移

27 38 49 97 76 13 65

i j

i大于j,交换,此时此刻j前移,i不变

27 38 49 97 76 13 65

i j

j小于i,交换,j不变,i后移

27 38 13 97 76 49 65

i j

i大于j,交换,i不变,j前移

27 38 13 49 76 97 65

i j

i小于j,i继续后移与j重合,第一趟排序结束,所以排序结果为

27 38 13 49 76 97 65

保证了49前面的元素都比49小,而49后面的元素都比49大

接下来对49前面的元素和后面的元素分别再次进行快速排序,

{13} 27 {38} 49 {65} 76 {97}

快速排序就是利用栈的递归方法,分治思想,栈的最大深度为log2n取值下限+1

在所有同数量级(O(nlogn))的排序方法中,其平均性能最好,若初始记录基本有序,快排将蜕化为冒泡排序,时间复杂度为O(n²),

接下来我要讲一讲我认为最复杂的一种排序——堆排序

/*

*堆排序(Heap Sort)

*/

首先介绍一下小根堆和大根堆

小根堆:每个节点小于等于左、右孩子,且根节点是序列n个元素的最小值

大根堆:每个节点大于等于左、右孩子,且根节点是序列n个元素的最大值

小根堆





性质:

1.堆是一棵采用顺序存储结构的完全二叉树,k是根节点

2.分为大(小)根堆

3.按元素值非递减排序

4.堆中任一子树也为堆

小根堆排序后得到的是非递减序列

大根堆排序后得到非递增序列

堆排序的时间复杂度为O(N*logN)

下面我们来看看堆的建立、插入元素、删除元素的具体操作

堆的建立:

记住建立过程永远是从上到下,从左到右的顺序,先来热个身

初始化序列表为{3,1,4}



将1 与3进行替换后实现了堆的建立结果:



下面给出以下序列,我将详细讲解如何建立一个小根堆

{49,38,65,97,76,13,27,49}



将此序列看成是一棵完全二叉树,最后一个非终端结点是n/2取值下限个元素,那么筛选就从这个元素开始,如图则从第4个元素97开始筛选,97>49,交换



接下来从第三个元素65开始:13<65,交换



第二个元素为38,不需要调整,第一个元素为49,49<13,交换





再次进行调整得到了小根堆,这就是堆的建立

堆的元素插入:

如果插入2



2与3进行替换得到最终结果为



如果初始插入的是0,将进行两次交换,则最终结果为



堆的元素删除:

如果删除根节点,将以堆中最后一个元素替代之,此时根节点左、右子树均为堆,则仅需自上至下进行调整即可,

堆排序定义:若在输出堆顶的最小值后,使得n-1个元素的序列又建成一个堆,则得到n个元素中的次小值,如此反复执行,便能得到一个有序序列,这个过程称之为堆排序

假如有以下小根堆:



97是最后一个元素,与13进行替换,取出13,







此时27为堆里最小的元素,将27与堆的最后一个元素进行交换,取出27,{13,27} ,此时97为最后一个元素,代替27



调整后



这种方法叫筛选法,

然后取出38,{13,27,38} 65到根节点进行调整,随后筛选出49,49,65,76,97,这就是堆排序

堆排序适合n较大的文件,深度为k的堆,筛选法关键字比较次数为2(k-1),堆排序在最坏情况下时间复杂度为0(nlogn),相比于快排,这是堆排序最大的优点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: