初级数据结构——树

目录

前言

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

一、树的基本概念

定义:树是一种非线性的数据结构,由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+树等,以满足不同的应用需求。

结语

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

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

相关推荐
BD_Marathon1 天前
SpringBoot程序快速启动
java·spring boot·后端
stillaliveQEJ1 天前
【JavaEE】Spring IoC(二)
java·开发语言·spring
寻星探路1 天前
【Python 全栈测开之路】Python 基础语法精讲(一):常量、变量与运算符
java·开发语言·c++·python·http·ai·c#
stevenzqzq1 天前
Android Studio 断点调试核心技巧总结
android·ide·android studio
ohoy1 天前
RedisTemplate 使用之List
数据结构·windows·list
行百里er1 天前
代码跑得慢?让Spring的StopWatch告诉你真相!
java·后端·github
又是忙碌的一天1 天前
SpringMVC响应
java·服务器·数据库
万物皆字节1 天前
Spring Cloud Gateway 启动流程源码分析
java·开发语言·spring boot
W001hhh1 天前
260110
java·数据库
stillaliveQEJ1 天前
【JavaEE】Spring IoC(一)
java·spring·java-ee