数据结构实验

1. (程序题, 25分)

二叉树结点类型为char,特殊字符为@。输入一个二叉树的扩展先序遍历序列,输出该二叉树的后序序列。

例如:一棵二叉树由ABCDEF共6个结点组成,对空指针域采用@扩展。

输入先序遍历序列:ABD@F@@@CE@@@

输出二叉树的后序遍历序列:FDBECA

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);//递归遍历
	print1(H->lch);//栈遍历
	return 0;
}


2. (程序题, 25分)

输入二叉树的扩展的先序遍历序列,建立一棵二叉树,然后输出该二叉树的层次遍历序列(要求借助队列实现)

二叉树结点类型为char,特殊字符为@。

输入先序遍历序列:ABD@F@@@CE@@@

输出二叉树的层次遍历序列为:ABCDEF

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {//递归遍历
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {//栈遍历
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
void print2(Node* r) {//层次遍历,手写队列
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);
	//print1(H->lch);
	print2(H->lch);
	return 0;
}

3. (程序题, 25分)

求二叉树的高度

输入二叉树的扩展的先序遍历序列,建立一棵二叉树,然后输出二叉树的高度(深度)。

输入:

AB@E@R@@CF@@@
输出:
4

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {//递归遍历
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {//栈遍历
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
void print2(Node* r) {//层次遍历,手写队列
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
}
int F(Node* r) {//利用层次遍历查找树的深度
	int ret = 0, f[1000] = { 0 };
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	f[tr] = 1;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
			ret = max(ret, f[tf]);
		}
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
			f[tr] = f[tf] + 1;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
			f[tr] = f[tf] + 1;
		}
	}
	return ret;
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);
	//print1(H->lch);
	//print2(H->lch);
	int ans = F(H->lch);
	cout << ans << endl;
	return 0;
}

4. (程序题, 25分)

求二叉树的叶子结点个数

输入二叉树的扩展的先序遍历序列,建立一棵二叉树,然后输出二叉树的叶子结点个数。

输入先序遍历序列:ABD@F@@@CE@@@

输出二叉树的叶子结点个数:2

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
void print2(Node* r) {
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
}
int F(Node* r) {
	int ret = 0, f[1000] = { 0 };
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	f[tr] = 1;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
			ret = max(ret, f[tf]);
		}
		//printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
			f[tr] = f[tf] + 1;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
			f[tr] = f[tf] + 1;
		}
	}
	return ret;
}
int F1(Node* r) {
	int ret = 0;
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		if (p->lch == NULL && p->rch == NULL) {
			ret++;
			continue;
		}
		//printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
	return ret;
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);
	//print1(H->lch);
	//print2(H->lch);
	//int ans=F(H->lch);
	int ans = F1(H->lch);//利用层次遍历查找叶子节点,写法有很多,只要满足p->lch == NULL && p->rch == NULL就行
	cout << ans << endl;
	return 0;
}

5. (程序题, 25分)

求森林的叶子结点个数:

输入森林对应的二叉树的先序遍历序列,建立一棵二叉树,将该二叉树看作一个森林的孩子兄弟表示法,输出森林的叶子结点个数。

二叉树结点类型为char,特殊字符为@。

输入二叉树的先序遍历序列:ABD@F@@@CE@@@

输出森林的叶子结点个数:3

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
void print2(Node* r) {
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
}
int F(Node* r) {
	int ret = 0, f[1000] = { 0 };
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	f[tr] = 1;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
			ret = max(ret, f[tf]);
		}
		//printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
			f[tr] = f[tf] + 1;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
			f[tr] = f[tf] + 1;
		}
	}
	return ret;
}
int F1(Node* r) {
	int ret = 0;
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		if (p->lch == NULL && p->rch == NULL) {
			ret++;
			continue;
		}
		//printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
	return ret;
}
int F2(Node* r) {
	int ret = 0;
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		if (p->lch == NULL) {
			ret++;
		}
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
	return ret;
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);
	//print1(H->lch);
	//print2(H->lch);
	//int ans=F(H->lch);
	//int ans = F1(H->lch);
	int ans = F2(H->lch);//判断条件:没有左孩子,同样的,有多种做法
	cout << ans << endl;
	return 0;
}

6. (程序题, 25分)

输入二叉树的扩展先序遍历序列,建立一棵二叉树,然后建立该二叉树的中序线索二叉树,在中序线索二叉树基础上中序遍历,输出中序遍历序列。二叉树各结点数据类型为字符型,空节点数据为@

二叉树结点类型为char,特殊字符为@。

输入先序遍历序列:ABD@F@@@CE@@@

输出二叉树的中序遍历序列为:DFBAEC

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
	int ltag, rtag;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
