归并排序
This presentation is the property of its rightful owner.
Sponsored Links
1 / 22

归并排序 PowerPoint PPT Presentation


  • 131 Views
  • Uploaded on
  • Presentation posted in: General

归并排序. 基本原理,通过对两个有序结点序列的合并来实现排序。 所谓归并是指将若干个已排好序的部分合并成一个有序的部分。. 两路归并的基本思想. 设有两个有序表 A 和 B ,对象个数分别为 a l 和 b l ,变量 i 和 j 分别是两表的当前指针。设表 C 是归并后的新有序表,变量 k 是它的当前指针。 i 和 j 对 A 和 B 遍历时,依次将关键字小的对象放到 C 中,当 A 或 B 遍历结束时,将另一个表的剩余部分照抄到新表中。. 两路归并的示例. 25 57 48 37 12 92 86. 25 57 37 48 12 92 86.

Download Presentation

归并排序

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


6030741

归并排序

  • 基本原理,通过对两个有序结点序列的合并来实现排序。

  • 所谓归并是指将若干个已排好序的部分合并成一个有序的部分。


6030741

两路归并的基本思想

设有两个有序表A和B,对象个数分别为al和bl,变量i和j分别是两表的当前指针。设表C是归并后的新有序表,变量k是它的当前指针。i和j对A和B遍历时,依次将关键字小的对象放到C中,当A或B遍历结束时,将另一个表的剩余部分照抄到新表中。


6030741

两路归并的示例

255748 37129286

25 5737 4812 9286

25 37 48 5712 86 92

12 25 37 48 57 86 92


6030741

归并算法

Merge(rectypr R[],rectype R1[],int low,int mid,int

high)

{ int i,j,k;

i=low; j=mid+1; k=low;

while ((i<=mid)&&(j<=high))

if (R[i].key<=R[j].key) R1[k++]=R[i++];

else R1[k++]=R[j++];

while (j<=mid) R1[k++]=R[i++];

while (j<=high) R1[k++]=R[j++];

}


6030741

归并排序就是利用上述归并操作实现排序的。其基本思想是:

将待排序列R[0]到R[n-1]看成n个长度为1的有序子序列,把这些子序列两两归并,便得到high(n/2)个有序的子序列。然后再把这high(n/2)个有序的子序列两两归并,如此反复,直到最后得到一个长度为n的有序序列。上述每次的归并操作,都是将两个子序列归并为一个子序列,这就是“二路归并”,类似地还可以有“三路归并”或“多路归并”。


6030741

归并过程示例

(25) (57) (48) (37) (12) (92) (86)

(25 57) (37 48) (12 92) (86)

(25 37 48 57) (12 86 92)

(12 25 37 48 57 86 92)


6030741

一趟归并算法

Mergepass(rectype R[],rectype R1[],int length)

{ int i,j;

i=0;

while (i+2*length-1<n)

{ MERGE(R,R1,i,i+length-1,i+2*length-1);

i=i+2*length;

}

if (i+length-1<n-1)

MERGE(R,R1,i,i+length-1,n-1);

else

for (j=i;j<n;j++) R1[j]=R[j];

}


6030741

归并排序算法

Mergesort(rectype R[])

{ int length=1;

while (length<n)

{ Mergepass(R,R1,length);

length=2*length;

Mergepass(R1,R,length);

length=2*length;

}

}


6030741

算法复杂性分析

归并排序在第i 趟归并后,有序子文件长度为2i,因此,因此,对于具有n个记录的序列来说,必须做high(log2n)趟归并,每趟归并所花的时间为O(n)。所以,二路归并排序算法的时间复杂度为O(nlog2n),辅助数组所需的空间为O(n)。

归并排序是稳定的排序方法。


6030741

基数排序

  • 基本原理,采用“分配”和“收集”的办法,用对多关键字进行排序的思想实现对单关键字进行排序的方法。

  • 下面先介绍多关键字排序


6030741

多关键字排序方法示例

  • 如对扑克牌的排序

  • 每张扑克牌有两个“关键字”:花色和面值它们之间有次序的优先。

  • 对以上排序,可以先对花色排序,或先对面值排序。


6030741

