《資料結構》實驗08--樹及其應用

Alex_SCY發表於2020-11-10

問題 A: DS樹–二叉樹高度

題目描述

給出一棵二叉樹,求它的高度。二叉樹的建立採用前面實驗的方法。
注意,二叉樹的層數是從1開始

輸入

第一行輸入一個整數t,表示有t個二叉樹
第二行起輸入每個二叉樹的先序遍歷結果,空樹用字元‘0’表示,連續輸入t行

輸出

每行輸出一個二叉樹的高度

樣例輸入

1
AB0C00D00

樣例輸出

3

題解

#include<iostream>
using namespace std;

typedef struct BTree_node {
	char data;
	struct BTree_node* LChild;
	struct BTree_node* RChild;
	int depth = 0;
}BTree;

class Btree {
public:
	BTree_node* root;
	int depth;
	int i;
	Btree() {
		root = NULL;
		depth = 0;
		i = 0;
	}
	void Create_BTree(BTree*& t)
	{
		char s;
		cin >> s;
		if (s == '0')
			t = NULL;
		else
		{
			t = new BTree_node;
			t->data = s;
			Create_BTree(t->LChild);
			Create_BTree(t->RChild);
		}
	}
	void cal_Depth(BTree* t,int i)
	{
		if (t)
		{
			i++;
			if (t->LChild == NULL && t->RChild == NULL)
			{
				if (depth < i)
					depth = i;
			}
			cal_Depth(t->LChild, i);
			cal_Depth(t->RChild, i);
		}
	}
};



int main() {
	int t;
	cin >> t;
	while (t--) {
		Btree tree;
		tree.Create_BTree(tree.root);
		tree.cal_Depth(tree.root, 0);
		cout << tree.depth << endl;
	}

	return 0;
}


問題 B: DS樹–二叉樹之最大路徑

題目描述

給定一顆二叉樹的邏輯結構(先序遍歷的結果,空樹用字元‘0’表示,例如AB0C00D00),建立該二叉樹的二叉鏈式儲存結構
二叉樹的每個結點都有一個權值,從根結點到每個葉子結點將形成一條路徑,每條路徑的權值等於路徑上所有結點的權值和。程式設計求出二叉樹的最大路徑權值。如下圖所示,共有4個葉子即有4條路徑,
路徑1權值=5 + 4 + 11 + 7 = 27
路徑2權值=5 + 4 + 11 + 2 = 22
路徑3權值=5 + 8 + 13 = 26
路徑4權值=5 + 8 + 4 + 1 = 18
可計算出最大路徑權值是27。
該樹輸入的先序遍歷結果為ABCD00E000FG00H0I00,各結點權值為:
A-5,B-4,C-11,D-7,E-2,F-8,G-13,H-4,I-1
在這裡插入圖片描述

輸入

第一行輸入一個整數t,表示有t個測試資料
第二行輸入一棵二叉樹的先序遍歷,每個結點用字母表示
第三行先輸入n表示二叉樹的結點數量,然後輸入每個結點的權值,權值順序與前面結點輸入順序對應
以此類推輸入下一棵二叉樹

輸出

每行輸出每棵二叉樹的最大路徑權值,如果最大路徑權值有重複,只輸出1個

樣例輸入

2
AB0C00D00
4 5 3 2 6
ABCD00E000FG00H0I00
9 5 4 11 7 2 8 13 4 1

樣例輸出

11
27

題解

#include<iostream>
using namespace std;

typedef struct BTree_node {
	char data;
	struct BTree_node* LChild;
	struct BTree_node* RChild;
	int value;
}BTree;

class Btree {
public:
	BTree_node* root;
	int depth;
	int i;
	int MaxRoutine;
	Btree() {
		root = NULL;
		depth = 0;
		i = 0;
		MaxRoutine = 0;
	}
	void Create_BTree(BTree*& t)
	{
		char s;
		cin >> s;
		if (s == '0')
			t = NULL;
		else
		{
			t = new BTree_node;
			t->data = s;
			Create_BTree(t->LChild);
			Create_BTree(t->RChild);
		}
	}
	void cal_Depth(BTree* t, int i)
	{
		if (t)
		{
			i++;
			if (t->LChild == NULL && t->RChild == NULL)
			{
				if (depth < i)
					depth = i;
			}
			cal_Depth(t->LChild, i);
			cal_Depth(t->RChild, i);
		}
	}
	void set_value(BTree* t) {
		if (t) {
			cin >> t->value;
			set_value(t->LChild);
			set_value(t->RChild);
		}
	}
	void cal_MaxRoutine(BTree* t, int val) {
		if (t) {
			val += t->value;
			if (t->LChild == NULL && t->RChild == NULL) {
				if (val > MaxRoutine) {
					MaxRoutine = val;
				}
			}
			cal_MaxRoutine(t->LChild, val);
			cal_MaxRoutine(t->RChild, val);
		}
	}
};

