排序分类
(1)插入排序
视第一个数为已经排好序的数,将接下来未被排序的数插进前面已经排好序的数中,直至全部插完,排序结束。
1.直接插入
理论:
例:将数组[1 5 3 2]按照从小到大的顺序排序。
注:【】内为已经排好序的数
【
1
】
5
3
2
\color{red}{【1】5\ 3 \ 2}
【1】5 3 2 :
- 视第一个数为排好序的数
【 1 5 】 3 2 \color{red}【1\ 5】3\ 2 【1 5】3 2:
- 拿出未被遍历过的第一个数5,5>1,将5插到1的后面
【 1 3 5 】 2 \color{red}【1\ 3\ 5】2 【1 3 5】2:
- 依次拿出未被遍历过的第二个数3,与已经排好序的数挨个比较进而找到3的位置。3>1
- 3<5,找到3应该插入的位置:1的后面,5的前面
【 1 2 3 5 】 \color{red}【1\ 2\ 3\ 5】 【1 2 3 5】:
- 依次拿出未被遍历过的第三个数2,与已经排好序的数挨个比较找到2的位置。2>1
- 2<3,找到2应该插入的位置:1的后面,3的前面
【
1
2
3
5
】
排
序
完
成
\color{red}【1\ 2\ 3\ 5】排序完成
【1 2 3 5】排序完成
时间复杂度T(n)=O(n^2)
算法描述:
从第二个数开始,找到当前的位置i(前a[i-1]已经排好序),从第i-1个数到第1个数中为a[i]找位置。倒着遍历能通过向后移出一个空位以供新的数来插入。
用a[0]暂存a[i],j=i-1以供倒着对数组进行遍历。将a[i]的前一个数a[j]覆盖a[i],同时j- -(这样能空出来一位以供a[0]插入)直至a[0]>a[j]跳出循环(此时a[0]大于前一个数a[j],那么他的位置就是a[j]的后面一位j+1,即a[j+1]=a[0])
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void Insertsort(int a[100],int n)//直接插入
{//数组a是从1到n储存数据
int i,j;
for(i=2;i<=n;i++)//从第二个数开始
{
a[0]=a[i];//a[0]暂存当前数据
j=i-1;//当前为i,所以前i-1个数已经排好序
//从第i-1个数开始比,将每个数都后移,直到找到插入位置
while(a[0]<a[j])
{
a[j+1]=a[j];
j--;
}
a[j+1]=a[0];//插入
}
}
int main()
{
int a[100],x,i=1,n;
while(cin>>x&&x)//输入0表示结束
{
a[i++]=x;
}
n=i-1;//n记录数组长度
Insertsort(a,n);
for (i=1;i<=n;i++)
printf("%d ", a[i]);
return 0;
}
/*
输入:
2 4 3 9 6 8 7 5 1 0
输出:
1 2 3 4 5 6 7 8 9
*/
从大到小排序:
while(a[0]<a[j]) 改为 while(a[0]>a[j])
2.折半插入
理论:
折半插入的被插入的部分必须是已经排好序的数,类似“直接插入”中不断地将未被遍历的数插到已经排序的数的过程。
折半插入相较于直接插入是在查找a[i]的位置上进行了优化,减少关键字间的比较次数,具体的优化是通过判断a[i]的所在区间而不断移动左区间(left)右区间(right)直至满足a[left]<a[i]<a[right]。判断是否满足a[left]<a[i]<a[right]需要引入区间的中间位置mid:
- 如果a[i]>a[mid]则应当将左边界右移到mid+1
- 如果a[i]<a[mid]应当将右边界左移到mid-1
以此缩小left与right之间的夹取空间,若要满足a[left]<a[i]<a[right]则a[left]与a[right]之间原本没有数(即left+1=right,a[mid]=a[l])
这时a[i]>a[mid]使left右移导致left=left+1=right,a[m]=a[right],此时a[i]<a[right]那么a[i]的位置为a[left]与a[right]之间,同时由于a[i]<a[right],right=mid-1破坏了原来left=right的平衡,l>r。这就是跳出循环也就是找到a[i]位置的标志!
移动过程通过下面的代码模拟:(从1开始存储,共n个数,为a[m]找位置)
left=1,right=n,mid=(left+right)/2
if(a[m]>a[0])//a[0]暂存a[i]
r=m-1;
else
l=m+1;
(以下left简称为l,right简称为r,mid简称为m)
例:将数组[1 5 3 0]按照从小到大的顺序排序。
即a[1]=1,a[2]=5,a[3]=3,a[4]=0
【
1
】
5
3
0
\color{red}【1】5\ 3\ 0
【1】5 3 0 :
- 视第一个数为排好序的数
【 1 】 5 3 0 − > 【 1 5 】 3 0 \color{red}【1】5\ 3\ 0\ ->【1\ 5】 3\ 0 【1】5 3 0 −>【1 5】3 0:
- l=1,r=1,m=1,a[m]=1,5>1,l=m+1=2
- 此时l>r,查找结束,a[l]=a[2]=5
【 1 5 】 3 0 − > 【 1 3 5 】 0 \color{red}【1\ 5】 3\ 0\ ->【1\ 3\ 5】0 【1 5】3 0 −>【1 3 5】0:
- l=1,r=2,m=1,a[m]=1,3>1,l=m+1=2
- 此时l=r=2,m=(l+r)/2=2,a[m]=5,3<5,r=m-1=1
- 此时l>r,查找结束,a[l]=a[2]=3
【 1 3 5 】 0 − > 【 0 1 3 5 】 \color{red}【1\ 3\ 5】0\ ->【0\ 1\ 3\ 5】 【1 3 5】0 −>【0 1 3 5】:
- l=1,r=3,m=2,a[m]=3,0<3,r=m-1=1
- 此时l=r,m=(l+r)/2=1,a[m]=1,0<1,r=m-1=0
- 此时l>r,查找结束,a[l]=a[1]为0的位置
【
0
1
3
5
】
排
序
完
成
\color{red}【0\ 1\ 3\ 5】排序完成
【0 1 3 5】排序完成
时间复杂度为:T(n)= O(n^2)
算法描述
从第二个数开始,找到当前的位置i,left从1开始,right从i-1开始(因为前i-1个数已经排好序)mid=(left+right)/2,让a[i]与a[mid]比较(要始终保证在左右区间内a[left]<a[i]<a[right]),那么当left>right时左右的数都被遍历过,此时a[left]则为a[i]的插入位置,同"直接插入法"倒着将a[i]插入在正确位置上
代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void Halfsort(int a[100],int n)//n表示个数
{
int i,j,l,r,m;//l表示left,r表示right,m表示mid
for(i=2;i<=n;i++)//n-1次排序完成
{
a[0]=a[i];
l=1;
r=i-1;//前i-1个数已经排好序
while(l<=r)//找a[i]的插入位置
{
m=(l+r)/2;
if(a[0]<a[m])//从大到小排序则改为a[0]>a[m]
r=m-1;
else
l=m+1;
}
for(j=i-1;j>=l;j--)//插入:向后覆盖,直至j<l,
{
a[j+1]=a[j];
}
a[l]=a[0];
}
}
int main()
{
int a[100],x,i=1,n;
while(cin>>x&&x)
{
a[i++]=x;
}
n=i-1;
Halfsort(a,n);
for (i=1;i<=n;i++)
printf("%d ", a[i]);
return 0;
}
/*
输入:
2 4 3 9 6 8 7 5 1 0
输出:
1 2 3 4 5 6 7 8 9
*/
从大到小排序:
if(a[0]<a[m]) 改为 if(a[0]>a[m])
3.希尔排序
理论:
希尔排序又称缩小增量法
先将整个待排记录序列分割成若干子序列,子序列内部分别进行直接插入排序,通过不断减少子序列内部的元素数,使整个序列中的记录“基本有序”,此时再对全体记录进行一次直接插入排序。
例:将下列元素从小到大排序
1 2 3 4 5 6 7 8 9 10 11 12 13 (下标)
7 8 4 6 1 9 5 3 2 12 11 13 -1 (数据)
- 这里一共有13个数,取下标的间隔为13/2=6,获取到6组序列如下:
- 第1组:
a
[
1
]
=
7
,
a
[
7
]
=
5
,
a
[
13
]
=
−
1
\color{blue}a[1]=7,a[7]=5,a[13]=-1
a[1]=7,a[7]=5,a[13]=−1
第2组: a [ 2 ] = 8 , a [ 8 ] = 3 \color{orange}a[2]=8,a[8]=3 a[2]=8,a[8]=3
第3组: a [ 3 ] = 4 , a [ 9 ] = 2 \color{green}a[3]=4,a[9]=2 a[3]=4,a[9]=2
第4组: a [ 4 ] = 6 , a [ 10 ] = 12 \color{pink}a[4]=6,a[10]=12 a[4]=6,a[10]=12
第5组: a [ 5 ] = 1 , a [ 11 ] = 11 \color{red}a[5]=1,a[11]=11 a[5]=1,a[11]=11
第6组: a [ 6 ] = 9 , a [ 12 ] = 13 \color{purple}a[6]=9,a[12]=13 a[6]=9,a[12]=13 - 每一组内部按照“直接插入排序”法是内部有序,得到如下结果
- 第1组:
a
[
1
]
=
−
1
,
a
[
7
]
=
5
,
a
[
13
]
=
7
\color{blue}a[1]=-1,a[7]=5,a[13]=7
a[1]=−1,a[7]=5,a[13]=7
第2组: a [ 2 ] = 3 , a [ 8 ] = 8 \color{orange}a[2]=3,a[8]=8 a[2]=3,a[8]=8
第3组: a [ 3 ] = 2 , a [ 9 ] = 4 \color{green}a[3]=2,a[9]=4 a[3]=2,a[9]=4
第4组: a [ 4 ] = 6 , a [ 10 ] = 12 \color{pink}a[4]=6,a[10]=12 a[4]=6,a[10]=12
第5组: a [ 5 ] = 1 , a [ 11 ] = 11 \color{red}a[5]=1,a[11]=11 a[5]=1,a[11]=11
第6组: a [ 6 ] = 9 , a [ 12 ] = 13 \color{purple}a[6]=9,a[12]=13 a[6]=9,a[12]=13
得 到 新 序 列 − 1 3 2 6 1 9 5 8 4 12 11 13 7 ( 相 比 原 来 变 得 更 加 有 序 ) \color{red}得到新序列 \color{blue}{-1}\ \color{orange}3\ \color{green} 2\ \color{pink}6\ \color{red} 1\ \color{purple}9\ \color{blue}5\ \color{orange}8\ \color{green}4\ \color{pink}12\ \color{red} 11\ \color{purple}13\ \color{blue}7\color{red}(相比原来变得更加有序) 得到新序列−1 3 2 6 1 9 5 8 4 12 11 13 7(相比原来变得更加有序) - 缩小间隔为原来的一半d=2/d=3,再次分组
- 第1组:
a
[
1
]
=
−
1
,
a
[
4
]
=
6
,
a
[
7
]
=
5
,
a
[
10
]
=
12
,
a
[
13
]
=
7
\color{blue}a[1]=-1,a[4]=6,a[7]=5,a[10]=12,a[13]=7
a[1]=−1,a[4]=6,a[7]=5,a[10]=12,a[13]=7
第2组: a [ 2 ] = 3 , a [ 5 ] = 1 , a [ 8 ] = 8 , a [ 11 ] = 11 \color{orange}a[2]=3,a[5]=1,a[8]=8,a[11]=11 a[2]=3,a[5]=1,a[8]=8,a[11]=11
第3组: a [ 3 ] = 2 , a [ 6 ] = 9 , a [ 9 ] = 4 , a [ 12 ] = 13 \color{green}a[3]=2,a[6]=9,a[9]=4,a[12]=13 a[3]=2,a[6]=9,a[9]=4,a[12]=13 - 每一组内部按照“直接插入排序”法是内部有序,得到如下结果
- 第1组:
a
[
1
]
=
−
1
,
a
[
4
]
=
5
,
a
[
7
]
=
6
,
a
[
10
]
=
7
,
a
[
13
]
=
12
\color{blue}a[1]=-1,a[4]=5,a[7]=6,a[10]=7,a[13]=12
a[1]=−1,a[4]=5,a[7]=6,a[10]=7,a[13]=12
第2组: a [ 2 ] = 1 , a [ 5 ] = 3 , a [ 8 ] = 8 , a [ 11 ] = 11 \color{orange}a[2]=1,a[5]=3,a[8]=8,a[11]=11 a[2]=1,a[5]=3,a[8]=8,a[11]=11
第3组: a [ 3 ] = 2 , a [ 6 ] = 4 , a [ 9 ] = 9 , a [ 12 ] = 13 \color{green}a[3]=2,a[6]=4,a[9]=9,a[12]=13 a[3]=2,a[6]=4,a[9]=9,a[12]=13
得到新序列 − 1 1 2 5 3 4 6 8 9 7 11 13 12 \color{blue}-1\ \color{orange}1\ \color{green}2\ \color{blue}5\ \color{orange}3\ \color{green}4\ \color{blue}6\ \color{orange}8\ \color{green}9\ \color{blue}7\ \color{orange}11\ \color{green}13\ \color{blue}12 −1 1 2 5 3 4 6 8 9 7 11 13 12(相比原来变得更加有序) - 缩小间隔为原来的一半d=2/d=1,再次分组
- 第1组:a[1]=-1,a[2]=1,a[3]=2,a[4]=5,a[5]=3,a[6]=4,a[7]=6,a[8]=8,a[9]=9,a[10]=7,a[11]=11,a[12]=13,a[13]=12
- 每一组内部按照“直接插入排序”法是内部有序,得到如下结果
- 第1组:a[1]=-1,a[2]=1,a[3]=2,a[4]=3,a[5]=4,a[6]=5,a[7]=6,a[8]=7,a[9]=8,a[10]=9,a[11]=11,a[12]=12,a[13]=13
得 到 最 终 序 列 − 1 1 2 3 4 5 6 7 8 9 11 12 13 ( 排 序 完 成 ) \color{red} {得到最终序列 -1\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\ 11\ 12\ 13(排序完成)} 得到最终序列−1 1 2 3 4 5 6 7 8 9 11 12 13(排序完成)
时间复杂度:
T
(
n
1.25
)
~
T
(
1.6
n
1.25
)
T(n^{1.25})~T(1.6n^{1.25})
T(n1.25)~T(1.6n1.25)
空间复杂度:S(n)=O(1)
如何选择最佳d序列?目前尚未解决
最后一个增量值必须为1,无除1以外的公因子
不宜在链式存储结构上实现
算法描述
先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void ShellSort(int a[],int n)
{
int d,i,j;
for(d=n/2;d>=1;d/=2)//间隔从每次间隔取d/2,当间隔取1时排序完成
{
//组内直接插入排序,只是元素间隔为d,其他同直接插入排序
for(i=d+1;i<=n;i++)//从每组的第二个数据开始
{
if(a[i]<a[i-d])//后一个小于前一个,交换
{
a[0]=a[i];//暂存
for(j=i-d;j>0&&a[j]>a[0];j-=d)
{
a[j+d]=a[j];//组内元素不断后移的过程
}
a[j+d]=a[0];
}
}
}
}
int main()
{
//数组中第0号位置的值不是有效值
int a[100],x,i=1,n;
while(cin>>x&&x)
{
a[i++]=x;
}
n=--i;
ShellSort(a,n);
//将已排序的结果逐个输出
for (i=1;i<=n;i++)
{
printf("%d ", a[i]);
}
return 0;
}
/*
输入:
1 8 4 6 7 9 5 3 2 12 11 13 -1 0
输出:
-1 1 2 3 4 5 6 7 8 9 11 12 13
*/
从大到小排序需要改动两个地方:
(1)if(a[i]<a[i-d]) 变为 if(a[i]>a[i-d])
(2)for(j=i-d;j>0&&a[j]>a[0];j-=d) 变为 for(j=i-d;j>0&&a[j]<a[0];j-=d)
(2)交换排序
两两比较,如果发生逆序则交换,直到所有记录都排好序为止。保证每轮比较时最后一个元素最大,结束时能将最大值排到最后面位置,还能同时部分理顺其他元素。
1.冒泡
理论:
例:将数组[1 8 4 7 9 5 -1]按照从小到大的顺序排序,n=7。
-
第
一
轮
\color{red}第一轮
第一轮(比较n-1次):
1和8比,8>1,不动,8为当前最大:1 8 4 7 9 5 -1
8和4比,8>4,交换位置,8为当前最大:1 4 8 7 9 5 -1
8和7比,8>7,交换位置,8为当前最大:1 4 7 8 9 5 -1
8和9比,8<9,交换位置,9为当前最大:1 4 7 8 9 5 -1
9和5比,9>5,不动,9为当前最大:1 4 7 8 5 9 -1
9和-1比,9>-1,交换位置,9为当前最大:1 4 7 8 5 -1 9
已将最后一个元素排好: 1 4 7 8 5 − 1 9 1\ 4\ 7\ 8\ 5\ {-1}\ \color{darkorange}9 1 4 7 8 5 −1 9 -
第
二
轮
\color{red}第二轮
第二轮(比较n-2次):
1和4比,1<4,不动,4为当前最大:1 4 7 8 5 -1 9
4和7比,4<7,不动,7为当前最大:1 4 7 8 5 -1 9
7和8比,7<8,不动,8为当前最大:1 4 7 8 5 -1 9
8和5比,8>5,交换位置,8为当前最大:1 4 7 5 8 -1 9
8和-1比,8>-1,交换位置,8为当前最大:1 4 7 5 -1 8 9
已将倒数2个元素排好: 1 4 7 5 − 1 8 9 1\ 4\ 7 \ 5\ {-1}\ \color{darkorange}8\ 9 1 4 7 5 −1 8 9 -
第
三
轮
\color{red}第三轮
第三轮(比较n-3次):
1和4比,1<4,不动,4为当前最大:1 4 7 5 -1 8 9
4和7比,4<7,不动,7为当前最大:1 4 7 5 -1 8 9
7和5比,7>5,交换位置,7为当前最大:1 4 5 7 -1 8 9
7和-1比,7>-1,交换位置,7为当前最大:1 4 5 -1 7 8 9
已将倒数3个元素排好: 1 4 5 − 1 7 8 9 1\ 4\ 5 \ -1\ \color{darkorange}7\ 8\ 9 1 4 5 −1 7 8 9 -
第
四
轮
\color{red}第四轮
第四轮(比较n-4次):
1和4比,1<4,不动,4为当前最大:1 4 5 -1 7 8 9
4和5比,4<5,不动,5为当前最大:1 4 5 -1 7 8 9
5和-1比,5>-1,交换位置,5为当前最大:1 4 -1 5 7 8 9
已将倒数4个元素排好: 1 4 − 1 5 7 8 9 1\ 4\ -1 \ \color{darkorange}5\ 7\ 8\ 9 1 4 −1 5 7 8 9 -
第
五
轮
\color{red}第五轮
第五轮(比较n-5次):
1和4比,1<4,不动,4为当前最大:1 4 -1 5 7 8 9
4和-1比,4>-1,交换位置,4为当前最大:1 -1 4 7 8 9
已将倒数5个元素排好: 1 − 1 4 5 7 8 9 1\ -1 \ \color{darkorange}4\ 5\ 7\ 8\ 9 1 −1 4 5 7 8 9 -
第
六
轮
\color{red}第六轮
第六轮(比较n-6次):
1和-1比,1>-1,交换位置,1为当前最大:-1 1 4 5 7 8 9
已将倒数6个元素排好: − 1 1 4 5 7 8 9 -1\ \color{darkorange}1\ 4\ 5\ 7\ 8\ 9 −1 1 4 5 7 8 9 - 排 序 完 成 ! \color{red}排序完成! 排序完成!
时间复杂度T(n)=O(
n
2
n^2
n2)
空间复杂度S(n)=O(1)
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void BubbleSort(int a[100],int n)
{
int i,j,t;
for(i=1;i<=n-1;i++)//轮数
{
for(j=1;j<=n-i;j++)//让当前最大与下一个比
{
if(a[j]>a[j+1])//交换
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int main()
{
int a[100],x,i=1,n;
while(cin>>x&&x)
{
a[i++]=x;
}
n=--i;
BubbleSort(a,n);
for (i=1;i<=n;i++)
printf("%d ", a[i]);
return 0;
}
/*
输入:
1 8 4 6 7 9 5 3 2 12 11 13 -1 0
输出:
-1 1 2 3 4 5 6 7 8 9 11 12 13
*/
从大到小排序:
函数交换位置那步的if(a[j]>a[j+1]) 改为 if(a[j]<a[j+1])
2.快排
参考连接处视频https://www.bilibili.com/video/BV1at411T75o?from=search&seid=7469410686447511593
任取一个元素 (如第一个) 为中心,所有比它小的元素一律前放,比它大的元素一律后放,形成左右两个子表。对各子表重新选择中心元素并依此规则调整,直到每个子表的元素只剩一个。
理论:
例:将数组[1 8 4 7 5 -1]按照从小到大的顺序排序,n=7。
取第一个数1为中心,L指向第一个位置1,R指向最后一个数-1,L和R交替遍历数,依次与中心进行比较,规则如下:
- R从右向左遍历,直到找到比中心小的数,将R与中心交换,并让R向左移动一位,得到下一个当前数;
- L从右向左遍历,直到找到比中心小的数,将L与中心交换,并让L向右移动一位得到下一个当前数。
- 重复上述步骤直至 L>R,此时比key小的数都在key左边,比key大的数都在key右边。当 L 与 R 重合时,此处位置为空,将中心挪到这里后排序结束
——————————————————————————————————————
-
第
一
轮
\color{red}第一轮
第一轮:
取1为中心,L指向1的位置,R指向-1:
当前为-1,-1<1,-1移到L指向的位置得到下图,交替移动L指向8;
当前为8,8>1,8移到R指向的位置得到下图,交替移动R指向,5;
当前为5,4>1,不动,R顺延指向7;
当前为7,7>1,不动,R顺延指向4;
当前为4,4>1,不动,R顺延与L重合;
得到左序列-1,右序列 1 4 7 5 8 。即-1 1 4 7 5 8
-
第
二
轮
\color{red}第二轮
第二轮:
对左序列-1进行排序,由于只有一个元素,无序排序。
对右序列 4 7 5 8 进行排序,取4为中心,L指向1的位置,R指向-1;
当前为8,8>4,不动,R顺延指向5; 当前为5,5>4,不动,R顺延指向7; 当前为7,7>4,不动,R顺延与L重合;
得到左序列-1 1 4,右序列7 5 8 。即-1 1 4 7 5 8
-
第
三
轮
\color{red}第三轮
第三轮:
对右序列7 5 8 进行排序,取7为中心,L指向7的位置,R指向8,得到如下结果;
得到左序列-1 1 4 5 7,右序列 8。即-1 1 4 5 7 8
时间复杂度:T(n)=O(n²)
空间复杂度:S(n)=O(
l
o
g
2
n
log_2n
log2n)
①每一趟的子表的形成是采用从两头向中间交替式逼近法;
②由于每趟中对各子表的操作都相似,可采用递归算法。递归结束的条件是两边递归的结果为一个数,此时排序完成。
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void Kuaipai(int a[],int left, int right)//整数+从小到大
{
int i=left;
int j=right;
int key=a[i];//key记录中心数
int n=a[0];
if(left>right)
return;//设置递归的结束条件
while(i<j)
{
while(i<j&&key<a[j])//找到第一个右指针指向的数<中心的数
j--;
a[i]=a[j];//将小的挪到左边
while(i<j&&key>a[i])//找到第一个左指针指向的数>中心的数
i++;
a[j]=a[i];//将大的挪到右边
}
a[i]=key;//left=right时的位置为中心数的位置
Kuaipai(a,left,i-1);//对当前的中心左边进行快排
Kuaipai(a,i+1,right);//对当前的中心右边进行快排
}
int main()
{
int a[100],x,i=1,n;
while(cin>>x&&x)
{
a[i++]=x;
}
n=--i;
Kuaipai(a,1,n);
for (i=1;i<=n;i++)
printf("%d ", a[i]);
return 0;
}
/*
输入:
1 8 4 6 7 9 5 3 2 12 11 13 -1 0
输出:
-1 1 2 3 4 5 6 7 8 9 11 12 13
*/
从大到小排序:
那么指针指向的数与中心数进行比较时挪动的法则应相反
while(i<j&&key<a[j]) 改为 while(i<j&&key>a[j])
while(i<j&&key>a[i]) 改为 while(i<j&&key<a[i])
剩下的排序方法将放在另一篇博客中。