排序算法

一.排序算法

首先明白几个概念

(1)排序稳定性

简单来讲就是对于两个相同的元素,比如a1,a2,开始排序时a1在a2前面,那么排序结束后位置仍然如此,则为稳定算法,否则就是不稳定算法。在下面介绍的几种排序算法中,稳定排序算法有,不稳定排序算法有

(2)内排序和外排序

根据待排序记录是不是全放在内存中,排序分为外排序和内排序,内排序当然是所有记录都放在内存中,外排序是记录太多,内存放不下,所以内外存都有数据,排序时要内外交换数据。主要的内排序算法有:插入排序,交换排序,选择排序,归并排序。

(3)算法衡量标准

无非就是两个,一是耗费的空间越小越好,二是所用的时间越短越好,也就是时间复杂度和空间复杂度越低越好

接下来进入正题

1.简单选择排序

思想就是正常人的思维,从头开始扫描到尾,首先找出最小的记录放在第一位,把第一位的数和最小记录的数交换一下位置,然后再找出次小的放在第二位,继续交换第二位原本的数和此次找出次小数的位置······最后整个表都有序了。

数字389102
下标0123456

起始状态

数字089132
下标0123456

第一次选择排序,最小的在下标为5的位置,交换下标为1和下标为5的数字,下标为1的位置有序了

数字019832
下标0123456

第二次选择排序,次小的在下标为4的位置,交换下标为2和下标为4的数字,下标为2的位置有序了Ok,后面步骤类似,直到整个列表有序。下表为0位置可以用来标记整个表是否排完或者存放中间临时变量。

不墨迹,上代码

#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int SelectSort(Sqlist *L)
{
    int i,j,min;
    for(i=1;i<=L->length;i++)
    {
        min=i;
        for(j=i+1;j<=L->length;j++)
        {
            if(L->r[min]>L->r[j])
                min=j;
        }
        swap(L,i,min);
    }
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
       L.length=5;
    SelectSort(&L);
    for(i=1;i<6;i++)
        printf("%d",L.r[i]);
}

算法复杂度O(n^2)

2.冒泡排序

每一次都进行两两相邻元素比较,小一点的移到前面,直到所有位置都有序,有n个元素的表要经过n-1轮冒泡,每一轮又要经过n-i次相邻比较换位

第一趟冒泡,从后向前比较2移到了最末的位置

下标01234
初始7219
7219
7129
完成1位置1729
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int BubbleSort1(Sqlist *L)
{
   int i,j;
   for(i=1;i<=L->length;i++)
   {
       for(j=L->length;j>i;j--)
       {
           if(L->r[j]<L->r[j-1])
            swap(L,j,j-1);
       }
   }
   return 1;
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
       L.length=5;
    BubbleSort1(&L);
    for(i=1;i<6;i++)
        printf("%d",L.r[i]);

}

还可以优化一下

//相邻两数不断交换位置,通过标志旗帜来解决后续已经有序但仍需继续比较的问题
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int BubbleSort2(Sqlist *L)
{
   int i,j;
   int flag=1;//flag用来做标记
   for(i=1;i<=L->length&&flag;i++)//flag为0退出循环
   {
       flag=0;
       for(j=L->length;j>i;j--)
       {
           if(L->r[j]<L->r[j-1])
           {
               swap(L,j,j-1);
               flag=1;//有数据交换,flag就为1
           }
       }
       printf("%d ",flag);
   }
   return 1;
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
       L.length=5;
    BubbleSort2(&L);
    for(i=1;i<6;i++)
        printf("%d",L.r[i]);
}

