堆排序
来源:互联网 发布:台达plc编程入门 编辑:程序博客网 时间:2024/06/02 04:00
排序有很多种方法,堆排序是其中的一种。它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。
堆有一个很好的性质:第i个位置上的值小于第2*i个位置上和第2*i+1个位置上的值(i<2*i && i<2*i+1),这种堆称为小根堆;第i个位置上的值大于第2*i个位置上和第2*i+1个位置上的值(i<2*i && i<2*i+1),这种堆称为大根堆。而第i个位置正好是第2*i个位置和2*i+1个位置的父母结点。
小根堆排序后是从大到小,大根堆排序后是从小到大。
我们先把准备工作做好
#include <stdio.h>#include <stdlib.h>#include<math.h>#define MAX_SIZE 100typedef char InfoType;typedef struct Sz{ int key; InfoType *info;}Sz;typedef struct SQ//定义一个顺序线性表{ Sz *R; int length;}SqList;int Init_SqList(SqList *L)//顺序线性表初始化{ L->R=(Sz *)malloc((MAX_SIZE + 1) * sizeof(Sz)) ; if(!L->R) return 0; else { L->length = 0; return 1; }}
要对一个数组进行堆排序,首先要建立一个堆。
void Heap_adjust(SqList *L, int s, int m){ /*H->R[s…m]中记录关键字除H->R[s].key均满足堆定义*/ /*调整H->R[s]的位置使之成为小根堆*/ int j = s;//起始位置 int k = 2 * j;/*计算H->R[j]的左孩子的位置*/ L->R[0] = L->R[j];/*临时保存H->R[j]*/ for (k = 2 * j; k <= m; )//k = 2*k { if(((k + 1) <= m) && (L->R[k].key > L->R[k + 1].key)) k++;/*选择左、右孩子中关键字的最的一个*/ if(L->R[k].key < L->R[0].key) { L->R[j] = L->R[k]; j = k; k = 2 * j; } else { break; } } L->R[j] = L->R[0];}
然后把第一个元素和最后一个元素交换,交换之后可能就把堆打乱了,所以要重新在建立一个堆。这样交换n-1次,数组就有序了。
void Heap_Sort(SqList *L){ int i; int j; for(j = L->length/2; j > 0; j--) Heap_adjust(L, j, L->length);/*初始建堆*/ for(j = 1; j <= L->length; j++) { printf("%d ", L->R[j].key); } printf("\n"); printf("------------------------------\n"); int k = L->length; //需要进行n-1次交换 for(j = k; j > 1; j--) { L->R[0] = L->R[1]; L->R[1] = L->R[k]; L->R[k] = L->R[0];/*堆顶与最后一个交换*/ k--;/*每交换一次,长度减一,把最后一个元素除去*/ printf("%d\n", k); if(j != 1) { for(i = ceil(k / 2); i > 0; i--) Heap_adjust(L, i, k);/*建堆*/ } for(i = 1; i <= k; i++) { printf("%d ", L->R[i].key); } printf("\n"); }}
主方法
int main(){ int i; int num; SqList L; Init_SqList(&L); /*输入数组*/ printf("please enter the number of the data:"); scanf("%d", &num); for(i = 1; i < num + 1; i++){ int values; printf("please enter the %d data:", i); scanf("%d", &values); L.R[i].key = values; L.length++; } for(i = 1; i <= L.length; i++) { printf("%d ", L.R[i].key); } printf("\n"); printf("-------------create heap----------------\n"); Heap_Sort(&L); printf("-------------after heap sort----------------\n"); for(i = 1; i <= L.length; i++) { printf("%d ", L.R[i].key); } printf("\n"); return 0;}
例:
运行结果:
阅读全文