数据结构第23讲_插入排序2和交换排序_C

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2.快速排序 2.快速排序
背景 起泡排序的过程可见, 起泡排序的过程可见,起泡排序是一个增加 有序序列长度的过程, 有序序列长度的过程,也是一个缩小无序序列长 度的过程,每经过一趟起泡,无序序列的长度只 度的过程,每经过一趟起泡, 缩小 1。 试设想:若能在经过一趟排序, 试设想:若能在经过一趟排序,使无序序列 的长度缩小一半,则必能加快排序的速度。 的长度缩小一半,则必能加快排序的速度。
1)基本思想 通过一趟排序将待排序列以枢轴为标准划分 通过一趟排序将待排序列以枢轴为标准划分 枢轴 成两部分,使其中一部分记录的关键字均比另一 两部分, 部分小,再分别对这两部分进行快速排序, 部分小,再分别对这两部分进行快速排序,以达 到整个序列有序。 到整个序列有序。 通常取第一个记录的值为基准值或枢轴。 通常取第一个记录的值为基准值或枢轴。
flag=0 //开始时元素未交换 flag=0; //开始时元素未交换 j=2 j<=i; for (int j=2; j<=i; j++) if (R[j]<R[j-1]) { (R[j]<R[jtemp=R[j]; temp=R[j]; flag=1 flag=1; } if(flag==0 return; if(flag==0) return; } } // Bubblesort //发生逆序 //发生逆序
3)具体做法 首先将静态链表中数组下标为“1” 的分量 首先将静态链表中数组下标为“ (结点)和表头结点构成一个循环链表,然后 结点)和表头结点构成一个循环链表, 依次将下标为“ 至 的分量( 依次将下标为“2”至“n”的分量(结点)按记 的分量 结点) 录关键字非递减有序插入到循环链表中。 录关键字非递减有序插入到循环链表中。
R[j]=R[jR[j- ]=temp; R[j]=R[j-1]; R[j-1]=temp;
3)起泡排序算法分析 正序: 正序:
只需进行一趟排序, 在排序过程中进行n 只需进行一趟排序 , 在排序过程中进行 n-1 次关键字 间的比较,且不移动记录;时间复杂度为O(n) 间的比较,且不移动记录;时间复杂度为O(n) 。
8 3
2 38 1 2 38 1 2 38 1 2 38 1
3 65
5 4
4 97 0 4 97 0 4 97 0 4 97 0
5
76 4 -
6 13 6
13 13 2 -
7 27 7 27 7 27 27
2 -
8 49 8 49 8 49 8 49 49
3 -
3 65 5 3 65 5 3 65 5
void ShellSort (SqList &L, int dlta[ ], int t) { 按增量序列dlta[ ..t dlta[0 对顺序表L // 按增量序列dlta[0..t-1]对顺序表L作希尔排序 (k=0 k<t; for (k=0; k<t; ++k) ShellInsert( L, dlta[k]); dlta[k]); ShellInsert( 一趟增量为dlta[k] dlta[k]的插入排序 // 一趟增量为dlta[k]的插入排序 } // ShellSort
逆序: 逆序:
需要进行n 趟排序, 需要进行n(n )/2 次比较, n(n需要进行 n-1 趟排序 , 需要进行 n(n-1)/2 次比较 , 并 作等数量级的记录移动。总的时间复杂度为O(n 作等数量级的记录移动。总的时间复杂度为O(n2) 。
稳定的 适合于数据较少 数据较少的 起泡排序方法是稳定 起泡排序方法是 稳定 的 。 适合于 数据较少 的 情况。 情况。
2)具体做法 附设两个指针low和high, 附设两个指针low和high,初值分别指向第 low 一个记录和最后一个记录, key; 一个记录和最后一个记录,设枢轴为 key; (1)从 所指位置起向前搜索, (1)从high 所指位置起向前搜索,找到第一 个不大于基准值的记录与枢轴记录相互交换; 个不大于基准值的记录与枢轴记录相互交换; (2)从low 所指位置起向后搜索,找到第一 (2)从 所指位置起向后搜索, 个不小于基准值的记录与枢轴记录相互交换。 个不小于基准值的记录与枢轴记录相互交换。 (3)重复这两步直至low=high为止。 (3)重复这两步直至low=high为止。 重复这两步直至low=high为止
5 76 4 5 76 4 5 76 4
0 i=7 MAXINT 6 0 i=8 MAXINT 6
6 13
7 2
6 13 7
7 27 2
4)表插入排序性能分析 从表插入排序的过程可见, 从表插入排序的过程可见,表插入排序的基 本操作仍是将一个记录插入到已排好序的有序表 当中。和直接插排序相比,不同之处仅是以修改 当中。和直接插排序相比,不同之处仅是以修改 2n次指针值代替移动记录,排序过程中所需进行 2n次指针值代替移动记录, 次指针值代替移动记录 的关键字间的比较次数相同。因此表插入排序的 的关键字间的比较次数相同。因此表插入排序的 比较次数相同 时间复杂度仍是O(n 时间复杂度仍是O(n2)。
3
1 65
2 49
3 97
4 25
5 25
6 13
增量 3
希 尔 排 序 过 程
2
1 25
2 25
3 13
4 65
5 49
6 97
增量 2
1
1 13 1 13
2 25 2 25
3 25 3 25
4 65 4 49
5 49 5 65
6 97 6 97
增量 1
2)希尔排序算法描述
void ShellInsert ( SqList &L, int dk ) { //一趟希尔插入排序。本算法对直接插入算法作了以下修改: //一趟希尔插入排序。本算法对直接插入算法作了以下修改: 一趟希尔插入排序 //1 前后记录位置的增量是dk,而不是1 //1.前后记录位置的增量是dk,而不是1; dk //2 //2.L.r[0]只是暂存单元,不是哨兵。当j<=0时,插入位置已找到 r[0 只是暂存单元,不是哨兵。 j<=0 i=dk+1 i<=L.length; for ( i=dk+1; i<=L.length; ++i ) if ( L.r[i].key< L.r[i-dk].key) {//将R[i]插入有序增量子表 r[i]. r[i-dk]. //将R[i]插入有序增量子表 r[i]; 暂存在R[ R[0 L.r[0] = L.r[i]; // 暂存在R[0] r[0 (j=i-dk; j>0 (L.r[0 r[j].key); for (j=i-dk; j>0 && (L.r[0].key< L.r[j].key);j -= dk) r[j]; 记录后移, L.r[j+dk] = L.r[j]; // 记录后移,查找插入位置 r[0 L.r[j+dk] = L.r[0]; // 插入 } }//ShellInsert
11 25 41 41 36
11 25 36
起 泡 排 序 示 例
第 二 趟
第 三 趟
第 四 趟
第 五 趟Leabharlann Baidu
第 六 趟
2)起泡排序算法描述
void Bubblesort(ElemType R[],int n) { flag=1 //当flag为 int flag=1; //当flag为0则停止排序 i=n; i>1 --) for (int i=n; i>1; i--) { //i表示趟数,最多n //i表示趟数,最多n-1趟 表示趟数
1)基本思想 又称为“缩小增量排序” 又称为“缩小增量排序” 。先将整个待排 元素序列分割成若干个子序列(由相隔某个“ 元素序列分割成若干个子序列(由相隔某个“增 量”的元素组成的)分别进行直接插入排序,待 的元素组成的)分别进行直接插入排序, 整个序列中的元素基本有序(增量足够小) 整个序列中的元素基本有序(增量足够小)时, 再对全体元素进行一次直接插入排序( 再对全体元素进行一次直接插入排序(接近最好 情况,效率很高), ),因此希尔排序在时间效率上 情况,效率很高),因此希尔排序在时间效率上 比前两种方法有较大提高。 比前两种方法有较大提高。
8 49 8 49 8 49 8 49 key域 域 next域 域
i=2
MAXINT
2 1
0 i=3 MAXINT 2 0 i=4 MAXINT 2
2 38 1 2 38 1
1 49 3
3 65
4 0
0 i=5 MAXINT 2 0 i=6 MAXINT
6 2
1 49 3 1 49 3 1 49 3 1 49
Typedef struct{ SLNode r[MAXSIZE+1 r[MAXSIZE+1]; //0 //0号单元为表头结点
length; int length; SLinkListType; } SLinkListType;
//链表当前长度 //链表当前长度 //静态链表类型 //静态链表类型
具体做法: 具体做法: 第一趟: 第一趟:第1个与第2个比较,大则交换;第2个与第3个 个与第2个比较,大则交换; 个与第3 比较,大则交换, 比较,大则交换,… 关键字最大的记录交换 到最后一个位置上; 到最后一个位置上; 第二趟:对前n 个记录进行同样的操作, 第二趟:对前n-1个记录进行同样的操作,关键字次大 的记录交换到第n 个位置上; 的记录交换到第n-1个位置上; 依次类推,则完成排序。 依次类推,则完成排序。
25 56 49 78 11 65 41 36
初 始 状 态
25 56 49 78 11 78 11 65 65 78 41 78 36 36
第 一 趟
25 49 56 56 11 65 41 41 65 36
25 49 49 11 56 41 56 36 36
25 25 11 11 49 49 41 49 41 36 36
2)待排记录序列的存储结构
#define MAXSIZE 100 Typedef struct{ RcdType next; int next; } SLNode; SLNode; rc; rc; //记录项 //记录项 //指针项 //指针项 //静态链表容量 //静态链表容量
//表结点类型 //表结点类型
4)表插入排序性能分析 表插入排序的结果只是求得一个有序链表, 表插入排序的结果只是求得一个有序链表, 则只能对它进行顺序查找,不能进行随机查找, 则只能对它进行顺序查找,不能进行随机查找, 为了能实现有序表的折半查找, 为了能实现有序表的折半查找,尚需对记录进行 重新排列。 重新排列。
5.希尔排序 5.希尔排序
第10章 10章
10.1 排序的基本概念 10.2 插入排序 10.3 交换排序 10.4 选择排序 10.5 归并排序 10.6 基数排序
内部排序
10.7 各种内部排序方法的比较
10.3 交换排序
1. 起泡排序 2. 快速排序
1.起泡排序 1.起泡排序
1)起泡排序的基本思想 小的浮起, 小的浮起,大的沉底
3)希尔排序算法分析
希尔排序的时间复杂度较直接插入排序低。 希尔排序的时间复杂度较直接插入排序低。希尔排 序的分析是一个复杂的问题,因为它的时间是和所取 序的分析是一个复杂的问题,因为它的时间是和所取 “增量”序列的函数密切相关。到目前为止,还没有求 增量”序列的函数密切相关。到目前为止, 得一种最好的增量序列,但有大量的局部结论。 得一种最好的增量序列,但有大量的局部结论。 注意:应使增量序列中的值没有除1之外的公因子, 注意:应使增量序列中的值没有除1之外的公因子, 并且最后一个增量值必须等于1 并且最后一个增量值必须等于1。
10.2 插入排序
直接插入排序 折半插入排序 2-路插入排序 表插入排序 希尔排序
4.表插入排序 4.表插入排序
1)基本思想 通过改变排序过程中采用的存储结构, 通过改变排序过程中采用的存储结构,减少 在排序过程中进行“移动”记录的操作。 在排序过程中进行“移动”记录的操作。利用静 态链表进行排序,并在排序完成之后, 态链表进行排序,并在排序完成之后,一次性地 调整各个记录相互之间的位置, 调整各个记录相互之间的位置,即将每个记录都 调整到它们所应该在的位置上。 调整到它们所应该在的位置上。
初始 状态
0 MAXINT 1 0
1 49 0 1 49 0 1 49
3 0
2 38 2 38
1 -
3 65 3 65 3
65 65 0 -
4 97 4 97 4 97 4
97 97 0 -
5 76 5 76 5 76 5 76 -
6 13 6 13 6 13 6 13 -
7 27 7 27 7 27 7 27 -
相关文档
最新文档