手撕数据结构与算法——树(三指针描述一棵树)

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

为什么有的树要三个指针,# 数据结构,数据结构,链表,c++

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段,因为最近参加新星计划算法赛道(白佬),所以加快了脚步,果然急迫感会增加动力>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的
📖作者主页:king&南星
📖专栏链接:数据结构

🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾

为什么有的树要三个指针,# 数据结构,数据结构,链表,c++

🌱树

一、🌲概念与定义

描述树结构:

  1. 和现实世界的树 反着画
  2. 根节点 枝干 叶子节点
  3. 同一层 兄弟 上层:父 叔叔 上层的上层:爷爷
    下层:孩子 侄儿
  4. 树的高度:几代人
  5. 树退化成线性结构 : 一叉树(链表) N代单传
    图解:
    现实中的树

为什么有的树要三个指针,# 数据结构,数据结构,链表,c++
数据结构中的树是和现实倒着的

为什么有的树要三个指针,# 数据结构,数据结构,链表,c++
为什么有的树要三个指针,# 数据结构,数据结构,链表,c++
详细解读:三个指针描述,一个指针指向父亲,一个指针指向兄弟,一个指针指向孩子,同时规则设定只有父亲的第一个孩子才可以有孩子

二、🌳定义与预备

先准备好头文件、结构体和函数声明

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef struct treeNode
{
	int data;                  //数据
	struct treeNode* pParent;  //指向父
	struct treeNode* pBrother; //指向第一个兄弟
	struct treeNode* pChild;   //指向第一个孩子
}treeNode;

#define SIZE sizeof(treeNode)

//创建节点函数
treeNode* createNode(int data);

//在树中找一个节点,找到返回这个节点的地址,找不到返回NULL
treeNode* findNode( treeNode* root, int findData);

//插入一个节点到树中
//把insertData插入到*pRoot树中 如果isChild为真成为findData节点的孩子,否则成为findData节点的兄弟
bool intsertNode( treeNode** pRoot, int findData, int insertData, bool isChild);

//遍历
void print_Tree(treeNode* root);

三、🌴创建结点函数

这里利用一个技巧,直接使用内存设置函数memset函数,把三个指针内存都设置为0

treeNode* createNode( int data )
{
	treeNode* newNode = (treeNode*)malloc(SIZE);
	assert(newNode);
	memset(newNode, 0, SIZE);		//内存都设置为0
	newNode->data = data;
	return newNode;
}

四、🍀查找

在树中找一个节点,找到返回这个节点的地址,找不到返回NULL
先在while循环中遍历同一层的兄弟,直到他下一个兄弟为空,切换到下一层,如此循环下去,如果找到则返回地址,如果没找到则返回空

treeNode* findNode(treeNode* root, int findData) 
{
	if (NULL == root) return NULL;  //防呆
	treeNode* pTemp;
	treeNode* pnextChild = root;
	while (true)
	{
		pTemp = pnextChild;
		if (NULL == pnextChild) break;
		while( true )
		{
			//遍历兄弟层
			if (NULL == pTemp) break;
			if (findData == pTemp->data) return pTemp;
			pTemp = pTemp->pBrother;
		}
		//切换到下一层(孩子)
		pnextChild = pnextChild->pChild;
	}
	return NULL;
}

五、🍁插入

描述:插入一个节点到树中,把insertData插入到*pRoot树中 如果isChild为真成为findData节点的孩子,否则成为findData节点的兄弟
为什么有的树要三个指针,# 数据结构,数据结构,链表,c++

bool intsertNode(treeNode** pRoot, int findData, int insertData, bool isChild)
{
	if (NULL == pRoot) return false; //防呆
	if (NULL == *pRoot) //空树
	{
		*pRoot = createNode(insertData);
		return true;
	}
	treeNode* pFind = findNode(*pRoot, findData);  //查找
	if (NULL == pFind) return false;
	treeNode* pNew, * pTemp;
	//找到了
	if (isChild) //新节点成为pFind指向节点的孩子
	{
		//有孩子,新节点成为pFind节点孩子的最小兄弟
		if (pFind->pChild)
		{
			pTemp = pFind->pChild;
			pNew = createNode(insertData);
			while (pTemp->pBrother) pTemp = pTemp->pBrother;
			pTemp->pBrother = pNew;
			pNew->pParent = pFind;
			return true;
		}
		//pFind指向的节点没有孩子
		else
		{
			//有父,pFind不是根节点
			if (pFind->pParent)
			{
				//pFind是pFind->pPartent的第一个孩子
				if (pFind->pParent->pChild == pFind)
				{
					pNew = createNode(insertData);
					pFind->pChild = pNew;
					pNew->pParent = pFind;
					return true;
				}
				else
				{
					//pFind不是pFind->pParent的第一个孩子
					//新节点只能成为 pFind->pParent->pChild的孩子
					intsertNode(&(pFind->pParent), pFind->pParent->pChild->data, insertData, true);
				}
			}
			//无父,pFind是根节点
			else
			{
				pNew = createNode(insertData);
				pFind->pChild = pNew;
				pNew->pParent = pFind;
				return true;
			}
		}
	}
	else //新节点成为pFind指向节点的兄弟
	{
		pTemp = pFind;
		while (pTemp->pBrother) pTemp = pTemp->pBrother;
		pNew = createNode(insertData);
		pTemp->pBrother = pNew;
		pNew->pParent = pFind->pParent;
		return true;
	}
	return false;
}

