欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

最大堆实现

程序员文章站 2024-01-16 23:09:10
...

1、基本概念

堆分为小根堆和大根堆,对于一个小根堆,它是具有如下特性的一棵完全二叉树:

(1)若树根结点存在左孩子或右孩子,则根结点的值(或某个域的值)小于等于左右孩子结点的值(或某个域的值)

(2)以左、右孩子为根的子树又各是一个堆。

大根堆的定义将上面的小于等于改成大于等于即可。

根据根的定义,小根堆的堆顶结点具有最小值,大根堆的堆顶结点具有最大值。

2、堆的存储结构

由于堆是一棵完全二叉树,所以适宜采用顺序存储结构,这样能够充分利用存储空间。

顺序存储结构:

对堆中所有结点进行编号,作为下标存储到指定数组的对应元素中,下标从0开始。按照从上到下,同一层从左到右进行。

设堆中有n个结点,则编号为 0 ~ n-1,则有如下性质:

(1)编号为 0 至 [n/2-1] 的结点为分支结点, 编号为 [n/2] 至 n-1 的结点为叶子结点;

(2)当 n 为奇数则每个分支结点既有左孩子又有右孩子,当 n 为偶数则每个分支结点只有左孩子没有右孩子

(3)对于每个编号为 i 的分支结点,其左孩子结点的编号为 2i+1,右孩子结点的编号为 2i+2

(4)除编号为0的堆顶结点外,对于其余编号为 i 的结点,其双亲结点的编号为 [(i-1)/2]

最大堆实现

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

typedef struct Heap
{
	int *key;
	int len;
	int MaxSize;
}Heap_Node;

int Heap_Init(Heap_Node *Node,int len, int MaxSize)
{
	if (len < 0 || MaxSize < 0)
	{
		printf("error");
		return 1;
	}
	Node->key = (int *)malloc(sizeof(int)*MaxSize);
	Node->len = len;
	Node->MaxSize = MaxSize;
	return 0;
}

int Heap_Clear(Heap_Node *Node)
{
    free(Node->key);
	Node->len = 0;
	Node->MaxSize = 0;
	return 0;
}

int Heap_Insert(Heap_Node *Node,int key)                     //最大堆的插入原理:
{															 //将要插入的元素插入到尾部,然后与其双亲结点比较,如果大于双亲结点,则上移
	if (Node == NULL || key == NULL)						 //直至小于双亲结点或者到达头结点为止
	{
		return 1;
	}
	else if (Node->len == 0)
	{
		Node->key[0] = key;
		Node->len++;
		return 0;
	}
	else
	{
		if (Node->len > Node->MaxSize)
		{
			printf("This Heap have already full");
			return 1;
		}
		Node->key[Node->len] = key;  //队尾插入元素
		int j = Node->len;  //插入结点位置
		Node->len++;        //长度加一
		int parent = (j - 1) / 2;  //双亲结点
		
		while (j != 0)
		{
			if (Node->key[parent]< key)
			{
				Node->key[j] = Node->key[parent];
				j = parent;
				parent = (j - 1) / 2;
			}
			else
			{
				break;
			}
		}
		Node->key[j] = key;
		return 0;
	}
}

int Heap_Delete(Heap_Node *Node)                  //最大堆的删除操作原理:
{												  //将首元素删除,然后将尾元素插入到删除首元素的位置,然后与左右子节点中!最大的进行比较!
	int x = Node->key[0];						  //如果其小于子节点,则将其调换位置,直至到达叶子结点
	int lchild, rchild;
	int temp = Node->key[Node->len];
	Node->len--;
	Node->key[0] = temp;
	int t = 0;       //标记要换位置的结点位置                    
	lchild = t * 2;  //其左孩子
	rchild = t * 2 + 1;  //其右孩子
	while (lchild <= Node->len-1 )
	{
		if (Node->key[lchild]>Node->key[rchild] && Node->key[lchild] > temp)
		{
			int m = Node->key[lchild];
			Node->key[lchild] = temp;
			Node->key[t] = m;
			t = lchild;
			lchild = t * 2;
			rchild = t * 2 + 1;
		}
		else if (Node->key[rchild] > Node->key[lchild] && Node->key[rchild] > temp)
		{
			int m = Node->key[rchild];
			Node->key[rchild] = temp;
			Node->key[t] = m;
			t = rchild;
			lchild = t * 2;
			rchild = t * 2 + 1;
		}
		else
		{
			break;
		}
	}
	return x;
}

int Heap_Len(Heap_Node *Node)
{
	return Node->len;
}

int Heap_MaxSize(Heap_Node *Node)
{
	return Node->MaxSize;
}

int main()
{
	int len = 0, MaxSize = 10;
	int t=6;   //要插入的数的个数
	Heap_Node Node;
	int key[8] = { 10,16,23,38,40,55,56,62 };
	Heap_Init(&Node,len,MaxSize);
	Heap_Insert(&Node, key[0]);
	Heap_Insert(&Node, key[1]);
	Heap_Insert(&Node, key[2]);
	Heap_Insert(&Node, key[3]);
	Heap_Insert(&Node, key[4]);
	Heap_Insert(&Node, key[5]);
	Heap_Insert(&Node, key[6]);
	Heap_Insert(&Node, key[7]);
	
	for (int i = 0; i < 8; i++)
	{
		
		int key = Heap_Delete(&Node);
		//printf("key=%d\n", Node.key[i]);
		printf("%d\n", key);
	}
	//Heap_Clear(&Node);
	

	system("pause");
	return 0;
}
相关标签: c 数据结构