网上看了很多堆排序算法的实现过程,演化过程描述的很详细,这里不再赘述。
前提说明:
完全二叉树的最后一个非叶子节点的下标为(n-2)/2,若一个完全二叉树有n个节点,则n-1为最后一个叶子节点的下标,而完全二叉树中一个节点的父亲节点的下标为此节点下标减去1再除2.
于是二叉树的最后一个非叶子节点的下标就为(n-2)/2,即n/2-1
代码中添加些注释,供理解。
#include <stdio.h>
void swap(int *arr, int i , int j) //数据互换
{
int temp =arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void Print(int A[],int N) //打印
{
int i;
for(i=0;i<N;i++)
{
printf(" %d ",A[i]);
}
printf("\n");
}
void adjust(int *arr, int s, int m)
{
int j;
int rc =arr[s];
for(j = 2*s +1; j<m;j=j*2+1 ) //从i结点的左子结点开始,也就是2i+1处开始
{
if((j+1)<m && (arr[j]<arr[j+1])) j++; // < 最大堆 ; > 最小堆 // j+1 < m 保证数组不越界
if(rc < arr[j]) // < 最大堆 ; > 最小堆 //针对rc进行调整
{
arr[s] = arr[j]; // 覆盖
s =j; //记录覆盖值的下标
}
else
break;
}
arr[s]=rc; // 填充
}
void sort(int *arr,int n)
{
int i;
for(i=n/2-1; i>=0; i--) // 第一个非叶子结点为 n/2-1
adjust(arr,i,n);
for(i = n-1; i>0;i--)
{
swap(arr,0,i);
adjust(arr,0,i);
}
}
void main()
{
int arr[10] ={6,7,8,9,0,1,2,3,4,5};
sort(arr,10);
Print(arr,10);
}