您的位置:首页 > 其它

堆排序

2017-07-08 16:03 375 查看

排序算法--堆排序(大根堆实现)

堆排序的平均时间复杂度 :O(N*logN)

空间复杂度:O(1)



堆排序算法的演示。首先,将元素进行重排,以匹配堆的条件。图中排序过程之前简单的绘出了堆树的结构。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define LEFT 2*nRootID+1
#define RIGHT 2*nRootID+2

//1.建初始堆
// (1)从最后一个父亲节点开始
// 1.1比较左右孩子大小
// 1.2拿大的和父亲比较
// 比父亲大:与父亲交换,被交换位置作为新的被调整节点,重复1.1和1.2
// 比父亲小:结束,进行下一个父亲节点 的调整
//2.排序
// 2.1 拿堆顶与当前数组的最后位置值交换
// 2.2最后位置元素不参与运算
//
//调整父亲节点
void Adjust(int a[],int nlen,int nRootID)
{
while (1)
{
//两个孩子
if(RIGHT<nlen)
{
//比较两个孩子大小,大的和父亲交换值
if(a[LEFT]>a[RIGHT])
{
if(a[LEFT]>a[nRootID])
{
//和父亲节点值交换
a[LEFT]^=a[nRootID];
a[nRootID]^=a[LEFT];
a[LEFT]^=a[nRootID];
nRootID=LEFT;
continue;
}
else
{
break;
}
}

else
{
if(a[RIGHT]>a[nRootID]){
a[RIGHT]^=a[nRootID];
a[nRootID]^=a[RIGHT];
a[RIGHT]^=a[nRootID];
nRootID=RIGHT;
continue;
}
else
{
break;
}
}
}

//一个孩子
else if (LEFT<nlen)
{
if(a[LEFT]>a[nRootID])
{
//大的和父亲交换
a[LEFT]^=a[nRootID];
a[nRootID]^=a[LEFT];
a[LEFT]^=a[nRootID];
nRootID=LEFT;
continue;
}
else
{
break;
}
}
else
{
//没有孩子
break;
}
}
}

void Adjust2(int a[],int nlen,int nRootID)
{
int MAX;
for(MAX=LEFT;MAX<nlen;MAX=LEFT)
{
//2个孩子
if(RIGHT<nlen)
{
if(a[RIGHT]>a[LEFT])
{
MAX=RIGHT;
}
}

//大的和父亲节点交换
if(a[MAX]>a[nRootID])
{
a[MAX]^=a[nRootID];
a[nRootID]^=a[MAX];
a[MAX]^=a[nRootID];

nRootID=MAX;
}
else
{
break;
}
}

}
void HeapSort(int a[],int nlen)
{
int i;
if(a==NULL ||nlen<=0) return ;
//从最后一个父亲节点开始调整
for(i=nlen/2-1;i>=0;i--)
{
//Adjust(a,nlen,i);

Adjust2(a,nlen,i);
}
//排序

for(i=nlen-1;i>0;i--)
{
//从最后一个父亲节点开始调整为大根堆
a[0]^=a[i];a[i]^=a[0];a[0]^=a[i];//重新调整堆顶

//Adjust2(a,i,0);
Adjust2(a,i,0);
}
}

int main()
{
int i;
int a[]={5,3,2,1,4,6,8,9,7};
int len=sizeof(a)/sizeof(a[0]);
HeapSort(a,len);

for(i=0;i<len;i++)
{
printf("%d ",a[i]);
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法 C 堆排序