排序

选择排序

简单选择排序

堆排序

堆排序(heap sort)是一种树形选择排序,在排序过程中,将待排序的记录 r[1,2,...,n] 看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲和孩子结点之间的内在联系,在当前无序的序列中选择关键字最大(或最小)的记录。

堆的定义:对一个有n个元素的序列{k1,k2,...,kn},将和此序列对应的一维数组看作为一棵完全二叉树,则当且仅当非终端结点的值均不大于(或不小于)其左右孩子结点的值时,称为小根堆(大根堆)。

在小根堆(大根堆)中,堆顶元素(即完全二叉树的根结点)必为序列中的最小值(最大值)。

代码:

//算法8.9 堆排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAXSIZE 20 //顺序表的最大长度
typedef struct ElemType {
int key;
char* otherinfo;
}ElemType;
//顺序表的存储结构
typedef struct SqList {
ElemType* r; //存储空间的基地址
int length; //顺序表长度
}SqList;
//用算法8.7 筛选法调整堆
void HeapAdjust(SqList* L, int s, int m) {
//假设r[s+1..m]已经是堆,将r[s..m]调整为以r[s]为根的大根堆
ElemType rc;
rc = (*L).r[s];
for (int j = 2 * s; j <= m; j *= 2) { //沿key较大的孩子结点向下筛选
if (j < m && (*L).r[j].key < (*L).r[j + 1].key)
++j; //j为key较大的记录的下标
if (rc.key >= (*L).r[j].key)
break; //rc应插入在位置s上
(*L).r[s] = (*L).r[j];
s = j;
}
(*L).r[s] = rc; //插入
}
void Create_Sq(SqList* L) {
int n;
//输入个数
printf("请输入数据个数,不超过 %d 个: \n", MAXSIZE);
scanf("%d", &n);
printf("请输入待排序的数据:\n");
while (n > MAXSIZE) {
printf("个数超过上限,不能超过 %d 个,请重新输入: \n", MAXSIZE);
scanf("%d", &n);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &((*L).r[i].key));
(*L).length++;
}
}
//用算法8.8 建初堆, 把无序序列L.r[1..n]建成大根堆
void CreatHeap(SqList* L) {
int i, n;
n = (*L).length;
for (i = n / 2; i > 0; --i) //反复调用HeapAdjust
HeapAdjust(L, i, n);
}
//对顺序表L进行堆排序
void HeapSort(SqList* L) {
ElemType x;
CreatHeap(L); //把无序序列L.r[1..L.length]建成大根堆
for (int i = (*L).length; i > 1; --i) {
x = (*L).r[1]; //将堆顶记录和当前未经排序子序列L.r[1..i]中最后一个记录互换
(*L).r[1] = (*L).r[i];
(*L).r[i] = x;
HeapAdjust(L, 1, i - 1); //将L.r[1..i-1]重新调整为大根堆
}
}
void show(SqList L) {
for (int i = 1; i <= L.length; i++)
printf("%d\n", L.r[i].key);
}
int main() {
SqList L;
L.r = (ElemType*)malloc(sizeof(ElemType) * (MAXSIZE + 1));
L.length = 0;
Create_Sq(&L);
HeapSort(&L);
printf("排序后的结果为:\n");
show(L);
return 0;
}

执行结果:

请输入数据个数,不超过 20 个:
9
请输入待排序的数据:
2 6 8 2 1 3 6 8 7
排序后的结果为:
1
2
2
3
6
6
7
8
8
posted @   有空  阅读(8)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示

目录导航