什么是堆
弄清楚堆排序之前,先弄清楚什么是堆。堆就是一个数据结构,是一个完全二叉树,满足所有的非叶子结点的值大于等于左右孩子结点。
n个数的集合{a1,a2,a3,a4,a5.........ai......an} // i在这里表示下标
左孩子结点 :相当于(父结点*2) //*乘以的意思
右孩子结点: 相当于(父结点*2+1)//*乘以的意思
小根堆满足 ai<=a(2i+1) && ai<=a2i
大根堆满足 ai >= a(2i) && ai>=a(2i+1)
(注意下这里是从下标1开始的,然而数组一般是从下标0开始,那样的话孩子结点下标不是这么计算的了)
记住堆调整是整体由上往下调整
建堆时候,是从下依次往上建立,把大数一直往上跑
void Heapadjust(int arr[],int fnode,int pop) //arr是传入数组,fnode是要调整的父结点 pop相当于标记数组下标,可以理解为pop =(len-1-已经排好的数据个数)
{
for(int maxnode = 2*fnode+1; maxnode <= pop; maxnode = 2*maxnode+1)
//maxnode一开始相当于左孩子结点,如果存在右孩子结点且右孩子结点比左孩子结点大那么把maxnode变成右孩子。在两个孩子中判断哪个更大,maxnode相当于大的那个下标
{
if(maxnode < pop && arr[maxnode]<arr[maxnode+1]) 这里是先判断是否存在右孩子结点在判断左右哪个大
{
maxnode++;
}
if(arr[maxnode] <= arr[fnode])//如果这是一个不用调整的堆,父结点比另外两个孩子结点都大证明不用调整break跳出循环
{
break;
}
else //否则就交换父结点和那个maxnode存的数据
{
int tmp = 0;
tmp = arr[maxnode];
arr[maxnode] = arr[fnode];
arr[fnode] = tmp;
}
fnode = maxnode; //因为这个结点数据发生变化,所以开始又要调整这边的堆了
}
}
void Heapsort(int arr[],int len)
{
int index = len-1;
for(int i=(index-1)/2; i>=0; i--) //这个是相当于建堆
{
Heapadjust(arr,i,index);
}
for(int j = index; j>=0; j--) //这部分是相当于排序
{
int tmp = arr[0];
arr[0] = arr[j];
arr[j] = tmp;
Heapadjust(arr,0,j-1);
}
}