算法复杂度O(n^2

3.插入排序

从头开始,默认第一个位置已经排序好,其他的插入,形成一个有序的表中

//默认第一个是有序的,其他的以其为基准不断往里调整顺序
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int InsertSort(Sqlist *L)
{
    int i,j;
    for(i=2;i<=L->length;i++)
    {
        if(L->r[i]<L->r[i-1])
        {
            L->r[0]=L->r[i];//设置哨兵
            for(j=i-1;L->r[j]>L->r[0];j--)
                L->r[j+1]=L->r[j];//记录后移
            L->r[j+1]=L->r[0];//插入到正确位置
        }
    }
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
       L.length=5;
    InsertSort(&L);
    for(i=1;i<6;i++)
        printf("%d",L.r[i]);
}

算法复杂度O(n^2)

4.希尔排序

相隔某个增量来组成一个子序列,局部有序,最后达到整体有序这个增量的选择dlta[k]=2^(t-k+1)-1(0<=k<=t<=[log 2底(n+1)])(向下取整),可以取得好一点效果

下标012345
初始47193

计算increment=6/3+1=3,i=increment+1=4,r[4]=9>r[i-increment]=r[1]=4,不交换, i+1=5,r[5]=3<r[i-increment]=r[2]=7,交换位置

下标012345
第一次43197

计算increment=4/3+1=2,i=increment+1=3,r[3]=1<r[i-increment]=r[1]=4,交换, i+1=4,r[4]=9>r[i-increment]=r[2]=3,不交换

i+1=5,r[5]=7>r[i-increment]=r[3]=4,不交换

下标012345
第二次13497

计算increment=2/3+1=1,最后一次循环i=increment+1=2,r[2]=3<r[i-increment]=r[1]=1,不交换,

i+1=3,r[3]=4>r[i-increment]=r[2]=3,不交换

i+1=4,r[4]=9>r[i-increment]=r[3]=4,不交换

i+1=5,r[5]=7<r[i-increment]=r[4]=9,交换位置

下标012345
第二次13479
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int ShellSort(Sqlist *L)
{
    int i,j;
    int increment=L->length;
    do{
        increment=increment/3+1;
        for(i=increment+1;i<L->length;i++)
        {
            if(L->r[i]<L->r[i-increment])
            {
                swap(L,i,i-increment);
            }
        }
    }while(increment>1);
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=6;
    ShellSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}

时间复杂度O(n^(3/2))

5.堆排序

:大根堆,堆顶元素比其他元素都要大的堆。小根堆,堆顶元素比其他元素都要小的堆。堆是一种完全二叉树。

按照层序遍历方式从1开始编号,结点满足如下关系**{k(i)>=k(2i),k(i)>=k(2i+1)}或{k(i)<=k(2i),k(i)<=k(2i+1)}(1<=i<=[n/2])**,用顺序表实现

下标01234567
大根堆90807060104050

k[i]=70>k[2i]=40, k[i]=70>k[2i+1]=50

小根堆同理

主要思想:待排序序列构成一个堆(比如大根堆),整个序列最大值就是堆顶结点,将他移开(也就是和末尾结点交换位置),剩下的堆重新组成大根堆,移开,重组,如此往复······,就成了一个从小到大排列的顺序表。

问题关键集中在了根堆调整,我将它总结为12字法则:从下到上(寻找有叶节点的根节点顺序从大下标到小下标),从右到左(同一层次根节点,其实跟第一条差不多,也是大下标到小下标),从上到下(针对某一根节点,将它之后的结点调整,也就是顺序表中下标比他大的所有点),具体怎么肥事呢?看我灵魂画手

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKP5gUIC-1621241510124)(https://i.loli.net/2018/07/28/5b5c1e7257490.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UC73I9e3-1621241510126)(https://i.loli.net/2018/07/28/5b5c1df83eccf.jpg)]

//堆排序
//从下到上。从左到右依次调整根堆,将堆顶元素依次与尾结点交换位置
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
void AdjustHeap(Sqlist *L,int s,int m)
{
    int temp,i;
    temp=L->r[s];
    for(i=2*s;i<=m;i*=2)//从上到下原则
    {
        if(i<m)//当前下标为i的结点还有右节点
            i=L->r[i+1]>L->r[i]?i+1:i;//较大的孩子下标
        if(temp>=L->r[i])
            break;//根节点比孩子大,不需要调整
        L->r[s]=L->r[i];//否则调整位置
        L->r[i]=temp;
        s=i;//控制循环作用,后面的每个结点都要调整为大根堆
    }
}
void HeapSort(Sqlist *L)
{
    int i;
    //把初始状态的r建立成一个大根堆
    for(i=L->length/2;i>0;i--)//从下到上原则
    {
        AdjustHeap(L,i,L->length);
    }
    //排序阶段,将堆顶元素和当前未经排序子序列末尾结点交换位置
    for(i=L->length;i>0;i--)
    {
        swap(L,1,i);
        AdjustHeap(L,1,i-1);
    }

}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    HeapSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}

