当前位置:文档之家› 南京邮电大学数据结构A第10章

南京邮电大学数据结构A第10章

然排在 Rj 之前,则称所用的排序算法是稳定的。反之,称 该排序算法是不稳定的。3,1,3=>1,3,3 3,1,3=>1,3,3 如果待排序元素总数相对于内存而言较小,整个排序过 程可以在内存中进行,则称之为内部排序;反之,如果待排 序元素总数较多,不能全部放入内存,排序过程中需访问外 存,则称之为外部排序。
10.2 简单排序算法
10.2.1 简单选择排序
0 1 2 3 4 5 6
初始序列: (48 第1趟: 第2趟: 第3趟: 第4趟: 第5趟: 第6趟: (02 (02 (02 (02 (02
36
68 68 36) 36 36 36 36
72 72 72 (72 48 48 48
12 12 36 68 48) 48 48
i 48 left 36 68 72 12 48
j 02 ∞ right
找到小于A[left] 接下来会分别把 交换以后, 只要 i 和 j准 尚未相遇,就 的元素 (02), A[left]元素两侧 此时,i和j已经“相遇”过,扫描结束 继续各自的扫描以及交换操作 ; 备和 A[i] 交换 ; 和right“指针”指出了 的序列作为排序对 ,下面要把A[left] 和 A[j]交换,实现 其目的是把较 A[left] 小的元素放到 象递归整个算法过 待排序的元素序列; 了各元素按“左边小右边大”的原则 左边 ,较A[left]大的元素放到右边; 程;(过程略) 分布在A[left]两侧;
为空或只有一个元素时得到有序序列。
(48,36,68,72,12,48,02) (12,36,02,48)48(72,68)
10.3 快速排序
扫描“指针”,向左 扫描“指针”,向右扫 找到大于A[left] 的 扫描寻找 <= A[left] 描寻找 >= A[left] 的 元素 (68), 扫描暂停 ; 36并不大于等 的元素 ; 元素; 准备和 A[j] 交换 ; 于A[left],所 以继续扫描;
10.2 简单排序算法
10.2.2 直接插入排序
temp = 36 68 72 36 12 12
i
i之前是有序区;排序开 始的时候i=1;
48 36 68 72 12 48 02
temp中存放新的欲处 j 理元素; j是扫描 “指针”; 向前寻找插入的位置 ;
10.2 简单排序算法
10.2.2 直接插入排序
12 12 12
12 48 68 12 72
48 48
48 48 48 48
02) 02) 02) 02) 48 02) 72 02) 02) 72 72 72 72 72 72 72
(第1趟) (第2趟) (第3趟) (第4趟) (第5趟) (第6趟)
(36 48 68 12 48 02) (36 48 12 48 02)68 (36 12 48 02)48 68 (12 36 02)48 48 68 (12 02)36 48 48 68 (02)12 36 48 48 68
在最坏情况下需要比较
n( n 1) i i 1 2
n 1
次,移动元素
1 (i 2) (n 4)(n 1) 2 i 1
次。 因此最坏情况时间复杂度为 O(n2),它是稳定的排序方法。
n 1
10.2 简单排序算法
10.2.3 冒泡排序
基本思想:第1趟在序列(A[0]A[n-1])中从前往后进
数据结构A · 第10章
第10章 内排序
内容提要
1、内排序的基本概念; 2、简单排序算法; 3、快速排序算法;
4、两路合并排序;
5、堆排序。
10.1 内排序的基本概念
设有n个数据元素的序列(R0,R1,…,Rn-1),Ki 是Ri 的关 键字。
所谓排序,就是找(0,1, …,n-1)的一种排列p(0), p(1),
10.2 简单排序算法
10.2.3 冒泡排序 A[j+1]<A[j]? Yes(直接后继较小 No(直接后继较大 ), 交换之 ), 无须交换 ; ;
48 36 68 72 12 48
j
02
扫描“指针”;
完成一遍扫描!
10.2 简单排序算法
10.2.3 冒泡排序
冒泡排序最好情况(已有序)下只需进行一趟排序,n-1次 比较,因此最好情况下的时间复杂度是O(n)。 最坏进行n-1趟,第i趟比较(n-i)次,移动元素3(n-i)次, 这样比较次数为:
行两个相邻元素的比较,若后者小,则交换,比较n-1次。
第1趟排序结束,最大元素被交换到A[n-1]中(即沉底)。 下一趟排序只需在子序列(A[0]A[n-2])中进行。如果 在某一趟排序中未交换元素,说明子序列已经有序,则不 再进行下一趟排序。
0 1 2 3 4 5 6
初始序列:(48 第1趟: (36 第2趟: (36
稳定的排序ቤተ መጻሕፍቲ ባይዱ法。
关于稳定性问题:
3,1,3进行简单选择排序: 1,3,3 1,3,3 (似乎是稳定的) 3,3,1进行简单选择排序: 1,3,3 1,3,3
10.2 简单排序算法
10.2.2 直接插入排序
基本思想:将序列中第1个元素作为一个有序序列,然后将 剩下的n-1个元素按关键字大小依次插入该有序序列,经过 n-1趟排序后即成为有序序列。
12
48
48 72) 68 68
02
02 02 02 72) 72)
72) 12 68 48 48
72 ) 48
排序结果: (02
10.2 简单排序算法
10.2.2 直接插入排序
程序 10-2 直接插入排序 template <class T> void InsertSort(T A[], int n){ for(int i=1; i<n; i++ ) { int j=i; T temp=A[i]; while(j>0 && temp<A[j-1]){ A[j]=A[j-1]; j--; } A[j]=temp; } }
…, p(n-1),使得序列按 Kp(0) Kp(1)…Kp(n-1) (非递减) 或 Kp(0)Kp(1)…Kp(n-1) (非递增) 的次序排列为: (Rp(0),Rp(1),…,Rp(n-1))
10.1 内排序的基本概念
序列中两个元素Ri和 Rj (i<j),且 Ki=Kj,排序后,Ri 仍
10.2 简单排序算法
10.2.1 简单选择排序
i指向无序区的 开始位置 small变量用来记录无序 区中最小元素的索引值;
small= 0 14 6
i
48 02
0
36
1
68
2
72
3
12
4
48
5
02 48
6
j
整个无序序列的最小 值02被放到i位置后, 第一遍扫描结束,进 j为扫描“指针” 入第二遍扫描;;
1 ( n i ) n ( n 1) i 1 2
n 1
移动元素次数为3n(n-1)/2。
最坏情况下的时间复杂度为O(n2)。 冒泡排序是稳定的排序方法。
10.3 快速排序
基本思想:对任意给定的序列中元素Rs(关键字为Ks),
经过一趟排序后,将原序列分割成两个子序列,其中,前一
个子序列中的所有元素的关键字均小于等于Ks,后一个子序 列中元素的关键字均大于等于Ks。 称元素Rs 为分割元素。 以后只需对2个子序列分别进行快速排序,直到子序列
10.3 快速排序
0 1 2 3 4 5 6 7
j
算法要求A[n]=+∞,防止i超界。
10.3 快速排序
10.3 快速排序
程序10-4 快速排序 template <class T> void QSort(T A[],int left,int right){ int i,j; if ( left<right ) { i=left; j=right+1; do{ do i++; while (A[i]<A[left]); do j--; while (A[j]>A[left]); if (i<j) Swap(A[i],A[j]); }while (i<j); Swap(A[left],A[j]); QSort(A,left,j-1); QSort(A,j+1,right); }//endif }
48 48 48 48 72 (72 68) 68
02) 48) 48) 48) 48) 68 ) (72) 72)
(02)(36 12 12 12 12 12
12) (68
48) (68
排序结果: (02
图10-1 简单选择排序示意图
10.2 简单排序算法
10.2.1 简单选择排序
程序 10-1 简单选择排序 template <class T> void SelectSort(T A[], int n) { int small; for (int i=0; i<n-1; i++ ) { // n-1趟 small=i; for (int j=i+1; j<n; j++) if (A[j]<A[small]) small=j; Swap(A[i],A[small]); } //endfor } //函数Swap(T &a, T &b)交换两个元素 时间复杂度按比较次数衡量为O(n2)。
0 1 2 3 4 5 6
初始序列: (48) 36 第1趟: (36 48)
68 68
72 72
12 12
48 48
相关主题