数据结构实验
1. (程序题, 25分)
二叉树结点类型为char,特殊字符为@。输入一个二叉树的扩展先序遍历序列,输出该二叉树的后序序列。
例如:一棵二叉树由ABCDEF共6个结点组成,对空指针域采用@扩展。
输入先序遍历序列:ABD@F@@@CE@@@
输出二叉树的后序遍历序列:FDBECA
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
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;
}