Trees and Forests (Come and see)

forest definition 

A forest is a collection of trees composed of multiple disjoint trees, that is, a forest contains multiple trees, and each tree has its own root node. A tree can also be seen as a forest.

Tree representation and basic operations 

1. Tree (general tree) representation method

1.1 Parent representation of tree

The parent representation of the tree is to store each node of the tree in an array, each node is uniquely corresponding to the subscript of the array, record the subscript of its parent node in each node, and the parent of the root node Node is -1.

(Leftmost child node: the leftmost child node among the child nodes of a node)

In practical applications, the parent representation of the tree can be simply represented by two arrays data and pa, but the number of nodes and the subscript of the root node need to be specified.

Note: Numbering must be strictly in order of level traversal in the parent notation of the tree.

#include<iostream>
using namespace std;
constexpr auto N = 30;
typedef char datatype;
struct paNode {
	int pa; //父结点的下标
	datatype data;
	paNode() :pa(-1) {};
};
typedef struct {
	paNode tree[N];
	int n;	//树中节点的数量
	int root;  //树的根结点下标
}paTree;

//双亲表示法的树的创建
paTree create_paTree(datatype data[N], int pa[N], int n) {
	paTree t;
	t.n = n;
	for (int i = 0; i < n; i++) {
		t.tree[i].pa = pa[i], t.tree[i].data = data[i];
		if (pa[i] == -1)
			t.root = i;
	}
}

//求双亲表示法的树中某个结点的最左孩子结点和右兄弟节点
//求树t中结点cur的最左孩子结点,结果作为返回值。如果cur为叶结点,则返回-1
int lm_child(paTree t, int cur) {
	for(int i = cur + 1; i < t.n; i++) {
		if (t.tree[i].pa == cur)
			return i; //cur的最左孩子结点为i
	}
	return -1;
}

//求树t中结点cur的右兄弟结点,结果作为返回值。如果cur没有右兄弟结点,则返回-1
int r_brother(paTree t, int cur) {
	if (cur < t.n && t.tree[cur + 1].pa == t.tree[cur].pa) {
		return cur + 1;
	}
	return -1;
}

int main() {

}

1.2 Left and right chain representation of tree

The left-right chain representation of the tree refers to recording the leftmost child node and its right sibling node in each node of the tree. Each node in this representation should contain the node's data, the node's parent node, the node's leftmost child node, and the node's right sibling node. It can be represented by a linked list or an array.

#include<iostream>
using namespace std;
constexpr auto N = 30;
typedef char datatype;

struct lrbNode {
	datatype data;
	int pa;
	int lmc; //最左孩子结点
	int rb; //右兄弟结点
	lrbNode() :lmc(-1), rb(-1) {};
};
typedef struct {
	lrbNode tree[N]; //结点表
	int n; //树的节点总数
	int root;//树的根结点下标
}lrbTree;

//树的孩子列表数组表示法的基本操作
//创建数,data为树的各结点的数据,pa为各结点的父节点,n为树的结点数
lrbTree create_lrbTree(datatype data[], int pa[], int n) {
	lrbTree t;
	t.n = n;
	for (int i = 0; i < n; i++) {
		t.tree[i].data = data[i];
		if (pa[i] == -1) t.root = i; //指定树的父节点
		else {
			t.tree[i].pa = pa[i];//指定结点i的父节点
			if (t.tree[pa[i]].lmc == -1)t.tree[pa[i]].lmc = i; //i为其父节点的第一个孩子结点
			else {
				t.tree[i - 1].rb = i; //i有左兄弟结点i-1,i即为i-1的右兄弟节点
			}
		}
	}
	return t;
}

//求树t中结点cur的最左孩子结点的下标,结果作为返回值
int lm_child(lrbTree t,int cur) {
	return t.tree[cur].lmc;
}

//求树t中结点cur的右兄弟的下标,结果作为函数返回值
int r_brother(lrbTree t, int cur) {
	return t.tree[cur].rb;
}

int main() {

}

Tree and Forest Traversal

tree traversal 

#include<iostream>
using namespace std;
constexpr auto N = 30;
typedef char datatype;

