【数据结构】树与二叉树(中)

这篇具有很好参考价值的文章主要介绍了【数据结构】树与二叉树(中)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

一、顺序存储结构:

二、堆:

1.堆的性质:

2.堆的性质:

3.堆的实现:

Ⅰ.堆的初始化:

 Ⅱ.堆的插入(含向上调整):

 Ⅲ.堆的删除(含向下调整算法):

Ⅳ.取堆顶的数据:

Ⅴ.堆中的数据个数:

Ⅵ.堆的判空:

 Ⅶ.堆的销毁:

总结:


前言:

        上篇文章中,我们认识了树与二叉树相关概念以及两种常见的存储结构,而今天我们将对顺序存储结构进行实现的讲解。

一、顺序存储结构:

        普通的二叉树是是不适合用数组来存储的,因为可能会存在大量的空间浪费,但是完全二叉树不会存在此问题,所以更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来进行存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆完全没有关系。今天我们关于顺序存储结构的讲解,就以堆的形式进行。

二、堆:

1.堆的性质:

        堆分为小根堆和大根堆,根节点始终小于子节点称为小根堆,相反根节点大于子节点则称为大根堆。换句话说,根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

2.堆的性质:

①.堆中的某个节点的值总是小于或不小于其父节点的值。

②.堆总是一颗完全二叉树

3.堆的实现:

        Heap.h:存放函数声明、包含其他头文件、定义宏。

        Heap.c:书写函数定义,书写函数实现。

        test.c:书写程序整体执行逻辑。

Ⅰ.堆的初始化:

首先判断传入指针是否为空,然后为其开辟空间,并对相应数据进行赋值。

void HeapInit(HP* p)
{
	assert(p);
	HPDataType* new = (HPDataType*)malloc(sizeof(HPDataType)*4);
	if (new == NULL)
	{
		perror("malloc fail");
		return;
	}
	p->a = new;
	p->size = 0;
	p->capacity = 4;
}

 Ⅱ.堆的插入(含向上调整):

        因为堆的存储在物理层面上是数组,但是在逻辑层面上是二叉树。并且由于只有大根堆和小根堆,所以在插入数据之后要保准仍然是堆,就需要进行适当的调整。插入时从尾部插入,,而是否为堆取决于子节点和父节点的关系,所以插入的数据要与其父节点进行比较,若为小根堆则子节点要比父节点要大,否则就需要交换子节点和父节点,大根堆则相反。这种调整方式就叫做向上调整。

执行操作前进行非空判断,防止对空指针进行操作;

插入前判断空间是否足够,若不足则进行扩容;

插入后为了保证数组仍然为堆,所以需要在插入后进行向上调整。

