目录

  • 1 课程资料
    • 1.1 课程标准
    • 1.2 教学日历
    • 1.3 说课课件
  • 2 第一章绪论
    • 2.1 本章教学目标
    • 2.2 数据结构简介
    • 2.3 数据结构类型
    • 2.4 算法分析
    • 2.5 本章讲义
    • 2.6 本章测验题
    • 2.7 测验
  • 3 线性结构
    • 3.1 本章教学目标
    • 3.2 线性表
    • 3.3 线性表的顺序存储及运算实现
      • 3.3.1 本节讲义
    • 3.4 线性表的链式存储和 运算实现
      • 3.4.1 本节讲义
    • 3.5 应用
    • 3.6 数组
      • 3.6.1 讲义
    • 3.7 本章测验题
    • 3.8 测验
    • 3.9 作业
  • 4 第三章栈和队列
    • 4.1 本章教学目标
    • 4.2 第一课时栈
      • 4.2.1 讲义
    • 4.3 第二课时队列
      • 4.3.1 讲义
    • 4.4 应用
      • 4.4.1 讲义
    • 4.5 本章测验题
  • 5 第四章串
    • 5.1 第一课时概念
    • 5.2 本章学习目标
    • 5.3 本章测验题
  • 6 第五章树和二叉树
    • 6.1 本章学习目标
    • 6.2 第一课时树的定义及基本术语
    • 6.3 第二课时二叉树定义性质存储
    • 6.4 第三课时二叉树遍历
    • 6.5 第四二叉排序与平衡二叉树
    • 6.6 第五树森林二叉树之间转换
    • 6.7 第六课时哈夫曼树
    • 6.8 本章测验题
    • 6.9 测验
    • 6.10 作业
  • 7 第六章图
    • 7.1 本章学习目标
    • 7.2 第一课时图的基本概念
    • 7.3 第二课时图的存储
    • 7.4 第三课时图的遍历
    • 7.5 第四课时最小生成树
    • 7.6 第五课时最短路径
    • 7.7 第六课时拓扑排序
    • 7.8 第七课时关键路程
    • 7.9 本章测验题
    • 7.10 测验
    • 7.11 作业
  • 8 第七章查找
    • 8.1 本章学习目标
    • 8.2 第一课时顺序查找二分查找
    • 8.3 第二课时哈希表
    • 8.4 本章测验题
    • 8.5 测验
    • 8.6 作业
  • 9 第八章排序
    • 9.1 本章学习目标
    • 9.2 第一课时基本概念
    • 9.3 第二课时插入选择排序
    • 9.4 第三课时交换排序
    • 9.5 第四课时归并 基排序及比较
    • 9.6 本章测验题
    • 9.7 测验
    • 9.8 作业
第四课时归并 基排序及比较

1 堆的定义

n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆。

若将此序列对应的一维数组看成是一个完全二叉树,ki为二叉树的根结点,k2ik2i+1分别为ki左子树根右子树根

堆排序

将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小()值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列的过程。

堆排序需解决的两个问题:

如何由一个无序序列建成一个堆?(初始建堆)

如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?

void HeapAdjust (SqList &H, int s, int m)

{// 已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足//堆的定义, 本函数调整H.r[s]的关键字,使H.r[s..m]成为//一个大顶堆(对其中记录的关键字而言)

rc = H.r[s];          // 暂存根结点的记录

for(j=2*s;j<=m;j*=2 )

  { // 沿关键字较大的孩子结点向下筛选
if ( j<m && H.r[j].key<H.r[j+1].key )  ++j;                         //j为关键字较大的孩子记录下标
if (! (rc.key<H.r[j].key )) break;
                         // 不需要调整,跳出循环
H.r[s] = H.r[j]; s = j;  // 将大关键字记录往上调
}// for

H.r[s] = rc;           // 回移筛选下来的记录

} // HeapAdjust

void HeapSort ( SqList &H )

{// 对顺序表H进行堆排序

for ( i=H.length/2; i>0; --i )
// H.r[1..H.length] 建成大顶堆
HeapAdjust ( H, i, H.length );

for ( i=H.length; i>1; --i )

  {
H.r[1] « H.r[i]; // 将堆顶记录和当前未经排
// 序的子序列H.r[1..i]中最
// 后一个记录互相交换
HeapAdjust(H, 1, i-1);//H.r[1..i-1]重新调整为
// 大顶堆
}//for

} // HeapSort

2 归并排序

归并

将两个或两个以上的有序表组合成一个新的有序表。

void Merge(RcdType SR[],RcdType &TR[],int i,int m,int n)

{// 将有序的SR[i..m]SR[m+1..n]归并为有序的TR[i..n]

for (j=m+1, k=i; i<=m && j<=n; ++k){
// SR中记录按关键字从小到大地复制到TR
if ( LQ(SR[i].key, SR[j].key)) TR[k] = SR[i++];
else TR[k] = SR[j++];
}

while(i<=m) TR[k++] = SR[i++];//将剩余的SR[i..m]复制到TR

while(j<=n) TR[k++] = SR[j++];//将剩余的SR[j..n]复制到TR

} // Merge