头歌数据结构-排序的实现及其应用

第1关:直接插入排序

100

  • 学习内容
  • 参考答案
  • 记录
  • 评论
任务描述

本关任务:实现直接插入排序。

相关知识

为了完成本关任务,你需要掌握:1.顺序表的类型定义,2.直接插入排序。

顺序表的类型定义
复制代码
  1. #define MAXSIZE 100
  2. typedef int KeyType; /*关键字类型*/
  3. typedef struct
  4. {
  5. KeyType key;
  6. /*InfoType otherinfo;*/
  7. }RedType; /*记录类型*/
  8. typedef struct
  9. {
  10. RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
  11. int length; /*length存放表长*/
  12. }SeqList; /*顺序表类型*/
直接插入排序

算法思想:先将第1个记录看成是一个有序的子序列;然后从第2个记录开始逐个进行插入;直至整个序列变成一个按关键字非递减有序序列为止。

编程要求

在右侧编辑器中补充代码,完成InsertSort函数,以实现直接插入排序。具体要求如下:

* InsertSort:采用直接插入排序法,将表中记录按关键字非递减排列。

测试说明

可在右侧文件夹中查看step1/Main.cpp文件,以便于你的操作。

输入说明: 输入若干记录的关键字,以-1标志结束。

输出说明: 第一行输出排序之前的各记录的关键字。 第二行输出排序之后的各记录的关键字。

平台会对你编写的代码进行测试。

测试输入: 49 38 65 97 76 13 27 49 -1

预期输出: 49 38 65 97 76 13 27 49 13 27 38 49 49 65 76 97 //末尾换行

开始你的任务吧,祝你成功!

复制代码
/*************************************************************
    直接插入排序  实现文件  
    更新于2026年10月18日
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort.h"
	
void InsertSort(SeqList  &L) /*直接插入排序*/
{	
	int i,j;
	for(i=2;i<=L.length;i++){
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
		KeyType key = L.r[i].key;
        j=i-1;
        while(j>=1 && L.r[j].key >  key){
            L.r[j+1].key=L.r[j].key;
            j--;
        }
        L.r[j+1].key = key;
    /********** End **********/		
    }
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
	int i=1; KeyType x;
	scanf("%d",&x);
	while(x!=-1)
	{
		L.r[i++].key=x; scanf("%d",&x);
	}
	L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i].key);
	printf("\n");
}

第2关:希尔排序

200

  • 学习内容
  • 参考答案
  • 记录
  • 评论
任务描述

本关任务:实现希尔排序。

相关知识

为了完成本关任务,你需要掌握:1.顺序表的类型定义,2.希尔排序。

顺序表的类型定义
复制代码
  1. #define MAXSIZE 100
  2. typedef int KeyType; /*关键字类型*/
  3. typedef struct
  4. {
  5. KeyType key;
  6. /*InfoType otherinfo;*/
  7. }RedType; /*记录类型*/
  8. typedef struct
  9. {
  10. RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
  11. int length; /*length存放表长*/
  12. }SeqList; /*顺序表类型*/
希尔排序

算法思想:先将待排记录序列按某个增量分割成若干个子序列,然后对各子序列分别进行直接插入排序,当整个序列中的记录 "基本有序" 时,再对全体记录进行一次直接插入排序。

编程要求

在右侧编辑器中补充代码,完成ShellInsert函数,以实现希尔排序。具体要求如下:

* ShellInsert:对顺序表L作一趟增量为d的希尔排序。

测试说明

可在右侧文件夹中查看step2/Main.cpp文件,以便于你的操作。

输入说明: 输入若干记录的关键字,以-1标志结束。

输出说明: 第一行输出排序之前的各记录的关键字。 第二行输出排序之后的各记录的关键字。

平台会对你编写的代码进行测试。

测试输入: 49 38 65 97 76 13 27 49 -1

预期输出: 49 38 65 97 76 13 27 49 13 27 38 49 49 65 76 97 //末尾换行

开始你的任务吧,祝你成功!

