内部排序

一般内部排序方法:插入、交换 、选择、归并、基数

性能评价:(1)执行排序算法所需要的时间 (2)执行排序算法所需要的附加 空间

一般排序方法的时间代价以具体排序算法执行过程中的关键字之间比较次数记录位置移动次数来反映。


【1】插入排序 Inserton sort

[思想]

1. 开始时,把第一个记录看成是已经排序好的子序,这时子序只有一个记录

2. 从第二个记录起到最后一个记录,依次将其和前面子序中的记录按关键字比较,确定记录插入的位置

3. 将记录插入到子序中,子序记录个数加1,直至子序长度和原来待排序列长度一样结束

【例子】49      38    65    97     76    13 

49      38    65    97     76    13 

38      49    65    97     76    13

38      49    65    97     76    13 

38      49    65    97     76    13 

38      49    65    76     97    13   

13      38    49    65    76    97

[注意] 时间复杂度 O(n2), 用于记录个数较少场合


希尔排序 Shell Sort

[思想] 将n个待排序记录分割成若干个子序列,然后对各子序列分别进行排序,当整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序

【例】 25  38   65    97   76     27     13   25

 25  38   65    97   76     27    13  25

25  27  13   25  76   38    65  97

25  27   13   25  76   38    65  97

13  25   25    27   65    38     76   97

13  25   25    27   65    38     76   97

13  25   25    27   38    65     76   97

[注意] 希尔排序不稳定,时间复杂度为O(nlog2n),比直接插入排序快

【2】 冒泡排序法

[思想] 反复将第n个记录的关键字和第n-1个记录的关键字进行比较,逆序则交换;下一趟往前走一个记录继续

【例】 13    49    38    65    97      76     27     49

13    27    49    38    65      97     76     49

13    27   38    49    49      65     97     76

13    27  38    49    49      65     97     76

13    27   38    49    49      65     76     97

13    27   38    49    49      65     76     97

[注意] 总时间复杂度O,排序稳定,适合用于基本有序的场合

 快速排序

附设两个指针,low和high,从high所指为之气向前搜索找到第一个关键字小于pivotkey的记录和“枢轴”记录互相交换;

然后从low所指位置起向后搜索,找到第一个关键字大于pivokey的记录和“枢轴”记录互相交换。重复直到low=high

【例】 38   13   27     76     65    49    49  97

27   13   38     76     65    49    49  97

13   27   38     49     65    49    76  97

13   27   38      49    65    49    76  97

13   27   38      49    49    65    76  97

[ 注意] 栈空间O(log2n), 最坏需要栈空间O(n),平均时间复杂度O(nlog2n), 不稳定


int Partition(T a[], int p, int r){

int i=p, j=r+1;

T x = a[p];

while(true){

while(a[++i]<x);

while(a[--j]>x);

if(i>=j)break;

Swap(a[i],a[j]);

}

a[p] =a[j];

a[j]=x;

return j;

}

【3】直接选择排序

[思想] 选出n个记录中关键字最小的记录

【例】49    38    65    49     76    13

13     38    65     49    76    49

13    38     65     49     76   49

13     38    49     65     76    49

13      38   49     49      76    65

13      38    49     49      65    76

[复杂度] 时间复杂度O(n2),稳定的

  堆排序

① 先将初始文件R[1..n]建成一个大根堆(树中每个结点的键值不小于子树的键值),此堆为初始的无序区。

② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key

③ 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。直到无序区只有一个元素为止。

注:大根堆排序算法的基本操作:
              ① 初始化操作:将R[1..n]构造为初始堆;
              ② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一  个记录交换,然后将新的无序区调整为堆(亦称重建堆)。


【4】归并排序法

[思想] 将两个或者两个以上的有序序列归并成一个有序序列

【例】49      38    65   97       76     13     27      49

(38    49)   ( 65    97)  ( 13   76 )  ( 27   49)

(38    49    65    97) (  13   27    49   76)

(13    27    38    49    49   65   76    97)

[复杂度] 附加空间O(n), 需要进行O(log2n)

【5】基数排序法

基数排序的“分配”与“收集”过程 第一趟 :


基数排序的“分配”与“收集”过程 第二趟 :


基数排序的“分配”与“收集”过程 第三趟 :


【分析】有n个待排序记录,每个记录含d个关键字,每个关键字取值范围为rd

(1)分配一趟时间复杂度O(n),每一趟收集复杂度为O(rd),所以链式排序为 O(n+rd),整个排序d躺分配和收集,时间复杂度为O(d(n+rd))

( 2 )  排序时,需要rd个队列的头指针和尾指针,辅助空间为2rd


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值