struct lrbNode {
	datatype data;
	int pa;
	int lmc; //最左孩子结点
	int rb; //右兄弟结点
	lrbNode() :lmc(-1), rb(-1) {};
};
typedef struct {
	lrbNode tree[N]; //结点表
	int n; //树的节点总数
	int root;//树的根结点下标
}lrbTree;

//树的孩子列表数组表示法的基本操作
//创建数,data为树的各结点的数据,pa为各结点的父节点,n为树的结点数
lrbTree create_lrbTree(datatype data[], int pa[], int n) {
	lrbTree t;
	t.n = n;
	for (int i = 0; i < n; i++) {
		t.tree[i].data = data[i];
		if (pa[i] == -1) t.root = i; //指定树的父节点
		else {
			t.tree[i].pa = pa[i];//指定结点i的父节点
			if (t.tree[pa[i]].lmc == -1)t.tree[pa[i]].lmc = i; //i为其父节点的第一个孩子结点
			else {
				t.tree[i - 1].rb = i; //i有左兄弟结点i-1,i即为i-1的右兄弟节点
			}
		}
	}
	return t;
}

//求树t中结点cur的最左孩子结点的下标,结果作为返回值
int lm_child(lrbTree t, int cur) {
	return t.tree[cur].lmc;
}

//求树t中结点cur的右兄弟的下标,结果作为函数返回值
int r_brother(lrbTree t, int cur) {
	return t.tree[cur].rb;
}

//树的三种遍历方法
//对树t进行先根遍历,rt为当前子树的根结点
void preOrder(lrbTree t, int rt) {
	if (rt == -1)return;
	cout << t.tree[rt].data; //先访问根结点
	int cur = lm_child(t, rt); //根结点的最左孩子结点
	while (cur != -1) { //从树t的最左子树开始,依次先根遍历t的子树森林
		preOrder(t, cur);
		cur = r_brother(t, cur); //结点cur的右兄弟结点
	}
}

//对树t进行中根遍历,rt为当前子树的根结点
void midOrder(lrbTree t, int rt) {
	if (rt == -1)return;
	int cur = lm_child(t, rt); //根结点的最左孩子结点
	midOrder(t, cur);//中根遍历t的最左子树
	cout << t.tree[rt].data; //在t的最左子树遍历结束后访问根结点
	while (cur != -1) { //根结点的最左孩子结点
		cur = r_brother(t, cur);//结点cur的右兄弟结点
		midOrder(t, cur);
	}
}

//对树t进行后根遍历,rt为当前子树的根结点
void postOrder(lrbTree t, int rt) {
	if (rt == -1) return;
	int cur = lm_child(t, rt);  //根结点的最左孩子结点
	while (cur != -1) { //从t的最左孩子结点出发,依次后根遍历t的子树森林
		postOrder(t, cur);
		cur = r_brother(t, cur);  //结点cur的右兄弟结点
	}
	cout << t.tree[rt].data; //最终访问根结点
}

int main() {

}

Bracket notation for trees

【To be added】

Forest traversal [no code demo]

The forest consists of multiple trees, each tree has a root node, and an auxiliary node can be defined, and the root node of each subtree in the forest is used as its child node, so that the forest becomes a tree, so for Forest traversal can be transformed into tree traversal.

The forest has the following two traversal methods:
        Root-first traversal of the forest: from left to right, the first root traverses each subtree of the forest.
        Back-root traversal of the forest: From left to right, the back-root traverses each subtree of the forest.

Forest to Binary Tree Conversion

After the forest tree is converted into a binary tree, all operations on the forest can be converted into operations on the corresponding binary tree.

Convert forest to binary tree

 

reference:

Conversion between binary trees and trees and forests_kindoms214's blog-CSDN blog_Convert binary trees into corresponding trees or forests %255Fid%2522%253A%2522167422309216800211583404%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=1674223 09216800211583404&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1 -85699598-null-null.142%5Ev71%5Econtrol_1,201%5Ev4%5Eadd_ask&utm_term=%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%8E%E6%A3%AE% E6%9E%97%E7%9A%84%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187

Guess you like

Origin blog.csdn.net/qq_62687015/article/details/128741623
Recommended