算法复杂度O(nlogn)

6.归并排序

我用java建了一个基类实现基本的交换方法,子类对sort函数进行重写

package sort;

public class NecessarySort {
	public int[] a= {1,6,4,2,9,7};
	public int l=a.length;
	public void Swap(int[] a,int i,int j) {
		int m=a[i];
		a[i]=a[j];
		a[j]=m;
	}
	public void print(int[] a) {
		for(int i=0;i<a.length;i++) {
			System.out.print(a[i]+" ");
		}
		System.out.println();
	}
	public void Sort() {};
}

package sort;
//归并排序
public class MergeSort extends NecessarySort {

public static void main(String[] args) {
	MergeSort mergeSort=new MergeSort();
	mergeSort.Sort(mergeSort.a,0,mergeSort.l-1);
	mergeSort.print(mergeSort.a);
}
public void Sort(int[] a,int p,int q) {
	if(p>=q) return;
	int s=p+(q-p)/2;
	Sort(a,p,s);//对两边分别递归处理
	Sort(a,s+1,q);
	MergeAll(a,p,s,q);//合并过程
}
public void MergeAll(int[] a,int p,int r,int q) {
	int i=p,j=r+1,k=0;
	int[] newArray=new int[q-p+1];
	//对临时数组进行操作,使之有序
	while(i<=r&&j<=q) {
		if(a[i]<=a[j]) {
			newArray[k++]=a[i++];
		}
		else
			newArray[k++]=a[j++];
	}
	// 判断哪个子数组中有剩余的数据
    int start = i;
    int end = r;
    if (j <= q) {
      start = j;
      end = q;
    }
	//剩余数据拷入临时数组
	for(int m=start;m<=end;m++)
		newArray[k++]=a[m];
	//将数组拷贝回原数组
	for(i=0;i<newArray.length;++i)
		a[p+i]=newArray[i];
}

}

7.快速排序

也是一个局部有序达到整体有序的算法,分而治之思想,选取一个中间枢纽的值,小的排在他前面,大的排在他后面,这样就分成了两部分,然后对每一部分重复此动作,即选取中间枢纽调整次序,然后再选取调整·····相信你已经看出,这需要迭代

(1)初始状态r[9],L->length=8

下标012345678
数字57194386

(2)刚开始选取r[1]作为枢纽,确定low,high位置为表第一个1和最后一个位置8

下标012345678
数字5(low)7194386(high)

(3)high比枢纽值大或相等,保持原位不变,high–否则high与low交换位置,high与low指向的位置不变

r[8]=6>r[1]=5,high–变为7,同理变为6,但是因为r[6]=3<5,所以low与high交换数字,high仍为6

下标012345678
数字3(low)71945(high)86

(4)low比枢纽值大或相等,保持原位不变,low++,否则high与low交换位置,high与low指向的位置不变

r[1]=3<5,low++变为2,但是因为r[2]=7>5,所以low与high交换数字,low仍为2

下标012345678
数字35(low)1947(high)86

(5)继续进行,看high,r[6]=7>5,high变为5,r[5]=4<5.low,high交换位置

下标012345678
数字34(low)195(high)786

看low,r[2]=4<5,low变为3,同理low变为4此时r[4]=9>5,low,high换位

下标012345678
数字3415(low)9(high)786

(6)最后r[5]>5,high=low=4,这一轮终结,此时左边都比5小,右边都比5大,后续将r[1···3],r[5···8]同样步骤进行处理,然后每个再分为两部分,最后整体有序

//快速排序
//
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int Partition(Sqlist *L,int low,int high)
{
    int p=L->r[low];//用表中第一个位置作为枢纽记录
    while(low<high)
    {
        //比枢纽小的交换到低端
        while(low<high&&L->r[high]>=p)
            high--;
        swap(L,low,high);
        //比枢纽大的交换到高端
        while(low<high&&L->r[low]<=p)
            low++;
        swap(L,low,high);
    }
    return low;//返回枢纽所在位置
}
//对顺序表的子序列做快排r[low...high]
void QSort(Sqlist *L,int low,int high)
{
    int p;
    if(low<high)
    {
        p=Partition(L,low,high);//将L一分为二,求出枢纽值位置p
        QSort(L,low,p-1);//低子表递归排序
        QSort(L,p+1,high);//高子表递归排序
    }
}
void QuickSort(Sqlist *L)
{
    QSort(L,1,L->length);

}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    QuickSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}
优化
(1)优化中间枢纽值