//向上调整
void Adujustup(HPDataType* a, int child)
{
    assert(a);
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
//堆插入
void HeapPush(HP* p, HPDataType x)
{
	assert(p);

	if (p->size == p->capacity)
	{
		HPDataType* new = (HPDataType*)realloc(p->a,sizeof(HPDataType) * p->capacity*2);
		if (new == NULL)
		{
			perror("realloc fail");
			return;
		}
	}
	
		p->a[p->size] = x;
		p->size++;

	Adujustup(p->a, p->size - 1);

}

 Ⅲ.堆的删除(含向下调整算法):

        堆删除的实质时删除堆顶元素,但是如果我们直接删除堆顶元素,就会破坏堆的结构,所以这种方法不可取;于是我们这里采用将堆顶的数据于最后一个数据交换,再删除最后一个数据的方法,这样就实现了堆顶数据的删除。接着我们再调整以下堆顶数据的位置就可以了。

        而在这里我们就需要向下调整,所以我们选择的调整方法就是:将根节点与它的孩子中的较小的值交换,然后再将交换后的节点作为父节点继续与他的子节点交换,直到该节点小于他的子节点,或者成为叶节点。要注意的是,使用这个方法有一个前提:根节点的两个子树也得是堆才行。

执行操作前进行非空判断,防止对空指针进行操作;

删除过程同样与队列近乎一致,不同点是在删除过后为了保证删除堆顶数据后仍为堆,于是需要使用向下调整对删除后的对进行调整。

//向下调整
void Adujustdown(HPDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;
	
	while (child < size-1)
	{
		if (a[child] < a[child + 1])
		{
			child++;
		}
		if (a[parent] < a[child])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
		
	}


}
//堆删除
void HeapPop(HP* p)
{
	assert(p);
	if (p->size == 0)
	{
		return;
	}
	Swap(&p->a[0], &p->a[p->size - 1]);
	p->size--;
	Adujustdown(p->a, p->size, 0);

}

Ⅳ.取堆顶的数据:

HPDataType HeapTop(HP* p)
{
	assert(p);
	return p->a[0];
}

Ⅴ.堆中的数据个数:

int HeapSize(HP* p)
{
	assert(p);
	return p->size;
}

Ⅵ.堆的判空:

bool HeapEmpty(HP* p)
{
	assert(p);
	return p->size == 0;
}

 Ⅶ.堆的销毁:

void HeapDestroy(HP* p)
{
	assert(p);
	free(p->a);
	p->a = NULL;
	p->capacity = 0;
	p->size = 0;
}

总结:

        这篇文章我们完整的认识、了解、学习了二叉树顺序存储结构的相关知识,并且对二叉树顺序存储进行实现——堆的各接口实现。至此,关于二叉树的顺序存储的知识我们就全部学习完毕了。 文章来源地址https://www.toymoban.com/news/detail-564310.html

到了这里,关于【数据结构】树与二叉树(中)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [数据结构] 树与二叉树

    树是由 (n(n geq 0)) 个节点组成的有限集。当 (n = 0) 时,称为空树。 任意一棵非空树应满足以下两点: (1)有且仅有一个特定的称为根的节点; (2)当 (n 1) 时,其余节点可分为 (m(m0)) 个互不相交的有限集 (T_1, T_2, dots, T_m) ,其中每个集合本身又是一棵树,称为根的

    2024年03月09日
    浏览(31)
  • 数据结构--树与二叉树

    树的定义 树是n(n =0)个节点的有限集。当n=0 时,称为空树 在任意一棵非空树中应满足 有且仅有一个特定的称为根的结点 当n1 时,其余节点可分为m(m0) 个互不相交的有限集T1,T2……Tm,其中每个集合本身又是一棵树,并且称为根的子树 树是一种逻辑结构,也是一种分层结构 树的

    2024年02月22日
    浏览(32)
  • 【数据结构】树与二叉树

    树是一种 非线性的数据结构 ,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。它具有以下的特点: 有一个特殊的结点,称为根结点,根结点没有前驱结点 除根结点外,其余结点被分

    2024年02月11日
    浏览(32)
  • 数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

    目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历  后序遍历  树是一种 非线性数据结构 ,它由节点和边组成。树的每个节点可以有零个或多个子节点,其中一个节点被指定为

    2024年02月04日
    浏览(39)
  • 数据结构_树与二叉树

    目录 1. 树的基本概念 1.1 树的定义 1.2 基本术语 1.3 树的性质 1.4 相关练习 2. 二叉树的概念 2.1 二叉树的概念及其主要特性 2.2 二叉树的存储结构 2.2.1 顺序存储结构 2.2.2 链式存储结构 2.3 相关练习 3. 二叉树的遍历和线索二叉树 3.1 二叉树的遍历 3.1.1 先序遍历 3.1.2 中序遍历 3.1

    2024年02月04日
    浏览(33)
  • 【数据结构】树与二叉树(中)

    目录 前言: 一、顺序存储结构: 二、堆: 1.堆的性质: 2.堆的性质: 3.堆的实现: Ⅰ.堆的初始化:  Ⅱ.堆的插入(含向上调整):  Ⅲ.堆的删除(含向下调整算法): Ⅳ.取堆顶的数据: Ⅴ.堆中的数据个数: Ⅵ.堆的判空:  Ⅶ.堆的销毁: 总结:         上篇文章中,

    2024年02月16日
    浏览(32)
  • 【数据结构】24王道考研笔记——树与二叉树

    树是n个结点的有限集合,n=0时,称为空树。非空树满足: 除了根节点外,任何一个结点都有且仅有一个前驱 结点的层次(深度):从上往下数 结点的高度:从下往上数 树的高度(深度):总共有多少层 结点的度:有几个孩子(分支) 树的度:各节点的度的最大值 森林:

    2024年02月13日
    浏览(38)
  • 数据结构--》解锁数据结构中树与二叉树的奥秘(一)

            数据结构中的树与二叉树,是在建立非线性数据结构方面极为重要的两个概念。它们不仅能够模拟出生活中各种实际问题的复杂关系,还常被用于实现搜索、排序、查找等算法,甚至成为一些大型软件和系统中的基础设施。         无论你是初学者还是进阶者

    2024年02月08日
    浏览(35)
  • 数据结构--》解锁数据结构中树与二叉树的奥秘(二)

            数据结构中的树与二叉树,是在建立非线性数据结构方面极为重要的两个概念。它们不仅能够模拟出生活中各种实际问题的复杂关系,还常被用于实现搜索、排序、查找等算法,甚至成为一些大型软件和系统中的基础设施。         无论你是初学者还是进阶者,

    2024年02月08日
    浏览(34)
  • 【数据结构】树与森林(树的存储结构、森林与二叉树的转化、树与森林的遍历)

    树与二叉树知识点文章: 【数据结构】树与二叉树(递归法先序、中序、后序、层次遍历二叉树、二叉树的建立以及求树高的方法) 二叉树遍历算法的应用: 【数据结构】树与二叉树遍历算法的应用(求叶子节点个数、求树高、复制二叉树、创建二叉树、二叉树存放表达式、

    2024年04月13日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包