根据理解自己写的, 写好了之后发现建立没毛病,调整某个地方错了,找了两个小时才找到。
思路看这里的图。
http://www.cnblogs.com/wuchanming/p/3821607.html
每次都是拉出堆顶!!!
#include<bits/stdc++.h>
#define N 100000
using namespace std;
int a[N], n;
void creatheap(int x);
void adjust(int l, int r);
int top = 0;
int main()
{
cin >> n;
int t;
for(int i = 1; i <= n; i++)
{
cin >> t;
creatheap(t); //建立堆,向堆里插个数。我建的是小顶堆,堆顶最小。
} 排序时,每次把堆顶元素与为排序的堆的最后一个元素交换再调整堆。
所以等排完序后,最后一个元素是最小的,堆顶是最大了,再看下上面的那个博哥的图。
for(int i = top; i >= 2; i--)
{
adjust(1, i); 每次都能把一个最小的给排出来,挪到a【i】,剩下i-1个元素需要调整。每次都是。
}
for(int i = 1; i <= n; i++)
{
printf("%d ",a[i]); // 输出的是从大到小的堆。
}
return 0;
}
void creatheap(int x)
{
a[++top] = x;
int pos = top;
for(int i = pos/2; i > 0; i = pos/2) 建立堆是先插到堆的最后一个位置,
然后往上一个个判断是不是要进行交换。直到父亲比自己小。
{
if(a[pos] < a[i])
{
swap(a[pos], a[i]);
}
else break;
pos = i;
}
}
void adjust(int lelf, int right) 其实left没用到,因为堆顶的下标就是1。
{
swap(a[1], a[right]);
int l, r;
for(int i = 1; i < right;)
{
l = i*2;
r = l+1;
if(r > right) break; 到底就说明堆排好了。
if(r == right)
{
if(a[i] > a[l])
swap(a[i], a[l]);
break;
}
else
{
if(a[i] <= a[l] && a[i] <= a[r]) break;
else if(a[l] == min(a[l],a[r]))
{
swap(a[l], a[i]);
i = l;
}
else
{
swap(a[r], a[i]);
i = r;
}
}
}
}