在这里我们的中间枢纽值总是选取第一个值,这难免会产生问题,就是这个值是一个极端的值,比如{9,3,2,4,5,7},那么只是把9与7交换位置,其他不改变,之后的比较是多余的,使得整体性能下降。这个中间枢纽值理论上在为整个数组中值的时候算法性能最优,所以我们可以采取三点取中法,由于随机选取三点对系统开销太大,所以我们固定这三点为low,high和middle

//p值选取变为三点取中low,high,middle
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
void swap(Sqlist *L,int i,int j)//交换顺序表中i和j位置上的值
{
    int temp=L->r[i];
    L->r[i]=L->r[j];
    L->r[j]=temp;
}
int Partition(Sqlist *L,int low,int high)
{
    int p,m;
    m=low+(low+high)/2;//计算数组中间下标
    if(L->r[low]>L->r[high])
        swap(L,low,high);//交换左右数据,保证左端较小
    if(L->r[m]>L->r[high])
        swap(L,m,high);//交换右中数据,保证中间较小
    if(L->r[low]<L->r[m])
        swap(L,low,m);//交换左中数据,保证中间较小,low即为中间值
    p=L->r[low];//用表中第一个位置作为枢纽记录
    while(low<high)
    {
        //比枢纽小的交换到低端
        while(low<high&&L->r[high]>=p)
            high--;
        swap(L,low,high);
        //比枢纽大的交换到高端
        while(low<high&&L->r[low]<=p)
            low++;
        swap(L,low,high);
    }
    return low;//返回枢纽所在位置
}
//对顺序表的子序列做快排r[low...high]
void QSort(Sqlist *L,int low,int high)
{
    int p;
    if(low<high)
    {
        p=Partition(L,low,high);//将L一分为二,求出枢纽值位置p
        QSort(L,low,p-1);//低子表递归排序
        QSort(L,p+1,high);//高子表递归排序
    }
}
void QuickSort(Sqlist *L)
{
    QSort(L,1,L->length);

}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    QuickSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}
(2)优化交换位置

low,high交换数据也是影响速度的一个因素,可以把交换改成直接赋值,方法就是将枢纽值存在r[0]中,真是千呼万唤始出来啊,r[0]终于有用了。

//把swap变为=
#include<stdio.h>
#define Maxsize 10
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
int Partition(Sqlist *L,int low,int high)
{
    int p=L->r[low];//用表中第一个位置作为枢纽记录
    L->r[0]=p;//枢纽关键值备份到r[0]
    while(low<high)
    {
        //比枢纽小的交换到低端
        while(low<high&&L->r[high]>=p)
            high--;
        L->r[low]=L->r[high];//替换而不是交换
        //比枢纽大的交换到高端
        while(low<high&&L->r[low]<=p)
            low++;
        L->r[high]=L->r[low];
    }
    L->r[low]=L->r[0];//将枢纽替换回L->r[low],也可以是L->r[high],因为此时high==low
    return low;//返回枢纽所在位置
}
//对顺序表的子序列做快排r[low...high]
void QSort(Sqlist *L,int low,int high)
{
    int p;
    if(low<high)
    {
        p=Partition(L,low,high);//将L一分为二,求出枢纽值位置p
        QSort(L,low,p-1);//低子表递归排序
        QSort(L,p+1,high);//高子表递归排序
    }
}
void QuickSort(Sqlist *L)
{
    QSort(L,1,L->length);

}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    QuickSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}
(3)优化小数组时排序方案

庄子·逍遥游》 中有一篇讲述了一个大葫芦的故事,惠子中了个大葫芦,因为太大不知其用途,感慨它大而无用而庄子觉得,大有大的用途,小有小的用途,大葫芦可以剖开当船,去江湖上漂。这里的快排遇到大数组确实很快,但是当遇到小数组的时候,确不如直接插入排序,因为快排递归的缘故,有点大材小用,这时就要看我们的小葫芦了。思想是:设置一个确定小数组的阈值,比它小用直接插入,比它大用快排。“大锤八十,小锤四十”,演变成:“大数快排,小数直插”

