简单堆排序(大根堆)

来源:互联网 发布:c语言教学视频哪个好 编辑:程序博客网 时间:2024/06/08 04:15

今天把书看了半天,终于自己写了个基于数组的堆排序。Debug又花了半天,结果发现是一条赋值语句放在了while里面......好像是第二次这种错误了?MDZZ

话不多说上代码,就一个源文件:

#include<iostream>
using namespace std;


void heap_sort(int[]);                         //总的驱动堆排序的函数
void insert_heap(const int current, int low, int high, int[]);   //关键函数,其余两个的实现也靠他,前态:

下标low+1到high是堆(基于在数组中的下标)

后态:插入值为current的元素,使得插入后下标low--high仍是堆。(这样原low位置的元素就被覆盖了,注意,它本来是位于最前的最大元素)
void build_heap(int[], int count);//起初把数组先构成一个堆。


void insert_heap(const int current, int low, int high, int a[])
{
int large = 2 * low + 1;
while (large <= high)//没有子,循环就结束了
{
if (large<high&&a[large]<a[large + 1])//有右子且它比左子大,那就选它做候选人吧
large++;
if (current >= a[large])     //current比拿掉结点的子都大,那就找到了能放的地方了
break;
else
{
a[low] = a[large];                    //子来继承了
low = large;                           //又拿掉了一个节点,重复这个过程找继承者
large = 2 * low + 1;
}
}
a[low] = current;//找到可以插入current的合适位置
}


void build_heap(int a[], int count)
{
int low, current;
for (low = count / 2 - 1; low >= 0; low--)
//挺巧妙的,一完整数组的后半部分一定构成堆,因为它们都没有子了呀
{
current = a[low];                            //准备插入这一串堆之前的一个元素
insert_heap(current, low, count - 1, a);//一个一个往前挪,知道最前面一个也插入,数组全构成堆了。
}
}


void heap_sort(int a[], int count)
{
int current, last_sorted;
build_heap(a, count);//先把数组变成一个堆
for (last_sorted = count - 1; last_sorted>0; last_sorted--)//大的元素都取完,余下首部一定是最小的,因此last_sorted>0即可
{
current = a[last_sorted];//从尾部开始取元素,因为它即将被覆盖
a[last_sorted] = a[0];    //取首部最大的元素,放尾部,尾部原有元素被覆盖
insert_heap(current, 0, last_sorted - 1, a);//被覆盖的元素重新插入堆(堆的元素少了一个)索引下标也可以往前挪了。
}
}


int main()//举个简单的例子试验一下
{
int a[10];
for (int i = 0; i<10; i++)//随机输入十个无序的数字(debug的时候是3个,好调试一点)
{
cin >> a[i];
}
heap_sort(a, 10);
for (int i = 0; i<10; i++)//成功地从小到大进行了排序
cout << a[i] << ' ';
cout << endl;
system("pause");
return 0;
}

1 0
原创粉丝点击