复制代码
/*************************************************************
    希尔排序  实现文件    
    更新于2026年10月18日
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort.h"
	
void ShellInsert(SeqList &L, int d) /*对顺序表L作一趟增量为d的希尔插入排序*/
{
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
	int i,j;
    for(i=d+1;i<=L.length;i++){
        if(L.r[i].key<L.r[i-d].key){
            L.r[0]=L.r[i];
            for(j=i-d;j>0 &&L.r[0].key<L.r[j].key;j-=d){
                L.r[j+d]=L.r[j];
            }
            L.r[j+d]=L.r[0];
        }
    }
	/********** End **********/	
}
void ShellSort(SeqList &L) /*希尔排序*/
{
	int d;
	d=L.length/2;
	while(d!=0)  /*调用一趟增量为d的希尔插入排序*/
	{
		ShellInsert(L,d); d=d/2;
	}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
	int i=1; KeyType x;
	scanf("%d",&x);
	while(x!=-1)
	{
		L.r[i++].key=x; scanf("%d",&x);
	}
	L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i].key);
	printf("\n");
}

第3关:快速排序

200

  • 学习内容
  • 参考答案
  • 记录
  • 评论
任务描述

本关任务:实现快速排序。

相关知识

为了完成本关任务,你需要掌握:1.顺序表的类型定义,2.快速排序。

顺序表的类型定义
复制代码
  1. #define MAXSIZE 100
  2. typedef int KeyType; /*关键字类型*/
  3. typedef struct
  4. {
  5. KeyType key;
  6. /*InfoType otherinfo;*/
  7. }RedType; /*记录类型*/
  8. typedef struct
  9. {
  10. RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
  11. int length; /*length存放表长*/
  12. }SeqList; /*顺序表类型*/
快速排序

算法思想:首先在待排记录中任取一个记录(通常取第一个记录)作为枢轴,将枢轴放入适当的位置后,待排记录被枢轴分割成两部分,并使得枢轴左边记录的关键字均小于枢轴,右边的均大于枢轴;然后分别对这两部分继续进行快速排序,以达到整个序列有序。

编程要求

在右侧编辑器中补充代码,完成QuickSort函数,以实现快速排序。具体要求如下:

* QuickSort:对顺序表L的子序列L.r[low...high]作快速排序。

测试说明

可在右侧文件夹中查看step3/Main.cpp文件,以便于你的操作。

输入说明: 输入若干记录的关键字,以-1标志结束。

输出说明: 第一行输出排序之前的各记录的关键字。 第二行输出排序之后的各记录的关键字。

平台会对你编写的代码进行测试。

测试输入: 49 38 65 97 76 13 27 49 -1

预期输出: 49 38 65 97 76 13 27 49 13 27 38 49 49 65 76 97 //末尾换行

开始你的任务吧,祝你成功!

复制代码
/*************************************************************
    快速排序  实现文件    
    更新于2026年10月18日
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort.h"
int Partition(SeqList &L, int low, int high)
{
    KeyType pivotkey = L.r[low].key;
    L.r[0] = L.r[low];
    while (low < high)
    {
        while (low < high && L.r[high].key >= pivotkey)
            high--;
        L.r[low] = L.r[high];
        while (low < high && L.r[low].key <= pivotkey)
            low++;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
}	
void QuickSort(SeqList &L, int low, int high) /*对顺序表L的子序列L.r[low...high]作快速排序*/
{
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
    int i;
    if (low < high)
    {
        i = Partition(L, low, high);
    
	/********** End **********/
	/*分别对左、右两部分进行递归排序*/
	QuickSort(L,low,i-1);/*对左半区L.r[low..i-1]进行快速排序*/
	QuickSort(L,i+1,high);/*对右半区L.r[i+1..high]进行快速排序*/
    }	
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
	int i=1; KeyType x;
	scanf("%d",&x);
	while(x!=-1)
	{
		L.r[i++].key=x; scanf("%d",&x);
	}
	L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i].key);
	printf("\n");
}

第4关:堆排序

300

  • 学习内容
  • 参考答案
  • 记录
  • 评论
任务描述

本关任务:实现堆排序。

相关知识

为了完成本关任务,你需要掌握:1.顺序表的类型定义,2.堆,3.堆排序。

顺序表的类型定义
复制代码
  1. #define MAXSIZE 100
  2. typedef int KeyType; /*关键字类型*/
  3. typedef struct
  4. {
  5. KeyType key;
  6. /*InfoType otherinfo;*/
  7. }RedType; /*记录类型*/
  8. typedef struct
  9. {
  10. RedType r[MAXSIZE+1]; /*r[0]闲置或用作"监视哨"*/
  11. int length; /*length存放表长*/
  12. }SeqList; /*顺序表类型*/
堆
  • 含有n个关键字的序列{ k1,k2,...,kn },当且仅当满足以下性质 (1) 或 (2) 时,称之为堆:

(1) Ki​≤K2i​ 且 Ki​≤K2i+1​ ,i=1,2,...,⌊ n/2 ⌋,称为小顶堆;

(2) Ki​≥K2i​ 且 Ki​≥K2i+1​ ,i=1,2,...,⌊ n/2 ⌋,称为大顶堆。

  • 如果用一维数组存放该序列,并把此数组看成是一棵完全二叉树的顺序存储结构,则堆实质上是满足如下性质的完全二叉树:树中所有分支结点的关键字值 Ki​ 均不大于(或不小于)其左右孩子结点的关键字值 K2i​ 和K2i+1​。

  • 若序列{ k1,k2,...,kn }是堆,则堆顶元素必为序列中最小值(或最大值)。

堆排序

算法思想:首先将待排序列建成一个堆,得到关键字最小(或最大)的记录,输出堆顶的最小(大)值;然后将剩余的n-1个元素重新建成一个堆,得到次小值,输出堆顶;如此反复执行,便能得到一个有序序列。这一过程称为"堆排序"。

编程要求

在右侧编辑器中补充代码,完成HeapAdjust函数,以实现堆排序。具体要求如下:

* HeapAdjust:调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。

测试说明

可在右侧文件夹中查看step4/Main.cpp文件,以便于你的操作。

输入说明: 输入若干记录的关键字,以-1标志结束。

输出说明: 第一行输出排序之前的各记录的关键字。 第二行输出排序之后的各记录的关键字。

平台会对你编写的代码进行测试。

测试输入: 49 38 65 97 76 13 27 49 -1

预期输出: 49 38 65 97 76 13 27 49 13 27 38 49 49 65 76 97 //末尾换行

开始你的任务吧,祝你成功!

复制代码
/*************************************************************
    堆排序  实现文件    
    更新于2026年10月18日
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort.h"
	
void HeapAdjust(SeqList &L, int low, int high)
{/*已知L.r[low..high]中记录的关键字除L.r[low].key之外均满足堆的定义,*/
 /*调整L.r[low].key,使L.r[low..high]成为一个新大顶堆。*/
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
	  int i = low, j = 2 * i; 
    KeyType temp = L.r[i].key; 
 
    while (j <= high) {
        if (j < high && L.r[j].key < L.r[j + 1].key) {
            j++; 
        }
        if (temp >= L.r[j].key) {
            break; 
        }
        L.r[i].key = L.r[j].key;
        i = j;
        j = 2 * i;
    }
    L.r[i].key = temp;
	/********** End **********/
}
void HeapSort(SeqList &L) /*堆排序*/
{
	int i;
	for(i=L.length/2;i>0;i--)/*从最后一个分支结点(编号为L.length/2)开始调整,建立初始堆*/
		HeapAdjust(L,i,L.length);
	for(i=L.length;i>1;i--)
	{
		L.r[0]=L.r[1];L.r[1]=L.r[i];L.r[i]=L.r[0];/*将堆顶L.r[1]和当前最后一个记录L.r[i]交换*/
		HeapAdjust(L,1,i-1);/*将剩余记录L.r[1..i-1]重新调整为堆*/
	}
}
void SeqListInput(SeqList &L) /*输入若干记录的关键字,存放到顺序表L中*/
{
	int i=1; KeyType x;
	scanf("%d",&x);
	while(x!=-1)
	{
		L.r[i++].key=x; scanf("%d",&x);
	}
	L.length=i-1;
}
void SeqListOutput(SeqList L) /*输出顺序表L中各记录的关键字*/
{
	int i;
	for(i=1;i<=L.length;i++)
		printf("%d ",L.r[i].key);
	printf("\n");
}
相关推荐
白杨尚青3 小时前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
likexuec21 小时前
数据结构(2)
数据结构
D e re k ZH1 天前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶1 天前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
十二2 天前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
D e re k ZH2 天前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
careathers2 天前
【数据结构】基于比较的排序算法 - 交换排序
数据结构·算法·排序算法
H.莓飛2 天前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
老师我太想进步了20263 天前
【数据结构-4】算法美学之顺序表
数据结构·算法
GrowingIO技术社区3 天前
CDP、行为分析、归因与营销自动化有什么区别?
数据结构·数据挖掘·数据分析