刷题——二叉树C++

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##
(a
b)+(-(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

22、已知层次序列和结点度,构造树的孩子兄弟链表

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值