【说明】以下代码实现最终均为递增序列,即从小到大排序。
#include<stdio.h>
#define ElemType int
/*函数声明*/
void swap(int& a, int& b); //1-1.交换
void SelectSort(ElemType A[], int n); //1-2.简单选择排序
void PrintA(ElemType A[], int len); //1-3.输出测试
void HeadAdjust(ElemType A[], int k, int len); //2-1.堆调整(以大根堆为例)
void BuildMaxHeap(ElemType A[], int len); //2-2.建立大根堆
void HeapSort(ElemType A[], int len); //2-3.堆排序
void PrintB(ElemType B[], int len); //2-4.输出测试
//1-1.交换
void swap(int& a, int& b) { //涉及两个元素实际交换,要带引用
int temp = a;
a = b;
b = temp;
}
//1-2.简单选择排序
void SelectSort(ElemType A[], int n) {
for (int i = 0; i < n - 1; i++) { //一共进行n-1趟排序
int min = i; //记录最小元素位置
for (int j = i + 1; j < n; j++) //再A[i...n-1]中选择最小元素
if (A[j] < A[min])
min = j; //更新最小元素的位置
if (min != i)
swap(A[i], A[min]); //封装的swap函数共移动元素3次
}
}
//1-3.输出测试
void PrintA(ElemType A[], int len) {
for (int i = 0; i < len; i++)
printf("%d\t", A[i]);
printf("%\n");
}
//2-1.堆调整(以大根堆为例)
void HeadAdjust(ElemType A[], int k, int len) {
//函数HeadAdjust将元素k为根的子树进行调整
A[0] = A[k]; //A[0]暂存子树的根结点
for (int i = 2 * k; i <= len; i *= 2) { //沿key较大的子结点向下筛选
if (i < len && A[i] < A[i + 1]) //子树根结点的左右孩子
i++; //取key较大的孩子的下标
if (A[0] >= A[i])
break; //若子树的根结点大于左右孩子,不必调整
else { //否则
A[k] = A[i]; //A[i]提到子树的根结点
k = i; //修改k值,继续向下筛选
}
}
A[k] = A[0]; //被筛选结点的值放入最终位置
}
//2-2.建立大根堆
void BuildMaxHeap(ElemType A[], int len) {
for (int i = len / 2; i > 0; i--) //从i=[n/2]~1,反复调整堆
HeadAdjust(A, i, len);
}
//2-3.堆排序
void HeapSort(ElemType A[], int len) {
BuildMaxHeap(A, len); //建立大根堆
for (int i = len; i > 1; i--) { //n-1趟的交换和调整过程
swap(A[i], A[1]); //输出堆顶元素(和堆底元素交换)
HeadAdjust(A, 1, i - 1); //调整,把剩余的i-1个元素整理成堆
}
}
//2-4.输出测试
void PrintB(ElemType B[], int len) {
for (int i = 1; i < len + 1; i++)
printf("%d\t", B[i]);
printf("%\n");
}
int main() {
/*1、简单选择排序*/
ElemType A[] = { 49,38,65,97,76,13,27,49 };
SelectSort(A, 8);
printf("<————————————简单选择排序————————————>\n");
PrintA(A, 8);
/*2、堆排序*/
ElemType B[] = { -1,53,17,78,9,45,65,87,32 };
//2-1.建立大根堆
BuildMaxHeap(B, 8);
printf("<————————————建立大根堆————————————>\n");
PrintB(B, 8);
//2-2.堆排序
HeapSort(B, 8);
printf("<————————————堆排序————————————>\n");
PrintB(B, 8);
return 0;
}
一、选择排序的概念
二、关于两种选择排序的性能分析
三、其他说明
四、关于堆的插入删除和关键字的比较次数