《挑戰程序設計競賽》
子節點個數——稱爲度
左子右兄弟表示法 left-child right-sibling representation
一、輸出給定有根樹T中各結點u的信息
#include "pch.h"
#include<iostream>
using namespace std;
#define MAX 100005
#define NIL -1
struct Node {
int parent;
int left;
int right;
};
Node T[MAX];
int n, D[MAX];
//打印節點
void print(int u) {
int i, c;
cout << "node " << u << ": ";
cout << "parent = " << T[u].parent << ", ";
cout << "depth = " << D[u] << ", ";
if (T[u].parent == NIL) {
cout << "rout, ";
}
else if(T[u].left==NIL){
cout << "leaf, ";
}
else {
cout << "internal node, ";
}
cout << "[";
for (i = 0, c = T[u].left; c != NIL; i++, c = T[u].right) {
if (i) {
cout << ", ";
}
cout << c;
}
cout << "]" << endl;
}
//遞歸求深度
void rec(int u, int p) {
D[u] = p;
//右側兄弟設置爲相同深度
if (T[u].right != NIL) {
rec(T[u].right, p);
}
//最左側子結點的深度設置爲自己的深度+1
if (T[u].left != NIL) {
rec(T[u].left, p + 1);
}
}
int main() {
int i, j, d, v, c, l, r;
cin >> n;//結點的個數
for (i = 0; i < n; i++) {
T[i].parent = NIL;
T[i].left = NIL;
T[i].right = NIL;
}
for (i = 0; i < n; i++) {
cin >> v >> d;//v:結點的編號;d:爲結點的度(即:該結點有幾個子結點)
for (j = 0; j < d; j++) {
cin >> c;
if (j == 0) {
T[v].left = c;
}
else {
T[l].right = c;
}
l = c;
T[c].parent = v;
}
}
for (i = 0; i < n; i++) {
if (T[i].parent == NIL) {
r = i;
}
}
rec(r, 0);
for (i = 0; i < n; i++) {
print(i);
}
return 0;
}
二、打印樹的前序、中序、後序遍歷
前序遍歷:根節點——左子樹——右子樹 【Preorder】
中序遍歷:左子樹——根節點——右子樹 【Inorder】
後序遍歷:左子樹——右子樹——根節點 【Postorder】
算法複雜度爲O(N),但使用遞歸時,一旦樹的結點數量龐大且分佈不均,很可能導致遞歸深度過深。
#include<iostream>
using namespace std;
#define MAX 10000
#define NIL -1
struct Node {
int p,l,r;
};
struct Node T[MAX];
int n;
//前序遍歷
void preParse(int u) {
if(u==NIL){
return;
}
printf(" %d",u); //根
preParse(T[u].l); //左
preParse(T[u].r); //右
}
//中序遍歷
void inParse(int u) {
if(u==NIL){
return;
}
inParse(T[u].l); //左
printf(" %d",u); //根
inParse(T[u].r); //右
}
//後序遍歷
void postParse(int u) {
if(u==NIL){
return;
}
postParse(T[u].l); //左
postParse(T[u].r); //右
printf(" %d",u); //根
}
int main() {
int i, v, root, l, r;
scanf("%d",&n); //結點的個數
for(i=0;i<n;i++){
T[i].p=NIL;
}
for(i=0;i<n;i++){
scanf("%d %d %d",&v,&l,&r); //v 結點的編號,l左結點,r右結點
T[v].l = l;
T[v].r = r;
if(l!=NIL){
T[l].p = v; //父結點
}
if(r!=NIL){
T[r].p = v; //父結點
}
}
for(i=0;i<n;i++){
if(T[i].p==NIL){
root = i;
}
}
printf("PreOrder\n");
preParse(root);
printf("\n");
printf("InOrder\n");
preParse(root);
printf("\n");
printf("PostOrder\n");
preParse(root);
printf("\n");
return 0;
}