#include <iostream>
#include <vector>
using namespace std;
void swap(int index1,int index2,vector<int>& v)
{
int tmp;
tmp = v[index1];
v[index1] = v[index2];
v[index2] = tmp;
}
void siftup( int index,vector<int>& v)
{
int n=v.size();
//堆的层数为logn
int parent ;
for(int i=index;i>=1;)
{
parent = i/2;
//父节点比当前子节点大/小,交换
if( v[parent]<v[i] )
{
swap(parent,i,v);
i = parent;
}
else
return;
}
}
void siftdown( int index,vector<int>& v)
{
int n=v.size();
//堆的层数为logn
int child ;
int i = 1;
do
{
//左子节点
child = i*2;
//超出范围
if(child>index+1)
{
break;
}
else if(child<=index)//存在右子节点
{
//找到较小/大的子节点
if(v[child]>v[child-1])
{
child++;
}
}
//父节点比当前子节点大/小,交换
if( v[i-1]<v[child-1] )
{
swap(child-1,i-1,v);
i = child;
}
else
return;
}while(1);
}
void siftdown( int index,int max,vector<int>& v)
{
int n=v.size();
//堆的层数为logn
int child ;
int i = index;
do
{
//左子节点
child = i*2;
//超出范围
if(child>max+1)
{
break;
}
else if(child<=max)//存在右子节点
{
//找到较小/大的子节点
if(v[child]>v[child-1])
{
child++;
}
}
//父节点比当前子节点大/小,交换
if( v[i-1]<v[child-1] )
{
swap(child-1,i-1,v);
i = child;
}
else
return;
}while(1);
}
void heapsort(vector<int>& v)
{
//建堆
/* for(int i=0;i<v.size();++i)
{
siftup(i,v);
}*/
/* 对于所有i>size/2的元素来说,(i,size)为排好的heap
* 所以当siftdown时,可以从size/2开始,到1结束
*/
int size = v.size();
for(int i=size/2;i>=1;--i)
{
siftdown(i,size,v);
}
cout<<"heap:"<<endl;
for(int i=0;i<v.size();i++)
{
cout<<v[i]<<endl;
}
//int n=1;
//建立有序序列
for(int i=v.size()-1;i>=1;--i)
{
//交换v[1]和无序序列最左边的值
swap(0,i,v);
//破坏堆属性了,重新建堆
siftdown(i-1,v);
/* cout<<"step:"<<n++<<" :"<<endl;
for(int i=0;i<v.size();i++)
{
cout<<v[i]<<endl;
}*/
}
//排序完毕
return ;
}
int main(void)
{
vector<int> v;
int tmp=0;
for(tmp=0;tmp<10;tmp+=10)
{
v.push_back(tmp);
v.push_back(tmp+1);
v.push_back(tmp+9);
v.push_back(tmp+7);
v.push_back(tmp+2);
v.push_back(tmp+8);
v.push_back(tmp+5);
v.push_back(tmp+6);
v.push_back(tmp+3);
v.push_back(tmp+4);
}
cout<<"before sort:"<<endl;
for(int i=0;i<v.size();i++)
{
cout<<v[i]<<endl;
}
heapsort(v);
cout<<"after sort:"<<endl;
for(int i=0;i<v.size();i++)
{
cout<<v[i]<<endl;
}
return 0;
}