堆排序
排序思路:(1)创建一个堆;(借助队列,按层创建)
(2)交换跟节点和最后一个叶子节点的值,在大堆中排除该叶子节点,再将 剩余的二叉树调整成大根堆;
(3)重复步骤2,直至二叉树中只有一个节点
//实现代码:
#include<stdio.h>
#include<stdlib.h>
#define N 8
int front=0;
int rear=0;
typedef struct node{
int data;
struct node *left,*right;
}BTnode;
void PrintTree(BTnode **Q);
BTnode *CreatBTree(int a[],BTnode **Q);
void PHeap(BTnode *r,BTnode **Q);
BTnode** _Heap(int D[]);
//创建完全二叉树
BTnode* CreatBTree(int a[],BTnode **Q)
{
BTnode *root,*t;
t=root=NULL;
int i;
//创建头结点
BTnode *p=(BTnode *)malloc(sizeof(BTnode));
p->data=a[0];
p->left=p->right=NULL;
Q[++rear]=root=p;
for(i=1;i<N;++i){
if(!t){
t=Q[++front]; //如果右孩子不为空,出队节点赋给t
}
BTnode* p=(BTnode *)malloc(sizeof(BTnode));
p->data=a[i];
p->left=p->right=NULL;
if(!(t->left)) { t->left=p; } //如果左孩子为空,填充左孩子
else{ //如果左孩子不为空,填充右孩子,并将t赋为空;
t->right=p;
t=NULL;
}
Q[++rear]=p; //入队操作
}
return root;
}
//调整完全二叉树(成大根堆结束)
void PHeap(BTnode *r,BTnode **Q)
{
// 1.先调整最后入队的最小二叉树,(可能没有右孩子,但是肯定有左孩子,即不是叶子节点)
// 2.通过 --K, 从队列向前遍历调整
// 3,通过外层死循环,不断调整,如果没有调整表示该二叉树已是大根堆,结束;
int flag,k,x;
while(1){
k=front;
flag=0; //注意每次遍历调整完都要置0,否则会出现死循环
while(k > 0){
if( Q[k]->data < Q[k]->left->data ){
x=Q[k]->left->data;
Q[k]->left->data=Q[k]->data;
Q[k]->data=x;
flag=1;
}
if(Q[k]->right && Q[k]->data < Q[k]->right->data){
x=Q[k]->data;
Q[k]->data = Q[k]->right->data;
Q[k]->right->data = x;
flag=1;
}
--k;
}
if(!flag) break;
}
}
//打印函数(从队列后面开始向前打印)
void PrintTree(BTnode **Q)
{ int i;
for(i=N;i>0;--i){
printf("%5d",Q[i]->data);
}
printf("\n");
}
//堆排序调用函数
BTnode** _Heap(int D[])
{
BTnode *root,*t,*k;
int x;
int y=1;
//声明队列
BTnode **Q=(BTnode **)malloc((N+1)*sizeof(BTnode *));
//创建完全二叉树
root=CreatBTree(D,Q);
//调整堆
PHeap(root,Q);
//交换根结点与队尾的叶子节点
while(rear > 1){
//交换
x=root->data;
root->data = Q[rear]->data;
Q[rear]->data =x;
--rear;
//砍叶子
if(Q[front]->right) Q[front]->right=NULL;
else{
Q[front]->left=NULL;
--front;
}
PHeap(root,Q);
}
return Q;
}
int main(void)
{
int data;
int D[N];
int i;
srand(time(NULL));
for(i=0;i<N;++i){
D[i] =rand()%100;
}
//堆排序(降序排序)
BTnode** Q=_Heap(D);
PrintTree(Q);
return 0;
}
如下为运行结果: