首页 > 其他分享 >【数据结构】二叉树链式结构的实现

【数据结构】二叉树链式结构的实现

时间:2024-11-01 20:19:04浏览次数:5  
标签:结点 遍历 return BTNode 二叉树 链式 数据结构 root

1.前置说明

       在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二 叉树结构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树 操作学习,等二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。

代码如下:

typedef int BTDataType;
typedef struct BinaryTreeNode
{
 BTDataType _data;
 struct BinaryTreeNode* _left;
 struct BinaryTreeNode* _right;
}BTNode;
 
BTNode* CreatBinaryTree()
{
 BTNode* node1 = BuyNode(1);
 BTNode* node2 = BuyNode(2);
 BTNode* node3 = BuyNode(3);
 BTNode* node4 = BuyNode(4);
 BTNode* node5 = BuyNode(5);
 BTNode* node6 = BuyNode(6);
 
 node1->_left = node2;
 node1->_right = node4;
 node2->_left = node3;
 node4->_left = node5;
 node4->_right = node6;

 return  node1;
}

 二叉树是:

1. 空树

2. 非空:根结点,根结点的左子树、根结点的右子树组成的。

从概念中可以看出,二叉树定义是递归式的,因此后序基本操作中基本都是按照该概念实现的。 

2.二叉树的遍历

前序、中序以及后序遍历 

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉 树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历 是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

 这里我们通常将二叉树分为三个部分  左子树 右子树

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中间。

3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为 根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

前序遍历递归图解:

使用递归 相当于函数栈帧不断创建 最后一个一个销毁 

 

前序遍历结果:1 2 3 4 5 6

中序遍历结果:3 2 1 5 4 6

后序遍历结果:3 2 5 6 4 1 

这里为了方便理解 以前序为例 : 我们按照 根 左子树 右子树 这样理解 , 第一个根为 1,打印1,往左子树走,遇到第二个根为 2,打印2,继续往左子树走,遇到第三个根为 3,打印3,继续往左子树走 ,此时为空 ,为空此时往回走,3 的右子树也为空,在往回走,2的右子树为空,继续往回走,此时遍历1的右子树 ,以同样的方法继续遍历。

 代码实现

使用递归实现,重在理解递归函数栈帧的创建与销毁 

void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	InOrder(root->left);
	InOrder(root->right);
    printf("%d ", root->data);
}

3.二叉树结点个数

int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

4.二叉树叶子结点个数

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;

	if (root->left == NULL && root->right == NULL)
		return 1;

	return TreeLeafSize(root->left)
		+ TreeLeafSize(root->right);
}

5.二叉树的高度

int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;

	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return leftHeight > rightHeight ?
		leftHeight + 1 : rightHeight + 1;
}

6.二叉树第k层结点个数

int TreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;

	// 子问题
	return TreeLevelKSize(root->left, k - 1)
		+ TreeLevelKSize(root->right, k - 1);
}

7.二叉树查找值为x的结点

BTNode* TreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;

	if (root->data == x)
		return root;

	BTNode* ret1 = TreeFind(root->left, x);
	if (ret1)
		return ret1;

	BTNode* ret2 = TreeFind(root->right, x);
	if (ret2)
		return ret2;

	return NULL;
}

   初学者使用递归实现二叉树功能时,多画图理解可以解决大部分问题,二叉树的问题大部分情况要记得考虑空树的状况。

标签:结点,遍历,return,BTNode,二叉树,链式,数据结构,root
From: https://blog.csdn.net/2303_77156410/article/details/143416202

相关文章

  • JAVA 二叉树面试题
    @目录摘要代码Node节点main函数问题1:递归——求二叉树的最大深度问题2:求二叉树的最小深度问题3:求二叉树中节点的个数问题4:求二叉树中叶子节点的个数问题5:求二叉树中第k层节点的个数,不是求第k层叶子节点个数问题6:判断两棵树是否相同问题7:给定一个二叉树,检查它是否是镜像对称的。问......
  • 数据结构与算法(二叉树)
    鲸饮未吞海,剑气已横秋。 前言  这是我学习数据结构的第五份笔记,有关二叉树的知识。后期我会继续将数据结构知识的笔记补全。 上一期笔记有栈与列队,没看过的同学可以去看看:有关栈与列队的笔记https://blog.csdn.net/hsy1603914691/article/details/143064674?spm=10......
  • C语言数据结构之二叉树(BINARY TREE)链式存贮的简单实现
    C语言数据结构之二叉树(BINARYTREE)链式存贮的简单实现树型数据结构在应用中非常多,效率也非常好,只是结构相对复杂,理解起来有点儿难度!!!定义数据结构typedefstruct_BTreeNodeBTreeNode;struct_BTreeNode{intval;BTreeNode*lchild,*rchild;};自定义结构体数......
  • C语言数据结构之哈希表(HASHTABLE)的实现
    C语言数据结构之哈希表(HASHTABLE)的实现哈希表的每个节点保存的数据格式为key:value,其中key为字符串,根据字符串内容采用不同方法(哈希函数)生成一个无符号整型哈希码,根据表的长度,采用取余法,将数据存入表单元,如果此表单元中已存在数据,则以此表单元为链表头,向链表追加数据,这......
  • C++ 手撕--基本数据结构的简单实现
    C++面试手撕代码----基本数据结构的简单实现1.String数据结构的简单实现:#include<iostream>#include<cstring>//forstrcpystrlenmethodsusingnamespacestd;classString{private: char*data; size_tlength;public: String():data(nullptr),length(0)......
  • 数据结构杂题乱记
    由于是杂题乱记所以题目大多数不会太难。目录P2572[SCOI2010]序列操作题目内容思路代码P2572[SCOI2010]序列操作题目内容给你一个\(01\)序列,支持\(5\)种操作:0lr区间赋值为\(0\);1lr区间赋值为\(1\);2lr区间取反,即\(0\)变\(1\)、\(1\)变\(0\);3lr询......
  • 链表(数据结构)
    一.单链表1.1概念与结构再上一篇中我们讲到顺序表,但是顺序表也是有很多的问题,像申请的空间过多过少或者增容该才能不浪费空间,今天我们就来认识一个新的知识,叫做链表,链表也是线性表的一种,链表是一种物理存储结构上非连续、非顺序的存储结构,数据结构的逻辑顺序是通过链表中的......
  • Python常用数据结构
    1.列表(List)列表是Python中最灵活的数据结构之一,像个能装万物的大箱子。你可以把任何类型的对象放进来,甚至可以把列表放进列表里,真是个魔法箱!功能特性:可变:你可以随时增加、删除、修改列表中的元素。有序:元素按插入顺序排列创建和基本操作:#创建一个空列表my_list=[]......
  • 二叉树专题学习
    前言:由于二叉树这一章的题型比较多,涉及到的递归程序也较多,所以单开一个随笔来记录这个学习过程,希望对读者有帮助。理论知识基础在二叉树的选择题中,常常会涉及到对于最多或最少结点、最大或最小高度、求叶子结点个数这几类经典的问题。上机题1.二叉树的建立和遍历P1305新二......
  • 108-二叉树-将有序数组转换为二叉搜索树
    树|二叉搜索树|数组|分治|二叉树二叉搜索树(BinarySearchTree,简称BST)和平衡二叉搜索树(BalancedBinarySearchTree)是计算机科学中非常重要的数据结构,广泛应用于各种算法和系统中。理解它们的定义、特点和性质对于掌握数据结构和算法至关重要。下面,我们将详细......