我是靠谱客的博主 可靠猫咪,最近开发中收集的这篇文章主要介绍二叉树[完全二叉树堆的实现],觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

二叉树

    • 二叉树的概念
    • 二叉树的特点
    • 特殊二叉树
    • 二叉树的性质
    • 完全二叉树的顺序结构及实现
    • 堆的实现

二叉树的概念

一颗二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上左子树和柚子树的二叉树组成

二叉树的特点

1、每个结点最多有俩个子树,每个结点的度不超过2
2、二叉树子树有左右之分,并且次序不能颠倒

特殊二叉树

1、满二叉树:一个二叉树,如果每一个层的结点都到达最大值时为满二叉树。也就是说如果一个二叉树的深度为K,则满二叉树的结点为(2^k)-1。
2、完全二叉树:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
完全二叉树:
完全二叉树
满二叉树:
在这里插入图片描述

二叉树的性质

1、如果规定根节点的层数为1,则二叉树每一层的节点个数为2^(i-1),i代表层数。
2、如果规定根节点的层数为1,则二叉树的最大结点个数为2^h-1。
3、对于任何一个二叉树,度为0的结点个数为n0,度为2的结点个数为n2,则有n0 = n2+1。
4、如果规定根节点的层数为1,结点个数为n的满二叉树的深度为log2(n+1).
5、对于具有n个结点的完全二叉树,结点按照从上向下从左向右的顺序进行从0开始编号。则对于序号为i的结点(i>0),则它的父亲结点为(i-1)/2;左孩子结点为2i+1;右孩子结点为2i+2;且左右孩子下标必须小于n。

完全二叉树的顺序结构及实现

1、堆的概念及结构
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储
在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为
小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
2、堆的性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
在这里插入图片描述

##堆的向下调整算法
向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
在这里插入图片描述
思路:
在这里插入图片描述
代码:

#include <stdio.h>

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;

}
void AdjustDown(int* a, int i, int n)
{
	//找出左右孩子最小的哪一个
	int parent = i;
	int child = 2 * parent + 1;
	//一直比到孩子超出数组最大值结束
	while (child < n)
	{
		if (child + 1 < n && a[child] > a[child + 1])
		{
			child = child + 1;
		}
		//如果父亲比孩子大
		if (a[parent] > a[child])
		{
			//交换父亲孩子
			swap(&a[parent], &a[child]);
			parent = child;
			child = 2 * parent + 1;
		}
		//如果父亲比孩子都小,停止交换
		else
		{
			break;
		}
	}
}
void ptintarr(int* a, int size)
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", a[i]);
	}
	printf("n");
}
int main()
{
	int array[] = { 27,15,19,18,28,34,65,49,25,37};
	//求出数组的大小
	int size = sizeof(array) / sizeof(array[0]);
	AdjustDown(array, 0, size);
	ptintarr(array, size);
	return 0;
}

堆的实现

上面我们说的堆的向下调整算法,只适合根节点的左右子树都是一个堆的情况下。如果左右子树不是一个堆呢?
思路:
在这里插入图片描述
代码:

#include <stdio.h>

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;

}
void AdjustDown(int* a, int i, int n)
{
	//找出左右孩子最小的哪一个
	int parent = i;
	int child = 2 * parent + 1;
	//一直比到孩子超出数组最大值结束
	while (child < n)
	{
		if (child + 1 < n && a[child] > a[child + 1])
		{
			child = child + 1;
		}
		//如果父亲比孩子大
		if (a[parent] > a[child])
		{
			//交换父亲孩子
			swap(&a[parent], &a[child]);
			parent = child;
			child = 2 * parent + 1;
		}
		//如果父亲比孩子都小,停止交换
		else
		{
			break;
		}
	}
}
void ptintarr(int* a, int size)
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", a[i]);
	}
	printf("n");
}
int main()
{
	//int array[] = { 27,15,19,18,28,34,65,49,25,37};
	求出数组的大小
	//int size = sizeof(array) / sizeof(array[0]);
	//AdjustDown(array, 0, size);
	//ptintarr(array, size);
	//return 0;
	int array[] = {1,8,3,5,7,6};
	int size = sizeof(array) / sizeof(array[0]);
	//找出最后一个叶子
	int end = size - 1;
	//找出它的父亲
	int parent = (end - 1) / 2;
	while (parent >= 0)
	{
		AdjustDown(array, parent, size);
		parent--;
	}
	ptintarr(array, size);
}

最后

以上就是可靠猫咪为你收集整理的二叉树[完全二叉树堆的实现]的全部内容,希望文章能够帮你解决二叉树[完全二叉树堆的实现]所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部