多关键字有序的概念

  • 考虑对象序列{V0,V1,..., Vn-1},每个对象Vi含d个关键字(Ki1,Ki2,..., Kid)。若对序列中的任意两个对象Vi和Vj都有

    (Ki1,Ki2,..., Kid) < (Kj1,Kj2,..., Kjd)

  • 则称序列对关键字(Ki1,Ki2,..., Kid)有序,且K1称为最高位关键字,Kd称为最低位关键字。


6030741

多关键字排序

  • 原理:根据组成关键字的各位的值进行排序。

    实现基数排序的两种方法:

    1 最高位优先(MSD)排序:从关键字的高位到低位

    2 最低位优先(LSD)排序:从关键字的低位到高位

  • MSD方法通常是一个递归的过程。


6030741

多关键字排序(续)

  • LSD和MSD方法也可应用于对一个关键字进行的排序。此时可将单关键字Ki看成是一个子关键字组:

    (Ki1,Ki2,..., Kid)

  • 如对关键字取值范围为0到999的一组对象,可看成是(K1,K2,K3)的组合。

  • MSD方法按K1,K2,K3的顺序对所有对象排序;LSD方法按K3 ,K2 , K1的顺序对所有对象排序。


6030741

链式的基数排序

  • 基数排序是一种典型的LSD排序方法,它利用“分配”和“收集”两种运算对单关键字进行排序。

  • 此时可将单关键字K看成是一个子关键字组:

    (Ki1,Ki2,..., Kid)

  • 排序过程:设关键字共有d位,让j= d, d-1,...,1, 依次执行d次“分配”与“收集”。


6030741

179

208

306

93

859

984

55

9

271

33

B[0].f B[1].f B[2].f B[3].f B[4].f B[5].f B[6].f B[7].f B[8].f B[9].f

271

93

984

55

306

208

179

859

33

9

B[0].e B[1].e B[2].e B[3].e B[4].e B[5].e B[6].e B[7].e B[8].e B[9].e


6030741

271

93

33

984

55

306

208

179

859

9

B[0].f B[1].f B[2].f B[3].f B[4].f B[5].f B[6].f B[7].f B[8].f B[9].f

306

33

55

271

984

93

208

859

179

9

B[0].e B[1].e B[2].e B[3].e B[4].e B[5].e B[6].e B[7].e B[8].e B[9].e


6030741

306

208

9

33

55

859

271

179

984

93

B[0].f B[1].f B[2].f B[3].f B[4].f B[5].f B[6].f B[7].f B[8].f B[9].f

9

179

208

306

859

984

33

271

55

93

B[0].e B[1].e B[2].e B[3].e B[4].e B[5].e B[6].e B[7].e B[8].e B[9].e

9

33

55

93

179

208

271

306

859

984


6030741

分配排序算法

typedef struct

{ int key[d];

int next;

datatype other;

} rectype;

rectype R[n];

typedef struct

{ int f,e;

} queue;

queue B[m];


6030741

for (j=d-1;j>=0;j--)

{ for (i=0;i<m;i++)

{ B[i].f=-1;

B[i].e=-1;

}

while (p!=-1)

{ k=R[p].key[j];

if (B[k].f==-1) B[k].f=p;

else R[B[k].e].next=p;

B[k].e=p;

p=R[p].next;

}

i=0;

while (B[i].f==-1) i++;

t=B[i].e; p=B[i].f;

while (i<m-1)

{ i++;

if (B[i].f!=-1)

{R[t].next=B[i].f; t=B[i].e;}

}

R[t].next=-1;

}

return p;

}

int RADIXSORT

(rectype R[])

{ int i,j,k,t,p;

for (i=0;i<n-1;i++)

R[i].next=i+1;

R[n-1].next=-1;

p=0;


6030741

内部排序方法的比较和选择

  • 选取排序方法时需要考虑的因素有:

  • 待排序的记录数目

  • 记录本身信息量的大小

  • 关键字的结构及其分布情况

  • 对排序稳定性的要求

  • 语言工具的条件、辅助空间的大小


6030741

外部排序简介

如果待排序的记录数很大,无法将所有记录都调入内存,只能将它们存放在外存上,我们称这时的排序为外部排序。

外部排序的实现,主要是依靠数据的内外存交换和“内部归并”。


  • Login