您的位置:首页 > 编程语言 > Go语言

【Algothrim】堆排序

2017-03-16 11:51 447 查看
性能最好的排序之一,除了归并,就是堆。

时间复杂度是:o(logn)

空间复杂度:o(1)

不是一个稳定的排序

有四种不稳定的排序:快速 选择 希尔 堆

排序的稳定性是指如果在排序的序列中,存在前后相同的两个元素的话,排序前 和排序后他们的相对位置不发生变化

堆排序用的数据结构是用数组来表示一颗完全二叉树

完全二叉树是效率很高的数据结构

完全二叉树是只有最下面的两层结点度能够小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树

算法的实现分为2步,

1, 建立最大堆

从第一个非叶子节点开始,length/2-1

如果有2个孩子,则将两个孩子里大的该节点交换

交换后,如果这个孩子节点有孩子,会导致该孩子节点作为父节点的时候不是最大堆,那么再交换长最大堆

2, 交换后调整

建立最大堆后,根节点就是最大值,和最后一个交换

去掉最后一个节点,将剩下的节点重新建立最大堆

实现

#include <iostream>
using namespace std;

void myprint(int a[], int n)
{
int i = 0;
for (i = 0; i < n; i++)
{
printf("%d\t", a[i]);
}
printf("\n");
}

void adjust(int a[], int i, int n)
{
while (i < n)
{

int lchild = 2 * i + 1;

if (lchild + 1 < n && a[lchild + 1] > a[lchild])
lchild++;

if (lchild<n-1 && a[lchild] >a[i])
{
int temp = a[i];
a[i] = a[lchild];
a[lchild] = temp;
i = lchild;//交换了这个孩子,导致这个孩子作为根节点的情况被改变,所以要重新调整
}
else
{
break;//没有引起变化,无须调整
}

}
}

void mysort(int a[], int n)
{
int i = n / 2 - 1;
for (; i >=0; i--)
{
adjust(a,i,n);
}

for (i = n - 1; i >= 0; i--)
{
int temp = a[i];
a[i] = a[0];
a[0] = temp;
adjust(a,0,i);
}
}

int main()
{
int a[10] = { 9, 7, 6, 41, 78, 54, 232, 52, 42, 10 };
printf("Orignal list is ...\n");
myprint(a, 10);
mysort(a, 10);
printf("New list is ...\n");
myprint(a, 10);
return 0;
}


运行结果

Orignal list is ...

9       7       6       41      78      54      232     52      42      10

New list is ...

7       6       9       10      41      42      52      54      78      232


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: