5.2二叉树的概念
1.已知一棵二叉树按顺序存储结构进行存储,设计一个算法,求编号分别i和j的两个结点的最近公共祖先结点的值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
char *T;
char a[MAX];
char Comm_Ancestor(char *T, int i, int j)
{
char res = '\0';
if (T[i] != '#' && T[j] != '#') {
while (i != j) {
if (i > j) i = i / 2;
else j = j / 2;
}
res = T[i];
}
return res;
}
int main()
{
char ans;
int p, q;
scanf("%s", a);
int len = strlen(a);
T = (char *)malloc(sizeof(char) * len);
for (int i = 1; i <= len; i++) {
*(T + i) = a[i - 1];
}
scanf("%d %d", &p, &q);
ans = Comm_Ancestor(T, p, q);
printf("%c\n", ans);
return 0;
}
5.3二叉树的遍历和线索二叉树
3.编写后序遍历二叉树的非递归算法。
#include <stack>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void visit(BiTNode *R)
{
cout << R->data << " ";
}
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void PostOrder(BiTree T)
{
stack<BiTNode *> st;
BiTNode *p = T, *r = NULL;
while (p || !st.empty()) {
if (p) {
st.push(p);
p = p->lchild;
} else {
p = st.top();
if (p->rchild != NULL && p->rchild != r) {
p = p->rchild;
} else {
r = st.top();
visit(r);
st.pop();
p = NULL;
}
}
}
}
int main()
{
BiTree T;
InitBiTree(T);
PostOrder(T);
return 0;
}
4.试给出二叉树的自下而上、从右到左的层次遍历算法。
#include <queue>
#include <stack>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void visit(BiTNode *R)
{
cout << R->data << " ";
}
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void LevelOrder(BiTree T)
{
queue<BiTNode *> q;
stack<BiTNode *> st;
BiTNode *p;
q.push(T);
while (!q.empty()) {
p = q.front();
st.push(p);
q.pop();
if (p->lchild != NULL) q.push(p->lchild);
if (p->rchild != NULL) q.push(p->rchild);
}
while (!st.empty()) {
visit(st.top());
st.pop();
}
}
int main()
{
BiTree T;
InitBiTree(T);
LevelOrder(T);
return 0;
}
5.假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度。
#include <queue>
#include <stack>
#include <iostream>
using namespace std;
const int MaxSize = 100;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void visit(BiTNode *R)
{
cout << R->data << " ";
}
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int Btdepth(BiTree T)
{
if (!T) return 0;
int front = -1, rear = -1;
int last = 0, level = 0;
BiTree Q[MaxSize];
Q[++rear] = T;
BiTree p;
while (front < rear) {
p = Q[++front];
if (p->lchild) Q[++rear] = p->lchild;
if (p->rchild) Q[++rear] = p->rchild;
if (front == last) {
level++;
last = rear;
}
}
return level;
}
int main()
{
BiTree T;
InitBiTree(T);
cout << Btdepth(T) << endl;
return 0;
}
6.设一棵二叉树中各结点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个一维数组 A [ 1... n ] A[1...n] A[1...n]和 B [ 1... n ] B[1...n] B[1...n]中,试编写算法建立该二叉树的二叉链表。
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 100;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
ElemType *A, *B, A1[maxn], B1[maxn];
BiTree PreInCreat(ElemType *A, ElemType *B, int l1, int h1, int l2, int h2)
{
int i, llen, rlen;
BiTree root = (BiTree)malloc(sizeof(BiTNode));
root->data = A[l1];
for (i = l2; B[i] != root->data; i++)
;
llen = i - l2;
rlen = h2 - i;
if (llen) root->lchild = PreInCreat(A, B, l1 + 1, l1 + llen, l2, l2 + llen - 1);
else root->lchild = NULL;
if (rlen) root->rchild = PreInCreat(A, B, h1 - rlen + 1, h1, h2 - rlen + 1, h2);
else root->rchild = NULL;
return root;
}
int main()
{
scanf("%s", A1);
scanf("%s", B1);
int h1 = strlen(A1); int h2 = strlen(B1);
A = (ElemType *)malloc(sizeof(ElemType) * h1);
B = (ElemType *)malloc(sizeof(ElemType) * h2);
for (int i = 1; i <= h1; i++) {
*(A + i) = A1[i - 1];
}
for (int i = 1; i <= h2; i++) {
*(B + i) = B1[i - 1];
}
BiTree T;
T = PreInCreat(A, B, 1, h1, 1, h2);
return 0;
}
7.二叉树按二叉链表形式存储,写一个判别给定二叉树是否是完全二叉树的算法。
#include <queue>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
bool IsComplete(BiTree T)
{
if (!T) return true;
queue<BiTree> q;
q.push(T);
BiTree tmp = NULL;
while (tmp = q.front()) {
q.push(tmp->lchild);
q.push(tmp->rchild);
q.pop();
}
while (!q.empty()) {
if (q.front() != NULL) return false;
q.pop();
}
return true;
}
int main()
{
BiTree T;
InitBiTree(T);
if (IsComplete(T)) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
8.假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。
#include <queue>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int DsonNodes(BiTree b)
{
if (b == NULL) return 0;
else if (b->lchild != NULL && b->rchild != NULL)
return DsonNodes(b->lchild) + DsonNodes(b->rchild) + 1;
else return DsonNodes(b->lchild) + DsonNodes(b->rchild);
}
int main()
{
BiTree T;
InitBiTree(T);
cout << DsonNodes(T) << endl;
return 0;
}
9.设树B是一棵采用链式结构存储的二叉树,编写一个把树B中所有结点的左、右子树进行交换的函数。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void swap(BiTree b)
{
if (b) {
swap(b->lchild);
swap(b->rchild);
BiTree temp = b->lchild;
b->lchild = b->rchild;
b->rchild = temp;
}
}
int main()
{
BiTree T;
InitBiTree(T);
swap(T);
cout << T->rchild->data << endl;
return 0;
}
10.假设二叉树采用二叉链表存储结构存储,设计一个算法,求先序遍历序列中第 k ( 1 ≤ k ≤ 二 叉 树 中 结 点 个 数 ) k(1 \leq k \leq 二叉树中结点个数) k(1≤k≤二叉树中结点个数)个结点的值。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
int i = 1;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
ElemType PreNode(BiTree b, int k)
{
if (b == NULL) return '#';
if (i == k) return b->data;
i++;
ElemType ch;
ch = PreNode(b->lchild, k);
if (ch != '#') return ch;
ch = PreNode(b->rchild, k);
return ch;
}
int main()
{
BiTree T;
InitBiTree(T);
ElemType ans;
ans = PreNode(T, 4);
cout << ans << endl;
return 0;
}
11.已知二叉树以二叉链表存储,i编写算法完成:对于树中每个元素值为x的结点,删去以它为根的子树,并释放相应的空间。
#include <queue>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
int i = 1;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void DeleteXTree(BiTree &bt)
{
if (bt) {
DeleteXTree(bt->lchild);
DeleteXTree(bt->rchild);
free(bt);
}
}
void Search(BiTree bt, ElemType x)
{
queue<BiTree> q;
if (bt) {
if (bt->data == x) {
DeleteXTree(bt);
exit(0);
}
q.push(bt);
while (!q.empty()) {
BiTree temp = q.front();
q.pop();
if (temp->lchild) {
if (temp->lchild->data == x) {
DeleteXTree(temp->lchild);
temp->lchild = NULL;
} else {
q.push(temp->lchild);
}
}
if (temp->rchild) {
if (temp->rchild->data == x) {
DeleteXTree(temp->rchild);
temp->rchild = NULL;
} else {
q.push(temp->rchild);
}
}
}
}
}
int main()
{
BiTree T;
InitBiTree(T);
ElemType x;
cin >> x;
Search(T, x);
cout << T->rchild->lchild->data << endl;
return 0;
}
12.在二叉树中查找值为x的结点,试编写算法(用C语言)打印值为x的结点的所有祖先,假设值为x的结点不多于一个。
#include <stack>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void visit(BiTree T)
{
cout << T->data << " ";
}
void Search(BiTree T, ElemType x)
{
BiTree p = T, r = NULL;
stack<BiTree> st;
while (p || !st.empty()) {
if (p) {
st.push(p);
p = p->lchild;
} else {
p = st.top();
if (p->data == x) {
while (!st.empty()) {
visit(st.top());
st.pop();
}
return;
}
if (p->rchild && p->rchild != r)
p = p->rchild;
else {
r = st.top();
st.pop();
p = NULL;
}
}
}
}
int main()
{
BiTree T;
InitBiTree(T);
ElemType x;
cin >> x;
Search(T, x);
return 0;
}
13.设一棵二叉树的结点结构为 ( L L I N K , I N F O , R L I N K ) (LLINK,INFO,RLINK) (LLINK,INFO,RLINK), R O O T ROOT ROOT为指向该二叉树根结点的指针, q q q和 q q q分别指向该二叉树中任意两个结点的指针,试编写算法 A N C E S T O R ( R O O T , p , q , r ) ANCESTOR(ROOT,p,q,r) ANCESTOR(ROOT,p,q,r),找到 p p p和 q q q的最近公共祖先结点 r r r。
#include <map>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType INFO;
struct BiTNode *LLINK, *RLINK;
} BiTNode, *BiTree;
map<ElemType, BiTree> fa;
map<int, bool> vis;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->INFO = ch;
InitBiTree(T->LLINK);
InitBiTree(T->RLINK);
}
}
void dfs(BiTree T)
{
if (T->LLINK) {
fa[T->LLINK->INFO] = T;
dfs(T->LLINK);
}
if (T->RLINK) {
fa[T->RLINK->INFO] = T;
dfs(T->RLINK);
}
}
void ANCESTOR(BiTree ROOT, BiTree p, BiTree q, BiTree &r)
{
fa[ROOT->INFO] = NULL;
dfs(ROOT);
while (p != NULL) {
vis[p->INFO] = true;
p = fa[p->INFO];
}
while (q != NULL) {
if (vis[q->INFO]) {
r = q;
return;
} else q = fa[q->INFO];
}
return;
}
int main()
{
BiTree ROOT, ans = NULL;
InitBiTree(ROOT);
ANCESTOR(ROOT, ROOT->RLINK->LLINK->RLINK, ROOT->RLINK->RLINK, ans);
cout << ans->INFO << endl;
return 0;
}
14.假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树b的宽度(即具有结点数最多的那一层的结点个数)。
王道书上的做法:
#include <iostream>
using namespace std;
const int MaxSize = 100;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
typedef struct {
BiTree data[MaxSize];
int level[MaxSize];
int front, rear;
} Qu;
Qu q;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int BTWidth(BiTree b)
{
BiTree p;
int k, maxn, i, n;
q.front = q.rear = -1;
q.rear++;
q.data[q.rear] = b;
q.level[q.rear] = 1;
while (q.front < q.rear) {
q.front++;
p = q.data[q.front];
k = q.level[q.front];
if (p->lchild != NULL) {
q.rear++;
q.data[q.rear] = p->lchild;
q.level[q.rear] = k + 1;
}
if (p->rchild != NULL) {
q.rear++;
q.data[q.rear] = p->rchild;
q.level[q.rear] = k + 1;
}
}
maxn = 0; i = 0;
k = 1;
while (i <= q.rear) {
n = 0;
while (i <= q.rear && q.level[i] == k) {
n++;
i++;
}
k = q.level[i];
if (n > maxn) maxn = n;
}
return maxn;
}
int main()
{
BiTree T;
InitBiTree(T);
cout << BTWidth(T) << endl;
return 0;
}
我的做法:
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int LevelOrder(BiTree T)
{
int res = 0;
queue<BiTree> q;
q.push(T);
while (!q.empty()) {
BiTree temp = q.front();
q.pop();
if (temp->lchild) q.push(temp->lchild);
if (temp->rchild) q.push(temp->rchild);
int t = q.size();
res = max(res, t);
}
return res;
}
int main()
{
BiTree T;
InitBiTree(T);
cout << LevelOrder(T) << endl;
return 0;
}
15.设有一棵满二叉树(所有结点值均不同),已知其先序序列为pre,设计一个算法求其后序序列post。
#include <stdio.h>
#include <string.h>
char pre[50], post[50];
void PreToPost(char pre[], int l1, int r1, char post[], int l2, int r2)
{
int mid;
if (r1 >= l1) {
post[r2] = pre[l1];
mid = (r1 - l1) / 2;
PreToPost(pre, l1 + 1, l1 + mid, post, l2, l2 + mid - 1);
PreToPost(pre, l1 + mid + 1, r1, post, l2 + mid, r2 - 1);
}
}
int main()
{
scanf("%s", pre);
int len = strlen(pre);
PreToPost(pre, 0, len, post, 0, len);
for (int i = 0; i < len + 1; i++)
printf("%c", post[i]);
return 0;
}
16.设计一个算法将二叉树的叶结点按从左到右的顺序连成一个单链表,表头指针为head,二叉树按二叉链表方式存储,链接时用叶结点的右指针域来存放单链表指针。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree head, pre = NULL;
void InitBiTree(BiTree &bt)
{
ElemType ch;
cin >> ch;
if (ch == '#') bt = NULL;
else {
bt = (BiTree)malloc(sizeof(BiTNode));
bt->data = ch;
InitBiTree(bt->lchild);
InitBiTree(bt->rchild);
}
}
BiTree InOrder(BiTree bt)
{
if (bt) {
InOrder(bt->lchild);
if (bt->lchild == NULL && bt->rchild == NULL) {
if (pre == NULL) {
head = bt;
pre = bt;
} else {
pre->rchild = bt;
pre = bt;
}
}
InOrder(bt->rchild);
pre->rchild = NULL;
}
return head;
}
int main()
{
BiTree bt;
InitBiTree(bt);
BiTree ans = InOrder(bt);
while (ans) {
cout << ans->data << " ";
ans = ans->rchild;
}
cout << endl;
return 0;
}
17.试设计判断两棵二叉树是否相似的算法。所谓二叉树 T 1 T_{1} T1和 T 2 T_{2} T2相似,指的是 T 1 T_{1} T1和 T 2 T_{2} T2都是空的二叉树或都只有一个根结点;或 T 1 T_{1} T1的左子树和 T 2 T_{2} T2的左子树是相似的,且 T 1 T_{1} T1的右子树和 T 2 T_{2} T2的右子树是相似的。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int similar(BiTree T1, BiTree T2)
{
int leftS, rightS;
if (T1 == NULL && T2 == NULL) return 1;
else if (T1 == NULL || T2 == NULL) return 0;
else {
leftS = similar(T1->lchild, T2->lchild);
rightS = similar(T1->rchild, T2->rchild);
return leftS && rightS;
}
}
int main()
{
BiTree T1, T2;
InitBiTree(T1);
InitBiTree(T2);
if (similar(T1, T2)) cout << "yes" << endl;
else cout << "no" << endl;
return 0;
}
18.写出在中序线索二叉树里查找指定结点在后序的前驱结点的算法。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct ThreadNode {
ElemType data;
struct ThreadNode *lchild, *rchild;
int ltag, rtag;
} ThreadNode, *ThreadTree;
void InitInThread(ThreadTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (ThreadTree)malloc(sizeof(ThreadNode));
T->data = ch;
InitInThread(T->lchild);
InitInThread(T->rchild);
}
}
void InThread(ThreadTree &p, ThreadTree &pre)
{
if (p != NULL) {
InThread(p->lchild, pre);
if (p->lchild == NULL) {
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL) {
pre->rchild = p;
pre->rtag = 1;
}
pre = p;
InThread(p->rchild, pre);
}
}
void CreateInThread(ThreadTree T)
{
ThreadTree pre = NULL;
if (T != NULL) {
InThread(T, pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
ThreadTree InPostPre(ThreadTree t, ThreadTree p)
{
ThreadTree q;
if (p->rtag == 0) q = p->rchild;
else if (p->ltag == 0) q = p->lchild;
else if (p->lchild == NULL) q = NULL; // p是中序序列第一结点,无后序前驱
else {
while (p->ltag == 1 && p->lchild != NULL) p = p->lchild;
if (p->ltag == 0) q = p->lchild;
else q = NULL;
}
return q;
}
int main()
{
ThreadTree T;
InitInThread(T);
CreateInThread(T);
ThreadTree ans = InPostPre(T, T->rchild->lchild);
cout << ans->data << endl;
return 0;
}
19.二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T,采用二叉链表存储,请设计求T的WPL的算法。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
int weight;
ElemType data;
struct BiTNode *left, *right;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
int w;
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
cin >> w;
T->weight = w;
InitBiTree(T->left);
InitBiTree(T->right);
}
}
int wpl_PreOrder(BiTree root, int deep)
{
static int wpl = 0;
if (root->left == NULL && root->right == NULL)
wpl += deep * root->weight;
if (root->left != NULL)
wpl_PreOrder(root->left, deep + 1);
if (root->right != NULL)
wpl_PreOrder(root->right, deep + 1);
return wpl;
}
int WPL(BiTree root)
{
return wpl_PreOrder(root, 0);
}
int main()
{
BiTree T;
InitBiTree(T);
int ans = WPL(T);
cout << ans << endl;
return 0;
}
20.设计一个算法,将给定的表达式树转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BNode {
ElemType data;
struct BNode *left, *right;
} BNode, *BTree;
void InitBTree(BTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BTree)malloc(sizeof(BNode));
T->data = ch;
InitBTree(T->left);
InitBTree(T->right);
}
}
void BtreeToExp(BTree root, int deep)
{
if (root == NULL) return;
else if (root->left == NULL && root->right == NULL)
cout << root->data;
else {
if (deep > 1) cout << "(";
BtreeToExp(root->left, deep + 1);
cout << root->data;
BtreeToExp(root->right, deep + 1);
if (deep > 1) cout << ")";
}
}
void BtreeToE(BTree root)
{
BtreeToExp(root, 1);
}
int main()
{
BTree T;
InitBTree(T);
BtreeToE(T);
return 0;
}
5.5树与二叉树的应用
6.试编写一个算法,判断给定的二叉树是否是二叉排序树。
#include <climits>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
bool dfs(BiTree T, int minv, int maxv)
{
if (T == NULL) return true;
if (T->data < minv || T->data > maxv) return false;
return dfs(T->lchild, minv, T->data - 1) && dfs(T->rchild, T->data + 1, maxv);
}
bool JudgeBST(BiTree T)
{
return dfs(T, INT_MIN, INT_MAX);
}
int main()
{
BiTree T;
InitBiTree(T);
if (JudgeBST(T)) cout << "yes" << endl;
else cout << "no" << endl;
return 0;
}
7.设计一个算法,求出指定结点在给定二叉排序树中的层次。
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int level(BiTree T, ElemType w)
{
int res = 0;
BiTree p = T;
if (T != NULL) {
res++;
while (p->data != w) {
if (p->data < w) p = p->rchild;
else p = p->lchild;
res++;
}
}
return res;
}
int main()
{
ElemType w;
BiTree T;
InitBiTree(T);
cin >> w;
int ans = level(T, w);
cout << ans << endl;
return 0;
}
8.利用二叉树遍历的思想编写一个判断二叉树是否是平衡二叉树的算法。
#include <cmath>
#include <iostream>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void Judge_AVL(BiTree bt, int &balance, int &h)
{
int bl = 0, br = 0, hl = 0, hr = 0;
if (bt == NULL) {
h = 0;
balance = 1;
} else if (bt->lchild == NULL && bt->rchild == NULL) {
h = 1;
balance = 1;
} else {
Judge_AVL(bt->lchild, bl, hl);
Judge_AVL(bt->rchild, br, hr);
h = (hl > hr ? hl : hr) + 1;
if (abs(hl - hr) < 2) balance = bl && br;
else balance = 0;
}
}
int main()
{
BiTree T;
InitBiTree(T);
int balance = 0, h = 0;
Judge_AVL(T, balance, h);
cout << balance << endl;
return 0;
}
9.设计一个算法,求出给定二叉排序树中最小和最大的关键字。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
ElemType Max_Element(BiTree T)
{
while (T->rchild != NULL)
T = T->rchild;
return T->data;
}
ElemType Min_Element(BiTree T)
{
while (T->lchild != NULL)
T = T->lchild;
return T->data;
}
void InitBiTree(BiTree &T)
{
ElemType ch;
scanf("%d ", &ch);
if (ch == -1) T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
int main()
{
BiTree T;
InitBiTree(T);
printf("%d %d\n", Max_Element(T), Min_Element(T));
return 0;
}
10.设计一个算法,从大到小输出二叉排序树中所有值不小于k的关键字。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)
{
ElemType ch;
scanf("%d ", &ch);
if (ch == -1) T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
InitBiTree(T->lchild);
InitBiTree(T->rchild);
}
}
void OutPut(BiTree T, ElemType k)
{
if (T == NULL) return;
if (T->rchild != NULL) OutPut(T->rchild, k);
if (T->data >= k) printf("%d ", T->data);
if (T->lchild != NULL) OutPut(T->lchild, k);
}
int main()
{
BiTree T;
ElemType k;
InitBiTree(T);
scanf("%d", &k);
OutPut(T, k);
return 0;
}