初级数据结构——树

目录

前言

从这一期开始数据结构开始有那么一点复杂了,这期我们一起来学习初级数据结构------树,树是数据结构中的一个重要概念,它用于表示具有层次关系的数据集合。

一、树的基本概念

定义:树是一种非线性的数据结构,由n(n>=0)个有限节点组成一个具有层次关系的集合。它看起来像一棵倒挂的树,根朝上,叶朝下。

特殊节点:
根节点 :树中唯一的特殊节点,没有前驱节点。
子节点 :根节点外的其余节点,被分成M(M>0)个互不相交的集合,每个集合又是一棵子树。
叶子节点 :度为0的节点,即没有子节点的节点。
分支节点 :度不为0的节点,即含有子节点的节点。
节点关系
双亲节点(父节点) :若一个节点含有子节点,则这个节点称为其子节点的父节点。
孩子节点(子节点) :一个节点含有的子树的根节点称为该节点的子节点。
兄弟节点 :具有相同父节点的节点互称为兄弟节点。
堂兄弟节点 :双亲在同一层的节点互为堂兄弟。
祖先节点 :从根到该节点所经分支上的所有节点。
子孙节点 :以某节点为根的子树中任一节点都称为该节点的子孙。
树的度 :树中节点的最大度,即节点的最大子树数。
树的层次 :从根开始定义起,根为第1层,根的子节点为第2层,以此类推。
树的高度(深度):树中节点的最大层次。

二、二叉树

定义:二叉树是节点的一个有限集合,该集合为空或由一个根节点加上两棵别称为左子树和右子树的二叉树组成。二叉树的子树有左右之分,次序不能颠倒。

特殊二叉树
满二叉树 :每一层上的节点数都是最大节点数,即每一层i的节点数都是2^i。
完全二叉树:叶子节点只能在层次最大的两层上出现,且对任一节点,若其右分支的子孙的最大层次为l,则其左分支的子孙的最大层次必是l或l+1。完全二叉树可以由满二叉树引伸出来,是效率很高的数据结构。

二叉树的性质:

在二叉树的第i层上至多有2^(i-1)个节点(i>=1)。

深度为k的二叉树至多有2^k-1个节点(k>=1)。

对于任何一颗二叉树,其叶子节点数为n0,度为2的节点数为n2,则n0=n2+1。

具有n个节点的完全二叉树的深度为log2n+1(向下取整,n>0)。

二叉树的存储结构:
顺序存储结构 :使用数组来存储,一般适合表示完全二叉树。对于非完全二叉树,可能会造成空间浪费。
链式存储结构:用链表来表示二叉树,链表中的每个节点由数据域和左右指针域组成,左右指针分别用来给出该节点左孩子和右孩子所在的链节点的存储地址。链式结构又分为二叉链和三叉链。

三、树的表示方法

树有多种表示方法,包括树形表示法、孩子兄弟表示法、文氏图表示法、凹形表示法、括号表示法等。其中,树形表示法是最常用的方法,每个节点指向若干孩子节点,以此类推。

四、树的遍历

树的遍历是指按照某种规则访问树中的每个节点,使得每个节点被访问且仅被访问一次。常见的遍历方法包括先根遍历、后根遍历和中序遍历(针对二叉树)。

先根遍历 :先遍历根节点再遍历它的子节点。
后根遍历 :先遍历子节点再遍历根节点。
中序遍历(针对二叉树):先访问左子树,再访问根,再访问右子树。

树的代码模版

cpp 复制代码
#include<iostream>
using namespace std;

template<typename T>
struct ListNode {
	T data;
	ListNode* next;
	ListNode(T x):data(x),next(NULL){}
};

template<typename T>
struct TreeNode {
	T data;
	ListNode<TreeNode<T>*>* childrenHead;//子节点指针
	TreeNode() {
		childrenHead = NULL;
	}
	void Addchild(TreeNode<T>* node) {//增加子节点的接口
		ListNode<TreeNode<T>*>* childNode = new ListNode<TreeNode<T>*>(node);
		if (childrenHead == NULL) childrenHead = childNode;
		else {
			childNode->next = childrenHead;
			childrenHead = childNode;
		}
	}
};