六、🍃遍历

和查找函数异曲同工文章来源地址https://www.toymoban.com/news/detail-796521.html

void print_Tree(treeNode* root) 
{
	if (NULL == root) return NULL;  //防呆
	treeNode* pTemp;
	treeNode* pnextChild = root;
	int cnt = 1;
	while (true)
	{
		pTemp = pnextChild;
		if (NULL == pnextChild) break;
		printf("第[%d]层:", cnt++);
		while (true)
		{
			//遍历兄弟层
			if (NULL == pTemp) break;
			printf("%d ", pTemp->data);
			pTemp = pTemp->pBrother;
		}
		printf("\n");
		//切换到下一层(孩子)
		pnextChild = pnextChild->pChild;
	}
}

到了这里,关于手撕数据结构与算法——树(三指针描述一棵树)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • [ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

    手撕排序算法系列之:冒泡排序。 从本篇文章开始,我会介绍并分析常见的几种排序,大致包括 插入排序 , 冒泡排序 ,希尔排序,选择排序,堆排序,快速排序,归并排序等。 大家可以点击此链接阅读其他排序算法:排序算法_大合集(data-structure_Sort) 本篇主要来手撕冒

    2024年02月11日
    浏览(59)
  • 【C++图解专栏】手撕数据结构与算法,探寻算法的魅力

    ✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343 📣专栏定位:为 0 基础刚入门数据结构与算法的小伙伴提供详细的讲解,也欢迎大佬们一起交流~ 📚专栏简介:在这个专栏,我将带着大家一起用 C++ 手撕基础的数据结构与算法,每一讲都有详细的讲解,29 篇文章共

    2024年02月09日
    浏览(59)
  • 【数据结构与算法篇】手撕排序算法之插入排序与希尔排序

    ​👻内容专栏:《数据结构与算法篇》 🐨本文概括: 讲述排序的概念、直接插入排序、希尔排序、插入排序和希尔排序的区别。 🐼本文作者:花 碟 🐸发布时间:2023.6.13 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的

    2024年02月09日
    浏览(51)
  • [数据结构 -- 手撕排序算法第七篇] 递归实现归并排序

    目录 1、归并的思想 2、归并排序的思想 2.1 基本思想 2.2 图解分析 3、归并排序递归版本代码实现 3.1 代码解析 3.2 注意事项 3.2.1错误划分:[begin, mid-1],[mid, end] 3.2.2 正确划分:[begin, mid], [mid+1, end] 4、归并排序的测试 5、时间复杂度、空间复杂度分析 5.1 时间复杂度 5.2 空间复杂

    2024年02月16日
    浏览(49)
  • 【夜深人静学数据结构与算法 | 第四篇】手撕二叉树遍历

    目录 前言: 二叉树遍历方式: 手撕前中后序遍历(递归)的三大准备 深度优先搜索:  手撕前中后遍历(递归): 手撕前中后序遍历(迭代): 深度优先搜索: 总结:         今天我们将带领大家手撕二叉树的遍历,本篇会分别讲解深度优先搜索法和广度优先有搜索法下

    2024年02月09日
    浏览(50)
  • 《数据结构、算法与应用C++语言描述》-列车车厢重排问题

    完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_10Train_carriages_rearrangement/ 一列货运列车有 n 节车厢,每节车厢要停靠在不同的车站。假设 n个车站从 1 到n 编号,而且货运列车按照从n到1的顺序经过车站。车厢的编号与它们要停靠的车站编号相同。为了便于从

    2024年04月10日
    浏览(67)
  • 数据结构:定长顺序串(SString)基本操作的算法描述(C语言)

    作者在学习数据结构时,发现鲜有完全按照 C 语言描述的算法操作,这让习惯于写 .c 而不是 .cpp 的初学者很是头疼。本文将基于 C 语言描述算法操作,如有错漏还望大佬们指正。 本文将按照严惠敏所著《数据结构(C语言版)》所做的函数原型声明进行算法描述,由于C语言不支

    2024年02月07日
    浏览(72)
  • 【数据结构与算法篇】手撕八大排序算法之快排的非递归实现及递归版本优化(三路划分)

    ​👻内容专栏: 《数据结构与算法篇》 🐨本文概括: 利用数据结构栈(Stack)来模拟递归,实现快排的非递归版本;递归版本测试OJ题时,有大量重复元素样例不能通过,导致性能下降,优化快速排序通过将数组划分为三个区域,可以更有效地处理重复元素。 🐼本文作者:

    2024年02月11日
    浏览(83)
  • 【数据结构与算法】之多指针算法经典问题

    本文为 【数据结构与算法】多指针算法经典问题 相关介绍,下边将对 链表反转 (包含 迭代反转链表 、 递归反转 、 头插法反转 ), 双指针-快慢指针 (包含 寻找单向无环链表的中点 、 判断单向链表是否有环及找环入口 ), 双指针-左右指针 (包含 两数之和 、 二分查

    2024年02月03日
    浏览(66)
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。

    最短路径的算法有两个, Dijkstra算法 和 Floyd算法 。 Dijkstra算法 解决的是 单源 最短路径问题 。 Floyd算法解决的是 多源 最短路径问题,并且可以处理负权图 。 今天要讲的就是Dijkstra算法。 加: feng--Insist (大写的i),进java交流群讨论互联网+技术。可索要PPT等资料。 其他资料

    2024年02月11日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包