int main() {
	int t;
	cin >> t;
	while (t--) {
		Btree tree;
		tree.Create_BTree(tree.root);
		int data;
		cin >> data;
		tree.set_value(tree.root);
		tree.cal_MaxRoutine(tree.root, 0);
		cout << tree.MaxRoutine << endl;
	}

	return 0;
}

問題 C: DS樹–帶權路徑和

題目描述

計算一棵二叉樹的帶權路徑總和,即求赫夫曼樹的帶權路徑和。
已知一棵二叉樹的葉子權值,該二叉樹的帶權案路徑和APL等於葉子權值乘於根節點到葉子的分支數,然後求總和。如下圖中,葉子都用大寫字母表示,權值對應為:A-7,B-6,C-2,D-3
樹的帶權路徑和 = 71 + 62 + 23 + 33 = 34在這裡插入圖片描述
本題二叉樹的建立參考前面的方法

輸入

第一行輸入一個整數t,表示有t個二叉樹
第二行輸入一棵二叉樹的先序遍歷結果,空樹用字元‘0’表示,注意輸入全是英文字母和0,其中大寫字母表示葉子
第三行先輸入n表示有n個葉子,接著輸入n個資料表示n個葉子的權值,權值的順序和前面輸入的大寫字母順序對應
以此類推輸入下一棵二叉樹

輸出

輸出每一棵二叉樹的帶權路徑和

樣例輸入

2
xA00tB00zC00D00
4 7 6 2 3
ab0C00D00
2 10 20

樣例輸出

34
40

題解

#include<iostream>
using namespace std;

typedef struct BTree_node {
	char data;
	struct BTree_node* LChild;
	struct BTree_node* RChild;
	int value;
}BTree;

class Btree {
public:
	BTree_node* root;
	int depth;
	int i;
	int MaxRoutine;
	int value;
	Btree() {
		root = NULL;
		depth = 0;
		i = 0;
		MaxRoutine = 0;
		value = 0;
	}
	void Create_BTree(BTree*& t)
	{
		char s;
		cin >> s;
		if (s == '0')
			t = NULL;
		else
		{
			t = new BTree_node;
			t->data = s;
			Create_BTree(t->LChild);
			Create_BTree(t->RChild);
		}
	}
	void cal_Depth(BTree* t, int i)
	{
		if (t)
		{
			i++;
			if (t->LChild == NULL && t->RChild == NULL)
			{
				if (depth < i)
					depth = i;
			}
			cal_Depth(t->LChild, i);
			cal_Depth(t->RChild, i);
		}
	}
	void set_value(BTree* t) {
		if (t) {
			if (t->LChild == NULL && t->RChild == NULL)
				cin >> t->value;
			set_value(t->LChild);
			set_value(t->RChild);
		}
	}
	void cal_MaxRoutine(BTree* t, int val) {
		if (t) {
			val += t->value;
			if (t->LChild == NULL && t->RChild == NULL) {
				if (val > MaxRoutine) {
					MaxRoutine = val;
				}
			}
			cal_MaxRoutine(t->LChild, val);
			cal_MaxRoutine(t->RChild, val);
		}
	}
	void cal(BTree* t, int deep) {
		if (t) {
			if (t->LChild == NULL && t->RChild == NULL) {
				value += t->value * deep;
			}
			deep++;
			cal(t->LChild, deep);
			cal(t->RChild, deep);
		}
	}
};

int main() {
	int t;
	cin >> t;
	while (t--) {
		Btree tree;
		tree.Create_BTree(tree.root);
		int data;
		cin >> data;
		tree.set_value(tree.root);
		tree.cal(tree.root, 0);
		cout << tree.value << endl;		
	}

	return 0;
}

相關文章