堆排序(大顶堆)

来源:互联网 发布:北京赛车源码 编辑:程序博客网 时间:2024/06/07 07:07

最近在看算法导论,顺便把里面的程序都实现下,先拿堆排序来练练手吧。

首先介绍下堆调整,堆是一种数据结构,是一种完全二叉树(不一定是满二叉树),所以根节点与叶子节点满足关系如下:根节点下标为i,左叶子为下标2*i,右叶子下标为2*i+1,当然这里我们用数组来对堆进行存储。堆的子树必须满足如下关系,根节点大于左子树且大于右子树。

堆调整的方法如下,检测根节点是否为叶子节点,是退出,否调出子树中最大的值作为根节点,并对受影响的叶子节点进行递归调整。代码如下:

int modify(int length,int i,int array_sort[]){int max = i,r,l;r = right(i);l = left(i);if(i > length/2) return 0;if(l <= length && array_sort[l] > array_sort[max])max = l;    if(r <= length && array_sort[r] > array_sort[max])max = r;if(max != i){swap(array_sort[max],array_sort[i]);modify(length,max,array_sort);}}

之后介绍建立堆,给定数组123456,得到堆,对得到的堆进行调整可以从第一个非叶子节点进行对调整,直到调整到根节点。代码如下:

void create_heap(int array_sort[],int length){int i;for(i = length/2;i >= 1; i--){modify(length,i,array_sort);}}
最后介绍下堆排序的过程,首先对给定的数组建立堆,建立完成之后,堆顶必为最大的值,将堆顶与堆尾交换(即将堆定移除堆),之后重新对堆进行调整(堆长度减一),

之后再交换再调整,直到堆中只有一个数为止,全部代码如下:

#include<iostream>#include<stdio.h>#define left(x) (x)<<1#define right(x) ((x)<<1)+1#define LENGTH 10000void swap(int &a,int &b){int temp;temp = a;a = b;b = temp;}int modify(int length,int i,int array_sort[]){int max = i,r,l;r = right(i);l = left(i);if(i > length/2) return 0;if(l <= length && array_sort[l] > array_sort[max])max = l;    if(r <= length && array_sort[r] > array_sort[max])max = r;if(max != i){swap(array_sort[max],array_sort[i]);modify(length,max,array_sort);}}void create_heap(int array_sort[],int length){int i;for(i = length/2;i >= 1; i--){modify(length,i,array_sort);}}void heap_sort(int array_sort[],int length){create_heap(array_sort,length);for(int i = length;i >= 1; i--){            swap(array_sort[1],array_sort[i]);            modify(i-1,1,array_sort);    }}int main(){int length,i,array_sort[LENGTH];printf("intput length of the array you want to sort\n");scanf("%d",&length);printf("int put the array now\n");for(i = 1;i <= length; i++)scanf("%d",&array_sort[i]);heap_sort(array_sort,length);for(i = 1;i <=length;i++)printf("%d ",array_sort[i]);system("pause");return 0;}


原创粉丝点击