树、森林小节完结

冲冲冲~
This commit is contained in:
Ruvikm
2021-02-07 18:07:13 +08:00
parent 894d8d6750
commit add6da7d1f
3 changed files with 358 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#pragma region 构造链式存储的树(孩子兄弟表示法)
#define MaxSize 100
#define ElemType char
#define _for(i,a,b) for(int i=(a);i<(b);i++)
typedef struct Node { //树的结点
ElemType val;
Node* firstchild;
Node* nextsibling;
}CSNode, * CSTree;
void CreateCSTree(CSTree& T)//要改变指针C++可以把指针的引用传进来
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = new CSNode;
T->val = ch;
CreateCSTree(T->firstchild);
CreateCSTree(T->nextsibling);
}
}
void visit(CSNode* BiCSNode) {
cout << BiCSNode->val << " ";
}
void InOrder(CSTree T) {
if (T) {
InOrder(T->firstchild);
visit(T);
InOrder(T->nextsibling);
}
}
void PostOrder(CSTree T) {
if (T) {
PostOrder(T->firstchild);
PostOrder(T->nextsibling);
visit(T);
}
}
void FindX(CSTree T, ElemType X, CSNode*& r) {
if (T) {
FindX(T->firstchild, X, r);
if (T->val == X)
r = T;
FindX(T->nextsibling, X, r);
}
}
#pragma endregion
//P177.5
//编程求以孩子兄弟表示法存储的森林的叶子结点数
queue<CSNode*> q;
stack<CSNode*> s;
int GetLeaves(CSTree T) {
if (!T)
return 0;
if (!T->firstchild)
return 1 + GetLeaves(T->nextsibling);
else
return GetLeaves(T->firstchild) + GetLeaves(T->nextsibling);
}
int main()
{
CSTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点(T1):" << endl;
// input(左孩子右兄弟): A B # C # D # # E F # # G H # # I # #
CreateCSTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
cout << "森林的叶子结点数为:" << GetLeaves(T) << endl;
return 0;
}
/*
二叉树的孩子兄弟表示:
A
B E
C F G
D H
I
之前的森林为:
A E G
B C D F H I
*/

View File

@@ -0,0 +1,108 @@
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#pragma region 构造链式存储的树(孩子兄弟表示法)
#define MaxSize 100
#define ElemType char
#define _for(i,a,b) for(int i=(a);i<(b);i++)
typedef struct Node { //树的结点
ElemType val;
Node* firstchild;
Node* nextsibling;
}CSNode, * CSTree;
void CreateCSTree(CSTree& T)//要改变指针C++可以把指针的引用传进来
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = new CSNode;
T->val = ch;
CreateCSTree(T->firstchild);
CreateCSTree(T->nextsibling);
}
}
void visit(CSNode* BiCSNode) {
cout << BiCSNode->val << " ";
}
void InOrder(CSTree T) {
if (T) {
InOrder(T->firstchild);
visit(T);
InOrder(T->nextsibling);
}
}
void PostOrder(CSTree T) {
if (T) {
PostOrder(T->firstchild);
PostOrder(T->nextsibling);
visit(T);
}
}
void FindX(CSTree T, ElemType X, CSNode*& r) {
if (T) {
FindX(T->firstchild, X, r);
if (T->val == X)
r = T;
FindX(T->nextsibling, X, r);
}
}
#pragma endregion
//P177.6
//以孩子兄弟链表为存储结构,请设计递归算法求树的深度
queue<CSNode*> q;
stack<CSNode*> s;
int GetDepth(CSTree T)
{
if (!T)
return 0;
else
return max(1 + GetDepth(T->firstchild), GetDepth(T->nextsibling));
}
int main()
{
CSTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点(T1):" << endl;
// input(左孩子右兄弟): A B # C # D # # E F # # G H # # I # #
CreateCSTree(T);
cout << "树的深度为:" << GetDepth(T) << endl;
return 0;
}
/*
二叉树的孩子兄弟表示:
A
B E
C F G
D H
I
所求的其实就是把二叉树转换成森林,森林中树的最大深度
之前的森林为:
A E G
B C D F H I
*/

View File

@@ -0,0 +1,139 @@
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
#pragma region 构造链式存储的树(孩子兄弟表示法)
#define MaxSize 100
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
typedef struct CSNode { //树的结点
ElemType val;
CSNode* firstchild;
CSNode* nextsibling;
}CSNode, * CSTree;
void CreateCSTree(CSTree& T)//要改变指针C++可以把指针的引用传进来
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = new CSNode;
T->val = ch;
CreateCSTree(T->firstchild);
CreateCSTree(T->nextsibling);
}
}
void visit(CSNode* BiCSNode) {
cout << BiCSNode->val << " ";
}
void InOrder(CSTree T) {
if (T) {
InOrder(T->firstchild);
visit(T);
InOrder(T->nextsibling);
}
}
void PostOrder(CSTree T) {
if (T) {
PostOrder(T->firstchild);
PostOrder(T->nextsibling);
visit(T);
}
}
void PreOrder(CSTree T) {
if (T) {
visit(T);
PreOrder(T->firstchild);
PreOrder(T->nextsibling);
}
}
void LevelOrders(CSTree T) {
queue<CSNode*> q;
q.push(T);
while (!q.empty()) {
CSNode* node = q.front();
visit(node);
if (node->firstchild)
q.push(node->firstchild);
if (node->nextsibling)
q.push(node->nextsibling);
q.pop();
}
}
void FindX(CSTree T, ElemType X, CSNode*& r) {
if (T) {
FindX(T->firstchild, X, r);
if (T->val == X)
r = T;
FindX(T->nextsibling, X, r);
}
}
#pragma endregion
//P177.7
//已知一棵树的层次序列及每个结点的度, 编写算法构造此树的孩子 - 兄弟链表
#define MaxNode 15
void CreateCSTree_Degree(CSTree& T, int levelOrder[], int degree[], int length) {
CSNode* pointer = new CSNode[length];
_for(i, 0, length) {
pointer[i].val = levelOrder[i];
pointer[i].firstchild = pointer[i].nextsibling = NULL;
}
int NodeID = 0;
_for(i, 0, length) {
int d = degree[i];
if (d) {
NodeID++;
pointer[i].firstchild = &pointer[NodeID];
for (int j = 2; j <= d; j++) {
NodeID++;
pointer[NodeID - 1].nextsibling = &pointer[NodeID];
}
}
}
T = &pointer[0];
}
int main()
{
CSTree T;
int length = 9;
int levelOrder[9] = { 3, 2, 1, 5, 4, 6, 8, 7, 9 };
int degree[9] = { 3, 2, 0, 1, 1, 0, 1, 0, 0 };
CreateCSTree_Degree(T, levelOrder, degree, length);
cout << "先序遍历:" << endl;
PreOrder(T);
return 0;
}
/*
3
2 1 5
4 6 8
7 9
参考了大佬的文章https://blog.csdn.net/qinglingls/article/details/110786988
*/