Node* pre = NULL;
void F(Node* r) {
	if (r == NULL)return;
	F(r->lch);
	if (r->lch == NULL) {
		r->ltag = 1;
		r->lch = pre;
	}
	else {
		r->ltag = 0;
	}
	if (pre != NULL) {
		if (pre->rch == NULL) {
			pre->rtag = 1;
			pre->rch = r;
		}
		else {
			pre->rtag = 0;
		}
	}
	pre = r;
	F(r->rch);
}
void print(Node* r) {
	Node* p = r;
	while (p != NULL) {
		while (p->lch != NULL && p->ltag == 0) {
			p = p->lch;
		}
		cout << p->c;
		while (p->rtag && p->rch != NULL) {
			p = p->rch;
			cout << p->c;
		}
		p = p->rch;
	}
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	F(H->lch);//线索化二叉树,跟书上的写法略微不一样,怎么方便怎么来
	print(H->lch);
	return 0;
}

7. (程序题, 25分)

输入二叉树的扩展的先序遍历序列,建立一棵二叉树,输出中序遍历序列(要求非递归算法)。

二叉树结点类型为char,特殊字符为@。

输入先序遍历序列:ABD@F@@@CE@@@

输出二叉树的中序遍历序列为:DFBAEC

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '@') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '@') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {//递归,中序遍历
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void print1(Node* r) {//栈,中序遍历
	Node* stk[100];
	int f[100];
	int tt = 0;
	Node* p = r;
	while (p != NULL || tt != 0) {
		if (p != NULL) {
			stk[tt] = p;
			f[tt] = 1;
			tt++;
			p = p->lch;
		}
		else {
			if (!f[tt - 1]) {
				//printf("%c", stk[tt - 1]->c);
				tt--;
			}
			else {
				printf("%c", stk[tt - 1]->c);
				p = stk[tt - 1];
				f[tt - 1]--;
				p = p->rch;
			}
		}
	}
}
void print2(Node* r) {//层次遍历
	Node* que[N];
	int tr = 0, tf = 0;
	que[++tr] = r;
	Node* p = NULL;
	while (tr != tf) {
		if ((tf + 1) % N <= tr) {
			tf = (tf + 1) % N;
			p = que[tf];
		}
		printf("%c", p->c);
		if ((tr + 1) % N != tf && p->lch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->lch;
		}
		if ((tr + 1) % N != tf && p->rch != NULL) {
			tr = (tr + 1) % N;
			que[tr] = p->rch;
		}
	}
}
int main() {
	cin >> s;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	//print(H->lch);
	//cout << endl;
	print1(H->lch);
	//print2(H->lch);
	return 0;
}

8. (程序题, 25分)

二叉树中求结点的祖先

在二叉链表表示的二叉树中(值域为字符型),查找值为x的结点的所有祖先结点并输出。

输入说明:

利用二叉树的先序递归创建二叉树,键盘输入字符序列,已*代表空结点,中间不允许有重复的值,建立二叉树,接着输入字符x。

输出说明:

若x为根,输出:“没有祖先结点”。

若x不存在,则输出:“x不存在”;

否则,依次输出x的祖先结点,从离x最近的父节点开始,输出到根节点,数据之间用一个空格分隔。

注意:此处的输入请采用C++模式,用cin来接收数据。

输入:
ABD**E*F**C**
F
输出:
E B A

输入:
ABD**E*F**C**
G
输出:
G不存在

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100;
typedef struct Node {
	char c;
	struct Node* lch;
	struct Node* rch;
}Node;
string s;
char x;
void build(Node** root, int& index) {
	if (index >= s.size())return;
	(*root) = (Node*)malloc(sizeof(Node));
	(*root)->c = s[index];
	index++;
	if (s[index] != '*') {
		build(&(*root)->lch, index);
	}
	else {
		(*root)->lch = NULL;
	}
	index++;
	if (s[index] != '*') {
		build(&(*root)->rch, index);
	}
	else {
		(*root)->rch = NULL;
	}
}
void print(Node* r) {
	if (r->lch != NULL) {
		print(r->lch);
	}
	if (r->rch != NULL) {
		print(r->rch);
	}
	printf("%c", r->c);
}
void F(Node* r) {
	if (r->c == x) {
		cout << "没有祖先结点" << endl;
		return;
	}
	Node* p = r;
	Node* stk[N];
	int tt = -1, f[N];
	while (tt != -1 || p != NULL) {
		if (p != NULL) {
			f[++tt] = 1;
			stk[tt] = p;
			p = p->lch;
		}
		else {
			if (f[tt]) {
				p = stk[tt];
				f[tt] = 0;
				p = p->rch;
			}
			else {
				tt--;
			}
		}
		if (p != NULL && p->c == x) {
			break;
		}
	}
	if (tt == -1) {
		cout << x << "不存在" << endl;
	}
	while (tt != -1) {
		cout << stk[tt--]->c << " ";
	}
	cout << endl;
}
int main() {
	cin >> s >> x;
	Node* H = (Node*)malloc(sizeof(Node));
	int index = 0;
	build(&(H->lch), index);
	F(H->lch);//用栈来写中序遍历
	return 0;
}

你可能感兴趣的:(数据结构:基础,杂项,数据结构,c++,算法)