堆排序算法的实现

参考博客:白话经典算法系列之七 堆与堆排序
参考视频:堆排序(heapsort)

/************************************
* 功能: 对数组元素进行堆排序
* 作者: khq
* 时间: 2020年4月23日
*************************************/
#include

void heapify(int tree[],int n,int i);
void swap(int tree[],int i,int j);
void printArr(int tree[],int n);
void build_heap(int tree[],int n);
void heap_sort(int tree[],int n);

int main(void){
	int tree[8] = {-8,3,1,15,22,-10,7,45};
	int n = 8;
	printf("堆排序前\n");
	printArr(tree,n);
	heap_sort(tree,n);
	printf("堆排序后\n");
	printArr(tree,n);
	return 0;
}

//第一步:对某一个节点进行堆化 
/***************************************************************
* n:表示数组元素的个数
* i:表示数组的第i个下标,也即是完全二叉树的第i个节点
* 使用数组保存完全二叉树好处:根据i可推算出它的父节点和子节点
* 父节点下标:(i-1)/2
* 子节点下标:c1=2*i+1;c2=2*i+2
***************************************************************/
void heapify(int tree[],int n,int i){
	if(i>=n){
		return ;
	}
	//确定第i个节点的两个子节点
	int C1 = 2*i+1;
	int C2 = 2*i+2;
	
	//假定第i个节点的值最大
	int max = i;
	if(C1<n && tree[C1] > tree[max]){
		max = C1;
	}
	if(C2<n && tree[C2] > tree[max]){
		max = C2;
	}
	if(max!=i){
		swap(tree,max,i);
		heapify(tree,n,max);
	}
}

//建立堆
void build_heap(int tree[],int n){
	//从最后一个节点的父节点开始进行堆化,确保根节点的值是最大的
	int last_node = n-1;
	int parent_node = (last_node-1)/2;
	for(int i=parent_node;i>=0;i--){
		heapify(tree,n,i);
	}
}

//堆排序
void heap_sort(int tree[],int n){
	//先建立堆
	build_heap(tree,n);
	//取根节点,也即是最大值,与最后一个叶子结点互换后,并将最后一个结点删掉,也就是取出来,再对根节点重新堆化,重复上述操作
	for(int i=n-1;i>=0;i--){
		swap(tree,i,0);
		heapify(tree,i,0);
	}
}

void swap(int tree[],int i,int j){
	int temp = tree[j];
	tree[j] = tree[i];
	tree[i] = temp;
}

void printArr(int tree[],int n){
	for(int i=0;i<n;i++){
		printf("%d ",tree[i]);
	}
	printf("\n");
}

结果:
堆排序算法的实现_第1张图片

你可能感兴趣的:(数据结构基础)