一种堆排序实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yxw0609131056/article/details/79497045

堆排序: 基于优先队列(二叉堆)进行的排序

时间复杂度为: O(N log N)

#include<stdio.h>
#include<stdlib.h>

struct BH_Node{
	int size;
	int *heap;
	int capacity;
};

//分配一个二叉堆
struct BH_Node *init_Binary_Heap(int capacity)
{
	struct BH_Node *p;
	p = malloc(sizeof(struct BH_Node));
	if(NULL == p)
	{
		printf("Error:out of memory!\n");
		return NULL;
	}
	p->heap = malloc(sizeof(int)*(capacity+1));
	if(NULL == p->heap)
	{
		printf("Error:out of memory!\n");
		return NULL;
	}
	p->size = 0;
	p->heap[0] = 65535;//添加一个哨兵
	p->capacity = capacity;
	return p;
}

//用要排序的数据构造一个二叉堆(max)
//注意下标从1开始
int insert_Binary_Heap(int c,struct BH_Node *p)
{
	int i;
	if(NULL == p)
	{
		printf("Error:please first init a Binary Heap!\n");
		return -1;
	}
	if(p->size >= p->capacity)
	{
		printf("Error:the current Heap is already full!\n");
		return -1;
	}
	i = p->size + 1;
	while(c > p->heap[i/2])
	{
		p->heap[i] = p->heap[i/2];//下滤
		i = i / 2;
	}
	p->heap[i] = c;
	p->size++;
	return 0;
}

//不断将下标为1的元素(最大值)和当前最后一个元素交换
//然后将size减1,将最大元素排除在外,再重新针对新下标
//为1的元素进行下滤操作
int delete_max_Binary_Heap(struct BH_Node *p)
{
	int temp;
	int max;
	int i;
	if(NULL == p)
	{
		printf("Error: H == NULL\n");
		return -1;
	}
	if(p->size == 0)
	{
		printf("Error:the current Heap is already empty!\n");
		return -1;
	}
	//swap操作
	max = p->heap[1];
	p->heap[1] = p->heap[p->size];
	p->heap[p->size] = max;
	//注意将最后一个元素不再参与下滤操作
	p->size--;
	for(i = 1;2*i <= p->size;)
	{
		//判断该节点是否有两个子节点
		if(2*i + 1 <= p->size)
		{
			//判断该节点与两个子节点之间关系,来决定如何进行下滤操作
			//左右两个节点都大于该节点
			if((p->heap[i] < p->heap[2*i])&&(p->heap[i] < p->heap[2*i + 1]))
			{
				//右节点最大,将其进行互换
				if((p->heap[2*i] < p->heap[2*i+1]))
				{
					temp = p->heap[i];
					p->heap[i] = p->heap[2*i+1];
					p->heap[2*i+1] = temp;
					i = 2*i+1;
					continue;
				}
				//左节点最大,将其进行互换
				else
				{
					temp = p->heap[i];
					p->heap[i] = p->heap[2*i];
					p->heap[2*i] = temp;
					i = 2*i;
					continue;
				}
			}
			//左节点 > 该节点 > 右节点
			else if((p->heap[i] < p->heap[2*i])&&(p->heap[i] > p->heap[2*i + 1]))
			{
				temp = p->heap[i];
				p->heap[i] = p->heap[2*i];
				p->heap[2*i] = temp;
				i = 2*i;
				continue;
			}
			//右节点 > 该节点 > 左节点
			else if((p->heap[i] > p->heap[2*i])&&(p->heap[i] < p->heap[2*i + 1]))
			{
				temp = p->heap[i];
				p->heap[i] = p->heap[2*i+1];
				p->heap[2*i+1] = temp;
				i = 2*i+1;
				continue;
			}
			//左右节点都小于该节点,下滤操作结束
			else
				break;
		}
		//只有一个左节点
		else
		{
			//左节点 > 该节点
			if((p->heap[i] < p->heap[2*i]))
			{
				temp = p->heap[i];
				p->heap[i] = p->heap[2*i];
				p->heap[2*i] = temp;
				i = 2*i;
			}
			break;
		}
	}
	return 0;
}

void print_Binary_Heap(struct BH_Node *p)
{
	int i;
	if(NULL == p)
	{
		printf("Error: H == NULL\n");
		return;
	}
	for(i=1;i<=p->capacity;i++)
	{
		printf("%d ",p->heap[i]);
	}
	printf("\n");
}

int main(void)
{
	int c;
	int i;
	int res;
	struct BH_Node *h;
	h = init_Binary_Heap(10);
	printf("please input 10 number: \n");
	for(i=0;i<10;i++)
	{
		scanf("%d",&c);
		res = insert_Binary_Heap(c,h);
		if(res < 0)
			break;
	}
	for(i=1;i<10;i++)
		delete_max_Binary_Heap(h);
	printf("---------------after heap sort----------- \n");
	print_Binary_Heap(h);
	return 0;
}

程序运行结果如下:


猜你喜欢

转载自blog.csdn.net/yxw0609131056/article/details/79497045