template<typename T>
class Tree {
private:
	TreeNode<T>* root;
	TreeNode<T>* nodes;
public:
	Tree();
	Tree(int maxNode);
	~Tree();
	TreeNode<T>* getTreeNode(int id);
	void setRoot(int rootId);
	void AddChild(int sonId, int parentId);
	void AssignData(int nodeId, T data);
	void Print(TreeNode<T>* node = NULL);
};

template<typename T>
Tree<T>::Tree() {
	nodes = new TreeNode<T>[100001];
}

template<typename T>
Tree<T>::Tree(int maxNodes) {
	nodes = new TreeNode<T>[maxNodes];
}

template<typename T>
Tree<T>::~Tree() {
	delete[]nodes;
}

template<typename T>
TreeNode<T>* Tree<T>::getTreeNode(int id) {
	return &nodes[id];
}

template<typename T>
void Tree<T>::setRoot(int rootId) {
	root = getTreeNode(rootId);
}

template<typename T>
void Tree<T>::AddChild(int parentId, int sonId) {
	TreeNode<T>* parentNode = getTreeNode(parentId);
	TreeNode<T>* sonNode = getTreeNode(sonId);
	parentNode->Addchild(sonNode);
}

template<typename T>
void Tree<T>::AssignData(int nodeId, T data) {
	getTreeNode(nodeId)->data = data;
}

template<typename T>
void Tree<T>::Print(TreeNode<T>* node) {
	if (node == NULL)node = root;
	cout << node->data;
	ListNode<TreeNode<T>*>* temp = node->childrenHead;
	while (temp) {
		Print(temp->data);
		temp = temp->next;
	}
}
int main() {
	Tree<char>t(9);
	t.setRoot(0);
	t.AssignData(0, 'a');
	t.AssignData(1, 'b');
	t.AssignData(2, 'c');
	t.AssignData(3, 'd');
	t.AssignData(4, 'e');
	t.AssignData(5, 'f');
	t.AssignData(6, 'g');
	t.AssignData(7, 'h');
	t.AssignData(8, 'i');

	t.AddChild(0, 2);
	t.AddChild(0, 1);
	t.AddChild(1, 3);
	t.AddChild(2, 5);
	t.AddChild(2, 4);
	t.AddChild(3, 8);
	t.AddChild(3, 7);
	t.AddChild(3, 6);

	t.Print();
	return 0;
}

五、经典例题

2236. 判断根结点是否等于子结点之和

(蓝色字体可以点进去看原题)

代码题解

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool checkTree(TreeNode* root) {
        return root->val==root->left->val+root->right->val;
    }
};

六、总结

综上所述,树是一种重要的数据结构,它用于表示具有层次关系的数据集合。在树的基础上,还可以构建出更复杂的树形结构,如二叉树、B树、B+树等,以满足不同的应用需求。

结语

下期我们将一起学习初级数据结构------二叉树,我们这期不见不散

想看更多内容可以关注我,看我作品,关注我让我们一起学习编程,希望大家能点赞关注支持一下,让我有持续更新的动力,谢谢大家

相关推荐
haoly19891 分钟前
数据结构和算法篇-线性查找优化-移至开头策略
数据结构·算法·移至开头策略
瓯雅爱分享6 分钟前
Java+Vue构建的采购招投标一体化管理系统,集成招标计划、投标审核、在线竞价、中标公示及合同跟踪功能,附完整源码,助力企业实现采购全流程自动化与规范化
java·mysql·vue·软件工程·源代码管理
mit6.8242 小时前
[C# starter-kit] 命令/查询职责分离CQRS | MediatR |
java·数据库·c#
咋吃都不胖lyh3 小时前
SQL-多对多关系
android·mysql·数据分析
诸神缄默不语3 小时前
Maven用户设置文件(settings.xml)配置指南
xml·java·maven
任子菲阳3 小时前
学Java第三十四天-----抽象类和抽象方法
java·开发语言
cyy2983 小时前
android 屏幕适配
android
学Linux的语莫3 小时前
机器学习数据处理
java·算法·机器学习
找不到、了3 小时前
JVM的即时编译JIT的介绍
java·jvm
earthzhang20214 小时前
【1007】计算(a+b)×c的值
c语言·开发语言·数据结构·算法·青少年编程