//“大数快排,小数直插”
#include<stdio.h>
#define Maxsize 10
#include<stdio.h>
#define MAX_LENGTH_QUICKSORT 2
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
int InsertSort(Sqlist *L)
{
    int i,j;
    for(i=2;i<=L->length;i++)
    {
        if(L->r[i]<L->r[i-1])
        {
            L->r[0]=L->r[i];//设置哨兵
            for(j=i-1;L->r[j]>L->r[0];j--)
                L->r[j+1]=L->r[j];//记录后移
            L->r[j+1]=L->r[0];//插入到正确位置
        }
    }
}
int Partition(Sqlist *L,int low,int high)
{
    int p=L->r[low];//用表中第一个位置作为枢纽记录
    L->r[0]=p;//枢纽关键值备份到r[0]
    while(low<high)
    {
        //比枢纽小的交换到低端
        while(low<high&&L->r[high]>=p)
            high--;
        L->r[low]=L->r[high];//替换而不是交换
        //比枢纽大的交换到高端
        while(low<high&&L->r[low]<=p)
            low++;
        L->r[high]=L->r[low];
    }
    L->r[low]=L->r[0];//将枢纽替换回L->r[low],也可以是L->r[high],因为此时high==low
    return low;//返回枢纽所在位置
}
//对顺序表的子序列做快排r[low...high]
void QSort(Sqlist *L,int low,int high)
{
    int p;
    if((high-low)>MAX_LENGTH_QUICKSORT)
    {
        p=Partition(L,low,high);//将L一分为二,求出枢纽值位置p
        QSort(L,low,p-1);//低子表递归排序
        QSort(L,p+1,high);//高子表递归排序
    }
    else
        InsertSort(L);
}
void QuickSort(Sqlist *L)
{
    QSort(L,1,L->length);

}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    QuickSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}
(4)优化递归操作

待排序序列分布不均衡时,递归可能会出现深度趋近于n的情况,将递归改为迭代可以让栈深度变小

//快速排序3
//迭代变为尾递归
#include<stdio.h>
#define Maxsize 10
#include<stdio.h>
#define MAX_LENGTH_QUICKSORT 2
typedef struct
{
    int r[Maxsize];//储存要排序数组,r[0]用作哨兵
    int length;//顺序表长度
}Sqlist;
int InsertSort(Sqlist *L)
{
    int i,j;
    for(i=2;i<=L->length;i++)
    {
        if(L->r[i]<L->r[i-1])
        {
            L->r[0]=L->r[i];//设置哨兵
            for(j=i-1;L->r[j]>L->r[0];j--)
                L->r[j+1]=L->r[j];//记录后移
            L->r[j+1]=L->r[0];//插入到正确位置
        }
    }
}
int Partition(Sqlist *L,int low,int high)
{
    int p=L->r[low];//用表中第一个位置作为枢纽记录
    L->r[0]=p;//枢纽关键值备份到r[0]
    while(low<high)
    {
        //比枢纽小的交换到低端
        while(low<high&&L->r[high]>=p)
            high--;
        L->r[low]=L->r[high];//替换而不是交换
        //比枢纽大的交换到高端
        while(low<high&&L->r[low]<=p)
            low++;
        L->r[high]=L->r[low];
    }
    L->r[low]=L->r[0];//将枢纽替换回L->r[low],也可以是L->r[high],因为此时high==low
    return low;//返回枢纽所在位置
}
//对顺序表的子序列做快排r[low...high]
void QSort(Sqlist *L,int low,int high)
{
    int p;
    if((high-low)>MAX_LENGTH_QUICKSORT)
    {
        while(low<high)
        {
            p=Partition(L,low,high);
            QSort(L,low,p-1);//尾递归
            low=p+1;
            //这句和QSort(L,p+1,high);差不多
        }
    }
    else
        InsertSort(L);
}
void QuickSort(Sqlist *L)
{
    QSort(L,1,L->length);
}
int main()
{
    Sqlist L;
    int i;
    for(i=1;i<6;i++)
        scanf("%d",&L.r[i]);
    L.length=5;
    QuickSort(&L);
    for(i=1;i<6;i++)
        printf("%d ",L.r[i]);
}

参考资料:程杰《大话数据结构》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值