樹:輸出給定有根樹T中各結點u的信息 & 樹的遍歷

《挑戰程序設計競賽》

子節點個數——稱爲度

左子右兄弟表示法 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章