文章目录
- 1、找两个结点的公共结点(顺序存储)
- 2、后序遍历二叉树的非递归算法
- 3、给出二叉树自下而上、自右向左的层次遍历算法
- 4、假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度
- 5、根据中序和前序构建二叉树的二叉链表
- 6、判断是否是完全二叉树
- 7、求二叉树所有双分支结点的个数
- 8、交换左右子树
- 9、求先序遍历中第k个结点的值
- 10、找到元素值为x的结点,删去以它为根的子树
- 11、打印值为x的结点的所有祖先
- 12、找出最近公共祖先结点
- 13、求非空二叉树的宽度
- 14、满二叉树已知先序,求后序序列
- 15、将二叉树叶结点连成单链表
- 16、判断二叉树是否相似
- 17、在中序线索二叉树里查找指定结点在后序的前驱
- 18、带权路径长度
- 19、求中缀表达式
- 20、以孩子兄弟表示法存储的森林的叶子结点数
- 21、孩子兄弟表示法递归求树深度
- 22、已知层次序列和结点度,构造树的孩子兄弟链表
1、找两个结点的公共结点(顺序存储)
#include<stdio.h>
#define MaxSize 100
typedef struct TreeNode { //二叉树顺序存储结构体
int data; // 结点中的数据元素
}TreeNode;
int FindCom(TreeNode* t,int i,int j){
if(t[i].data!=-1&&t[j].data!=-1) //data值为-1,表示结点值为空
{
while(i!=j)
{
if(i>j) i/=2;
else j/=2;
}
return t[i].data;
}
return -1;
}
int main(){
TreeNode t[MaxSize];
t[0].data=-1;
t[1].data=1;
t[2].data=2;
t[3].data=3;
t[4].data=-1;
t[5].data=4;
t[6].data=-1;
t[7].data=5;
t[8].data=-1;
t[9].data=-1;
t[10].data=-6;
t[11].data=-1;
int ret=FindCom(t,7,10);
(ret==-1)?printf("FALSE\n"):printf("公共祖先为:%d\n",ret);
return 0;
}
运行结果:
公共祖先为:1
2、后序遍历二叉树的非递归算法
#include <iostream>
using namespace std;
#define MaxSize 100
#define ElemType char
typedef struct node { //树的结构体
ElemType val;
node* lchild;
node* rchild;
int tag;
}Node, *BiTree;
void CreateBiTree(BiTree& T) //要改变指针,C++可以把指针的引用传进来
{
ElemType ch;
cin >> ch; //cin会跳过空格,不读入空白字符,如\t,\n,所以按回车相当于结束
if (ch == '#')
T = NULL;
else
{
T = new Node; //前序构造二叉树
T->val = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PostOrder(BiTree t)
{
Node* stack[100]; //指针数组
int top=-1;
Node *p=t;
Node *x;
while(p||top!=-1)
{
if(p)
{
top++;
stack[top]=p;
p=p->lchild;
}
else
{
p=stack[top];
if(p->rchild&&p->rchild->tag==0) //右子树未被访问过
p=p->rchild;
else
{
p=stack[top]; //左右子树访问过,出栈,设置标识位1
top--;
cout<<p->val<<" ";
p->tag=1;
p=NULL;
}
}
}
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "非递归后序遍历:" << endl;
PostOrder(T);
cout << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
非递归后序遍历:
H I D J E B K F G C A
3、给出二叉树自下而上、自右向左的层次遍历算法
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#define MaxSize 100
#define ElemType char
typedef struct treenode { //树的结构体
ElemType val;
treenode* lchild;
treenode* rchild;
int tag;
}treenode, *BiTree;
void CreateBiTree(BiTree& T) //要改变指针,C++可以把指针的引用传进来
{
ElemType ch;
cin >> ch; //cin会跳过空格,不读入空白字符,如\t,\n,所以按回车相当于结束
if (ch == '#')
T = NULL;
else
{
T = new treenode; //前序构造二叉树
T->val = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
queue<treenode*> q; //声明变量q,为队列类型,队列中存储的元素类型为treenode*
stack<treenode*> s;
void LevelOrder(BiTree T) {
q.push(T);
while (!q.empty()) {
treenode* t = q.front();
q.pop();
s.push(t);
if (t->lchild)
q.push(t->lchild);
if (t->rchild)
q.push(t->rchild);
}
while (!s.empty()) {
treenode* x = s.top();
s.pop();
cout << x->val << " ";
}
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "层次遍历:" << endl;
LevelOrder(T);
cout << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
层次遍历:
K J I H G F E D C B A
4、假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度
queue<treenode*> q;
//非递归
int GetHeight(BiTree T) {
if (!T)
return 0;
int height = 0;
treenode* front, * last;
last = front = T;
q.push(T);
while (!q.empty()) {
front = q.front();
if (front->lchild)
q.push(front->lchild);
if (front->rchild)
q.push(front->rchild);
if (front == last) {
height++;
last = q.back(); //将队列最后一个元素赋值给last
}
q.pop();
}
return height;
}
//递归
int GetHeight1(BiTree T) {
if (T == NULL)
return 0;
int Lh = GetHeight(T->lchild);
int Lr = GetHeight(T->rchild);
return Lh > Lr ? (Lh + 1) : (Lr + 1); //高度是指从根节点到最远叶子节点的路径上经过的节点数。另外,空树的高度定义为0。
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "树的高度为(非递归):" << GetHeight(T) << endl;
cout << "树的高度为(递归):" << GetHeight1(T) << endl;
cout << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
树的高度为(非递归):4
树的高度为(递归):4
5、根据中序和前序构建二叉树的二叉链表
//设一棵二又树中各结点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个
//维数组A[1…n]和B[1…n]中, 试编写算法建立该二叉树的二叉链表
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
BiTree BuildTree(string A, string B, int l1, int h1, int l2, int h2) {
// A = "ABDHIEJCFKG", B = "HDIBEJAFKCG";
BiTree root = new treenode;
root->val = A[l1];
int i;
for (i = l2; B[i] != root->val; i++);
int llen = i - l2;
int rlen = h2 - i;
if (llen)
root->lchild = BuildTree(A, B, l1 + 1, l1 + llen, l2, l2 + llen - 1);
else
root->lchild = NULL;
if (rlen)
root->rchild = BuildTree(A, B, h1 - rlen + 1, h1, h2 - rlen + 1, h2);
else
root->rchild = NULL;
return root;
}
int main()
{
BiTree T;
string Pre = "ABDHIEJCFKG", In = "HDIBEJAFKCG"; //定义一个字符串
T = BuildTree(Pre, In, 0, Pre.size() - 1, 0, In.size() - 1); //C++ 中,std::string 类型有一个成员函数 size(),用于返回字符串的长度(即字符的个数)。
cout << "后序遍历验证:" << endl;
PostOrder(T);
cout << endl;
return 0;
}
运行结果:
后序遍历验证:
H I D J E B K F G C A
6、判断是否是完全二叉树
//二又树按二叉链表形式存储, 写一个判别给定二叉树是否是完全二叉树的算法
void InOrder(BiTree T) {
if (T != NULL) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
queue<treenode*> q;
stack<treenode*> s;
bool Judge_Comtrees(BiTree T) {
q.push(T);
while (!q.empty()) {
treenode* t = q.front();
q.pop();
if (t) {
q.push(t->lchild);
q.push(t->rchild);
}
else {
while (!q.empty()) {
treenode* x = q.front();
q.pop();
if (x)
return false;
}
}
}
return true;
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input(完全二叉树): A B D H # # I # # E G # # K # # C F L # # M # # G N # # #
// input(普通二叉树): A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
if (Judge_Comtrees(T))
cout << "是完全二叉树" << endl;
else
cout << "不是完全二叉树" << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E G # # K # # C F L # # M # # G N # # #
中序遍历:
H D I B G E K A L F M C N G
是完全二叉树
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
不是完全二叉树
7、求二叉树所有双分支结点的个数
//假设二叉树采用二叉链表存储结构存储,试设计一个算法,
//计算一棵给定二叉树的所有双分支结点个数
//方法一
int num(tree t)
{
if(!t) return 0;
else if(t->lchild&&t->rchild) return num(t->lchild)+num(t->rchild)+1;
else return num(t->lchild)+num(t->rchild);
}
//方法二
int num = 0;
int Get_DouNum(BiTree T) {
if (T) {
Get_DouNum(T->lchild);
if (T->lchild && T->rchild) //只用一个if语句,确保每个结点计数一次
num++;
Get_DouNum(T->rchild);
}
return num;
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
cout << "双结点的个数为:" << Get_DouNum(T) << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
双结点的个数为:4
8、交换左右子树
//设树B是一棵采用链式结构存储的二叉树, 编写一个把树B中所有结点的左、右子树进行交换的函数
void SwapNode(BiTree &T) {
if (T) {
SwapNode(T->lchild);
SwapNode(T->rchild);
BiTree t=T->lchild;
T->lchild=T->rchild;
T->rchild=t;
}
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
cout << "交换完后(中序遍历):" << endl;
SwapNode(T);
InOrder(T);
cout << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
交换完后(中序遍历):
G C K F A J E B I D H
9、求先序遍历中第k个结点的值
//假设二叉树采用二叉链存储结构存储, 设计一个算法, 求先序遍历序列中第k(1≤k≤二叉树中结点个数)个结点的值
int Count = 1;
void GetNumK(BiTree& T,int K) {
if (T) {
if (Count == K)
cout << T->val;
Count++;
GetNumK(T->lchild,K);
GetNumK(T->rchild,K);
}
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
int k = 4;
cout << "先序遍历序列中第" << k << "个结点的值为" << endl;
GetNumK(T,k);
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
先序遍历序列中第4个结点的值为
H
10、找到元素值为x的结点,删去以它为根的子树
//已知二叉树以二叉链表存储, 编写算法完成:对于树中每个元素值为x的结点, 删去以它为根的子树, 并释放相应的空间
//递归释放结点
void Release(tree &t)
{
if(!t) return;
Release(t->lchild);
Release(t->rchild);
free(t);
}
//前序遍历
void delete_x(tree &T,char x)
{
if(T==NULL) return;
if(T->data==x)
{
Release(T);
T=NULL; //手动去设置结点为NULL 物理内存的一个释放
}
if(T!=NULL)
{
delete_x(T->lchild,x);
delete_x(T->rchild,x);
}
}
int main()
{
BiTree T;
cout << "请输入先序遍历顺序下各个结点的值,'#'表示没有结点:" << endl;
// input: A B D H # # I # # E # J # # C F # K # # G # #
CreateBiTree(T);
cout << "中序遍历:" << endl;
InOrder(T);
cout << endl;
char X = 'D';
cout << "删除" << X << "后中序遍历为" << endl;
delete_x(T, X);
InOrder(T);
cout << endl;
return 0;
}
运行结果:
请输入先序遍历顺序下各个结点的值,'#'表示没有结点:
A B D H # # I # # E # J # # C F # K # # G # #
中序遍历:
H D I B E J A F K C G
删除D后中序遍历为
B E J A F K C G
11、打印值为x的结点的所有祖先
//在二又树中查找值为x的结点, 试编写算法(用C语言)打印值为x的结点的所有祖先, 假设值为x的结点不多于一个。
#include <iostream>
using namespace std;
typedef struct treenode{
char data;
treenode* lchild,* rchild;
}treenode,*tree;
typedef struct{
treenode* p;
int tag;
}stack;
void createtree(tree& t){
char ch;
cin>>ch;
if(ch=='#') t=NULL;
else{
t=(treenode*)malloc(sizeof(treenode));
t->data=ch;
createtree(t->lchild);
createtree(t->rchild);
}
}
void search(tree t,char x){
stack s[20];
int top=0;
while(t!=NULL||top>0){
while(t!=NULL&&t->data!=x){
s[++top].p=t;
s[top].tag=0; //访问过左孩子
t=t->lchild;
}
if(t!=NULL&&t->data==x){
cout<<"所有祖先结点为: "<<endl;
for(int i=1;i<=top;i++)
cout<<s[i].p->data<<" ";
break;
}
while(top!=0&&s[top].tag==1){
top--;
}
if(top!=0){
s[top].tag=1;
t=s[top].p->rchild;
}
}
}
int main(){
tree t;
createtree(t);
search(t,'D');
return 0;
}
/*
A
B C
D E F G
*/
//ABD##E##CF##G##
运行结果:
所有祖先结点为:
A B
12、找出最近公共祖先结点
//设一棵二叉树的结点结构为(LLINK, INFO, RLINK), ROOT为指向该二叉树根结点的指针, p和q分别为指向该二叉树中任意两个结点的指针, 试编写算法ANCESTOR(ROOT, p, q, r), 找到p和q的最近公共祖先结点r。
#include <iostream>
using namespace std;
typedef struct treenode{
char data;
treenode* lchild,* rchild;
}treenode,*tree;
typedef struct{
treenode* p;
int tag;
}stack;
void createtree(tree& t){
char ch;
cin>>ch;
if(ch=='#') t=NULL;
else{
t=(treenode*)malloc(sizeof(treenode));
t->data=ch;
createtree(t->lchild);
createtree(t->rchild);
}
}
tree ancestor(tree t,tree p,tree q){
stack s1[20];
stack s2[20];
int top1=0,top2; //栈初始化
treenode* bt=t; //遍历指针
while(bt!=NULL||top1>0){
while(bt!=NULL){ //入栈
s1[++top1].p=bt;
s1[top1].tag=0;
bt=bt->lchild;
}
while(top1!=0&&s1[top1].tag==1){
if(s1[top1].p==p){
for(int i=1;i<=top1;i++){ //把值复制到另一个栈中
s2[i]=s1[i];
}
top2=top1;
}
if(s1[top1].p==q){ //从上向下比较
for(int i=top1;i>0;i--){
for(int j=top2;j>0;j--){
if(s2[j].p==s1[i].p)
return s1[i].p;
}
}
}
top1--;
}
if (top1!=0){
s1[top1].tag=1;
bt=s1[top1].p->rchild;
}
}
return NULL;
}
int main(){
tree t;
createtree(t);
tree p=t->lchild->rchild;
tree q=t->rchild->lchild;
cout<<ancestor(t,p,q)->data<<endl;
return 0;
}
/*
A
B C
D E F G
*/
//ABD##E##CF##G##
运行结果:
ABD##E##CF##G##
A
13、求非空二叉树的宽度
层次遍历
//假设二叉树采用二叉链表存储结构, 设计一个算法, 求非空二叉树b的宽度(即具有结点数最多的那一层的结点个数
#include <iostream>
using namespace std;
typedef struct treenode{
char data;
treenode* lchild,* rchild;
}treenode,*tree;
typedef struct{ //队列结构体
tree data[20];
int level[20];
int f,r;
}queue;
void createtree(tree& t){
char ch;
cin>>ch;
if(ch=='#') t=NULL;
else{
t=(treenode*)malloc(sizeof(treenode));
t->data=ch;
createtree(t->lchild);
createtree(t->rchild);
}
}
int BTWidth(tree t){
queue q;
tree p; //指向出队结点
int k; //保存出队结点层次
q.f=-1;
q.r=-1; //初始化
q.r++;
q.data[q.r]=t;
q.level[q.r]=1; //根入队,层数为1
while(q.f<q.r){
q.f++;
p=q.data[q.f];
k=q.level[q.f]; //队头出队,左右孩子入队
if(p->lchild){
q.r++;
q.data[q.r]=p->lchild;
q.level[q.r]=k+1;
}
if(p->rchild){
q.r++;
q.data[q.r]=p->rchild;
q.level[q.r]=k+1;
}
}
int max=0,i=0,n;
k=1;
while(i<=q.r){ //计算最大层数
n=0;
while(i<=q.r&&q.level[i]==k){
n++;
i++;
}
k=q.level[i];
if(n>max){
max=n;
}
}
return max;
}
int main(){
tree t;
createtree(t);
cout<<BTWidth(t)<<endl;
return 0;
}
/*
A
B C
D E F G
*/
//ABD##E##CF##G##
运行结果:
ABD##E##CF##G##
4
14、满二叉树已知先序,求后序序列
//设有一棵满二叉树(所有结点值均不同), 已知其先序序列为pre, 设计一个算法求其后序序列post
void PrePost(char pre[],int l1,int h1,char post[],int l2,int h2)
{
int half;//左右子树临界
if(l1<=h1)//递归条件
{
post[h2]=pre[l1];
half=(h1-l1)/2;
PrePost(pre,l1+1,l1+half,post,l2,l2+half-1);
PrePost(pre,l1+half+1,h1,post,l2+half,h2-1);
}
}
int main()
{
char pre[8]="ABDECFG",post[8];
PrePost(pre,0,6,post,0,6);
for(int i=0;i<7;i++)
{
cout<<post[i]<<" ";
}
return 0;
}
/*
A
B C
D E F G
*/
//ABD##E##CF##G##
运行结果:
D E B F G C A
15、将二叉树叶结点连成单链表
//设计一个算法将二叉树的叶结点按从左到右的顺序连成一个单链表, 表头指针为head,二叉树按二叉链表方式存储, 链接时用叶结点的右指针域来存放单链表指针
tree head=(treenode*)malloc(sizeof(treenode)),pre=NULL; //全局变量
tree InOrder(tree t){
if(t){
InOrder(t->lchild);
if(t->lchild==NULL&&t->rchild==NULL){
if(pre==NULL){
head=t;
pre=t;
}
else{
pre->rchild=t;
pre=t;
}
}
InOrder(t->rchild);
}
return head;
}
int main()
{
tree t;
createtree(t);
InOrder(t);
while(head)
{
cout<<head->data<<" ";
head=head->rchild;
}
return 0;
}
/*
A
B C
D E F G
ABD##E##CF##G##
*/
运行结果:
ABD##E##CF##G##
D E F G
16、判断二叉树是否相似
//试设计判断两棵二叉树是否相似的算法。所谓二叉树T1和T2相似, 指的是T1和T2都是空的二叉树或都只有一个根结点; 或T1的左子树和T2的左子树是相似的, 且T1的右子树和T2的右子树是相似的
int similar(tree t1,tree t2)
{
int left,right;
if(t1==NULL&&t2==NULL) return 1;
else if(t1==NULL||t2==NULL) return 0;
else
{
left=similar(t1->lchild,t2->lchild);
right=similar(t1->rchild,t2->rchild);
return (left&&right);
}
}
int main()
{
tree t1,t2;
createtree(t1);
createtree(t2);
cout<<similar(t1,t2)<<endl;
return 0;
}
/*
A
B
AB###
C
E
C#E##
*/
运行结果:
AB###
C#E##
0
17、在中序线索二叉树里查找指定结点在后序的前驱
//写出在中序线索二叉树里查找指定结点在后序的前驱结点的算法。
typedef struct treenode{
char data;
treenode* lchild,* rchild;
int ltag,rtag; //增加标志位
}treenode,*tree;
tree pre; //遍历二叉树的保留的前驱结点
void InPre(tree &t) //中序线索化
{
if(t)
{
InPre(t->lchild); //向左延伸 找叶子结点
if(t->lchild==NULL)
{
t->ltag=1; //ltag=1为前驱,ltag=0为左孩子
t->lchild=pre; //左孩子指针指向前驱结点
}
else t->ltag=0;
if(pre!=NULL&&pre->rchild==NULL) //当前结点无右孩子
{
pre->rtag=1;
pre->rchild=t;
}
pre=t; //更新前驱指针
InPre(t->rchild);
}
}
tree Inpostpre(tree t,treenode *p) //找后继的前驱结点
{
treenode *q; //结果指针
if(p->rtag==0) q=p->rchild; //有右孩子 结果就是右孩子
else if(p->ltag==0) q=p->lchild; //有左孩子 结果就是左孩子
else if(p->lchild==NULL) q=NULL; //该结点的前驱为空 即为中序第一个结点 也是后序第一个 则无后序前驱
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()
{
tree t;
createtree(t);
InPre(t);
cout<<Inpostpre(t,t->rchild)->data<<endl;
return 0;
}
/*
A
B C
D E F G
ABD##E##CF##G##
*/
运行结果:
ABD##E##CF##G##
G
18、带权路径长度
//〖2014统考真题】二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T, 采用二又链表存储, 结点结构为
//left
//weight
//right
//其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,
//请设计求T的WPL的算法。
typedef struct treenode{
char weight;
treenode* lchild,* rchild;
}treenode,*tree;
int wplpre(tree t,int deep) //采用先序遍历
{
static int ans=0; //静态变量 存储结果值在函数末尾返回
if(t->lchild==NULL&&t->rchild==NULL) //若是叶子结点 进行累加
ans+=(deep*((t->weight)-'0'));
if(t->lchild!=NULL) //递归遍历左子树找叶子结点,同时层数+1
wplpre(t->lchild,deep+1);
if(t->rchild!=NULL)
wplpre(t->rchild,deep+1);//递归遍历左子树找叶子结点同时层数+1
return ans;
}
int main()
{
tree t;
createtree(t);
cout<<wplpre(t,0)<<endl;
return 0;
}
/*
1
2 3
4 5 6 7
124##5##36##7##
ans=(4+5+6+7)*2=44
*/
运行结果:
124##5##36##7##
44
19、求中缀表达式
//表达式树转化成中缀表达式
void bitreetoe(tree t,int deep)
{
if(t==NULL) return;
else if(t->lchild==NULL&&t->rchild==NULL) //只有一个结点或叶子结点 输出
{
cout<<t->data;
}
else
{
if(deep>1) cout<<"("; //层数大于1,且有孩子
bitreetoe(t->lchild,deep+1); //中序遍历
cout<<t->data;
bitreetoe(t->rchild,deep+1);
if(deep>1) cout<<")"; //层数大于1,且左右孩子已访问过
}
}
int main()
{
tree t;
createtree(t);
bitreetoe(t,1);
return 0;
}
/*
*
+ *
a b c -
*+a##b##*c##-#d##
+
* -
a b -
c d
+*a##b##-#-c##d##
+
a b
+a##b##
*/
运行结果:
+a##b##c##-#d##
(a+b)(c*(-d))
+a##b##-#-c##d##
(ab)+(-(c-d))
+a##b##
a+b //根结点层数为1,不加左右括号
20、以孩子兄弟表示法存储的森林的叶子结点数
typedef struct treenode{
char data;
struct treenode *child,*rbro;
}treenode,*tree;
int leaves(tree t)
{
if(t==NULL) return 0; //空结点 返回0
if(t->child==NULL) return 1+leaves(t->rbro); //孩子域为空即左孩子为空 该结点为叶子结点 结果加1还要加上右兄弟子树的叶子结点数
else return leaves(t->child)+leaves(t->rbro); //有孩子 结果为左孩子子树和右兄弟子树的叶子结点个数之和
}
int main()
{
tree t;
createtree(t);
cout<<leaves(t)<<endl;
return 0;
}
/*
A
B F
D C G
\
E
ABD#E##C##FG###
*/
运行结果:
ABD#E##C##FG###
4
21、孩子兄弟表示法递归求树深度
//以孩子兄弟链表为存储结构,请设计递归算法求树的深度
typedef struct treenode{
char data;
struct treenode *child,*rbro;
}treenode,*tree;
int height(tree t)
{
if(t==NULL) return 0; //空树 返回0
else
{
int l=height(t->child); //递归计算左孩子子树高度
int r=height(t->rbro); //递归计算右兄弟子树高度
return max(l+1,r);
}
}
int main()
{
tree t;
createtree(t);
cout<<height(t)<<endl;
return 0;
}
/*
A
B
D C
E F
ABD#E##CF####
*/
运行结果:
ABD#E##C##FG###
4