二叉树研讨题(线索二叉树、字符串构建二叉树、复制二叉树、二叉树判同)

文章详细描述了如何通过前序序列构建二叉树,进行线索化处理,输出中序遍历序列,以及比较两棵树结构是否相同的方法。
摘要由CSDN通过智能技术生成

目录

线索二叉树(输入前序,输出中序并销毁二叉树)

用字符串构建一棵二叉树(输入扩展二叉树的前序序列,输出中序)

设计算法复制一棵二叉树(给定前序,复制,输出中序)

判断两棵二叉树是否结构相同(给定前序,构建二棵二叉树,判断是否相同)


线索二叉树(输入前序,输出中序并销毁二叉树)

【问题描述】

建立线索链表,实质上就是将二叉链表中的空指针改为指向前驱或后继的线索,而前驱或后继的信息只有在遍历该二叉树时才能得到。给定扩展二叉树的前序序列,构建二叉树。然后为这棵二叉树建立中序线索链表,并利用线索链表输出中序遍历结果。

【输入形式】

输入扩展二叉树的前序序列。

【输出形式】

利用线索二叉树输出树的中序遍历序列,并且按照中序顺序输出销毁线索二叉树的过程。

【样例输入】

abd#g###ce##f##  

【样例输出】

Inorder:dgbaecf

Inorder finished. Calling destructer...

delete d

delete g

delete b

delete a

delete e

delete c

delete f

【题目要求】

要求创建二叉树,然后建立线索链表

【题解代码】

#include<iostream>
#include<stdio.h>
using  namespace  std;

struct  ThreadNode
{
    char  data;
    ThreadNode    *lchild,  *rchild;
    int  ltag,  rtag;
};

class  ThreadBiTree
{
private:
    ThreadNode  *root;//指向线索链表的头指针
public:

    ThreadBiTree()  //构造函数,建立中序线索链表
    {
        root = NULL;
        root = creat(root);
        inThread(root);
    }
    ~ThreadBiTree();            //析构函数,释放各结点的存储空间
    ThreadNode  *next(ThreadNode  *p);    //查找p的后继
    void  inOrder();                                              //中序遍历线索链表
private:
    ThreadNode  *creat(ThreadNode  *bt);
    void  destroy(ThreadNode  *p);  //线索化,由构造函数调用

    void inThread(ThreadNode *p); //线索化,由构造函数调用



};

//create函数创建二叉树
ThreadNode *ThreadBiTree::creat(ThreadNode *bt)
{
//在此处填写创建线索二叉树的代码
    char ch;
    cin >> ch;
    if (ch == '#')
        bt = NULL;
    else
    {
        bt = new ThreadNode;
        bt->data = ch;
        bt->ltag = 0;
        bt->rtag = 0;
        bt->lchild = creat(bt->lchild);
        bt->rchild = creat(bt->rchild);
    }
    return bt;

}
//实现二叉树线索化,这个函数由构造函数调用
void ThreadBiTree::inThread(ThreadNode *p)
{
//在此处填写建立二叉树线索化的代码,注意,这个函数跟其他函数不同,它 的函数头可以修改,注意检查大括号是否匹配
    static ThreadNode* pre = NULL;//保存上一次递归遍历的结果
    if (p == NULL)
        return;
    inThread(p->lchild);
    if (p->lchild == NULL)
    {
        p->ltag = 1;
        p->lchild = pre;
    }
    if (pre != NULL && pre->rchild == NULL)
    {
        pre->rtag = 1;
        pre->rchild = p;
    }
    pre = p;
    inThread(p->rchild);
}

//查找p的后继
ThreadNode* ThreadBiTree::next(ThreadNode *p)
{
    //在此处填写next函数的代码
    ThreadNode* q;
    if (p->rtag == 1)
        q = p->rchild;
    else
    {
        q = p->rchild;
        while (q->ltag == 0)
            q = q->lchild;
    }
    return q;
}

//中序遍历线索链表
void ThreadBiTree::inOrder()
{
    //在此处填写中序遍历线索二叉树的代码
    if (root == NULL)
        return;
    ThreadNode* p = root;
    while (p->ltag == 0)
    {
        p = p->lchild;
    }
    cout << p->data;
    while (p ->rchild!= NULL)
    {
        p = next(p);
        cout << p->data;
    }
}

//析构函数,释放各结点的存储空间
//这个要注意,和普通的析构函数不一样   
ThreadBiTree::~ThreadBiTree()                             //卡了好久
{
    //在此处填写销毁线索二叉树的代码
    ThreadNode *p,*q;
    p=root;
    while(p->ltag==0)
    {
        p=p->lchild;
    }
    q=p;
    while(p->rchild!=NULL)
    {
        cout<<"delete "<<p->data<<endl;
        p=next(p);
        delete q;
        q=p;
    }
    cout<<"delete "<<p->data<<endl;
    delete p;
}


int  main()
{
    ThreadBiTree  tree;
    cout  <<  "Inorder:";
    tree.inOrder();
    cout  <<  endl  <<  "Inorder  finished.  Calling  destructer..."<<endl;
    return  0;
}
                                                        //好累,不写每一句的注释了

用字符串构建一棵二叉树(输入扩展二叉树的前序序列,输出中序)

【问题描述】

输入一组扩展二叉树的前序序列存入字符串,然后构建一棵二叉树。输出这棵二叉树的中序遍历序列。

【输入形式】

输入扩展二叉树的前序序列。

【输出形式】

输出二叉树的中序遍历序列。

【样例输入】

ab##cd##e##

【样例输出】

badce

【题目要求】

要求在递归函数中传入保存扩展二叉树前序序列的字符串。

【题解代码】

/**用前序字符串创建树*/
#include<iostream>
#include<stdio.h>
#include<string.h>
const  int  MAX=1000;
using  namespace  std;
struct  BiNode
{
    char  data;//数据域
    BiNode    *lchild,  *rchild;//左右儿子指针
};

class  BiTree
{
private:
    BiNode  *root;                            //指向根结点的头指针

public:
    BiTree()
    {
        root  =  NULL;                        //无参构造函数,创建空的二叉树
    }
    BiTree(char  str[])
    {
        int  index  =  0;
        root  =  creat(root,str,index);    //有参构造函数,利用已有的串构建二叉树
    }
    ~BiTree()
    {
        release(root);
    }
    BiNode*  getRoot()
    {
        return  root;
    }
    void  setRoot(BiNode*  bt)
    {
        root  =  bt;
    }
    BiNode*  creat(BiNode  *bt,  char  str[],  int  &index);  //构造函数调用

    void  release(BiNode  *bt);    //析构函数调用,释放树的存储空间
    void  inOrder(BiNode  *bt);    //中序遍历函数调用
};

/**利用已有的字符串前序构建二叉树*/
BiNode  *BiTree::creat(BiNode  *bt,  char  str[],  int  &index)
{
    if(str[index]=='#'||str[index]=='\0')
    {
        bt=NULL;
        if(str[index]=='\0')
        {
            index--;
        }
    }
    else
    {
        bt=new BiNode;
        bt->data=str[index];
        index++;
        bt->lchild=creat(bt->lchild,str,index);
        index++;
        bt->rchild=creat(bt->rchild,str,index);
    }
    return bt;
    //以下注释掉的是一个差不多的写法
    /*
    if(str[index]=='\0'){
    bt=NULL;}
    else if(str[index]=='#'){
    index++;
    bt=NULL;}
    else{
     bt=new BiNode;
            bt->data=str[index];
            index++;
     bt->lchild=creat(bt->lchild,str,index);
            bt->rchild=creat(bt->rchild,str,index);
        }
    return bt;
    */
}

/**后序释放二叉树节点*/
void  BiTree::release(BiNode  *bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        release(bt->lchild);
        release(bt->rchild);
    }
}

/**中序遍历*/
void  BiTree::inOrder(BiNode  *  bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        inOrder(bt->lchild);
        cout<<bt->data;
        inOrder(bt->rchild);
    }
}

int  main()
{
    //cout<<"输入前序字符串:";
    char  str[MAX];
    cin  >>  str;
    BiTree  tree(str);

    tree.inOrder(tree.getRoot());

    return  0;
}

设计算法复制一棵二叉树(给定前序,复制,输出中序)

【问题描述】

编写代码复制一棵二叉树。首先给定一组扩展二叉树的前序序列,构建一棵二叉树。然后编写代码复制这棵二叉树,并输出目标二叉树的中序遍历序列。

【输入形式】

输入扩展二叉树的前序序列。

【输出形式】

分两行输出两棵二叉树的中序遍历序列

【样例输入】

ab##cd##e##

【样例输出】

Copy Finished!

InOrder:badce

【题目要求】

要求创建名为source的二叉树对象,输入扩展二叉树的前序序列,构建一棵二叉树;然后创建名为dest的空树(输入#,则创建空树);然后在指定的函数框架中填写二叉树的复制代码,最后目标二叉树进行中序遍历。

【题解代码】

/**用复制一棵树,用字符串构建树*/
#include<iostream>
#include<stdio.h>
#include<string.h>
const  int  MAX=1000;
using  namespace  std;
struct  BiNode
{
    char  data;//数据域
    BiNode    *lchild,  *rchild;//左右儿子指针
};

class  BiTree
{
private:
    BiNode  *root;                            //指向根结点的头指针

public:
    BiTree()                //无参构造函数,创建空的二叉树
    {
        root  =  NULL;
    }
    BiTree(char  str[])        //有参构造函数,利用已有的串构建二叉树
    {
        int  index  =  0;
        root  =  creat(root,str,index);
    }
    ~BiTree()
    {
        release(root);
    }
    BiNode*  getRoot()                         //getter
    {
        return  root;
    }
    void  setRoot(BiNode*  bt)           //setter
    {
        root  =  bt;
    }
    void  inOrder()
    {
        inOrder(root);
    }

private:
    BiNode*  creat(BiNode  *bt,  char  str[],  int  &index);  //构造函数调用
    void  release(BiNode  *bt);    //析构函数调用,释放树的存储空间
    void  inOrder(BiNode  *bt);    //中序遍历函数调用
};

/**利用已有的字符串前序构建二叉树*/
BiNode  *BiTree::creat(BiNode  *bt,  char  str[],  int  &index)   //跟上一个题一样
{
    if(str[index]=='#'||str[index]=='\0')
    {
        bt=NULL;
        if(str[index]=='\0')
        {
            index--;
        }
    }
    else
    {
        bt=new BiNode;
        bt->data=str[index];
        index++;
        bt->lchild=creat(bt->lchild,str,index);
        index++;
        bt->rchild=creat(bt->rchild,str,index);
    }
    return bt;
}

/**后序释放二叉树节点*/
void  BiTree::release(BiNode  *bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        release(bt->lchild);
        release(bt->rchild);
    }
}

/**中序遍历*/
void  BiTree::inOrder(BiNode  *  bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        inOrder(bt->lchild);
        cout<<bt->data;
        inOrder(bt->rchild);
    }
}

/*//------------分割线  普通函数------------------//*/

/*  复制一棵树
//  参数说明:传入源树和目的树的根节点指针
      注意,这里dest这个指针的值需要传出去,因此采用引用&,否则不能传回。

*/
void  copyTree(BiNode  *source,  BiNode*  &dest)
{
    if (source == NULL)
    {
        dest = NULL;
        return;
    }
    dest = new BiNode;
    dest->data = source->data;
    copyTree(source->lchild, dest->lchild);
    copyTree(source->rchild, dest->rchild);
}

int  main()
{
    char  str[MAX];
    BiNode  *dest=NULL,*source=NULL;    //指向两棵树的根节点的指针

//        cout  <<  "请输入一棵树:(形式为:ABD##E##CF###)"<<endl;
    cin  >>  str;
    BiTree  sourceTree(str);
    source  =  sourceTree.getRoot();

    BiTree  destTree;      //创建一棵空树

    copyTree(source,dest);

    destTree.setRoot(dest);        //把复制后的树的指针存储到destTree类中

    cout  <<"Copy  Finished!"<<endl;
    cout  <<"InOrder:";
    destTree.inOrder();

    return  0;
}

判断两棵二叉树是否结构相同(给定前序,构建二棵二叉树,判断是否相同)

【问题描述】

给定两组扩展二叉树的前序序列,构建两棵二叉树。判断这两棵二叉树结构是否相同?

【输入形式】

分两行分别输入两棵扩展二叉树的前序序列。

【输出形式】

如果两个二叉树结构相同,输出“Same structure.”;如果两个二叉树结构不相同,输出“Different structure.”

【样例输入】

ab##cd##e##

AF##DE##K##

【样例输出】

Same structure.

【题目要求】

要求创建二叉树,然后用函数判断两棵二叉树是否相同。

【题解代码】

/**字符串建树判断两棵二叉树是否结构相同*/
#include<iostream>
#include<stdio.h>
using  namespace  std;
struct  BiNode
{
    char  data;//数据域
    BiNode    *lchild,  *rchild;//左右儿子指针
};

class  BiTree
{
private:
    BiNode  *root;                            //指向根结点的头指针

public:
    BiTree()
    {
        root  =  NULL;
        root  =  creat(root);//调函数构建二叉树
    }
    ~BiTree()
    {
        release(root);
    }
    BiNode  *  getRoot()
    {
        return  root;
    }
    BiNode  *creat(BiNode  *bt);  //构造函数调用
    void  release(BiNode  *bt);    //析构函数调用,释放树的存储空间

};
/**前序构建二叉树*/
BiNode  *BiTree::creat(BiNode  *bt)
{
    char  ch;
    cin>>ch;
    if(ch=='#')
        bt  =  NULL;
    else
    {
        bt  =  new  BiNode;
        bt->data  =  ch;
        bt->lchild  =  creat(bt->lchild);
        bt->rchild  =  creat(bt->rchild);
    }
    return  bt;
}
/**后序释放二叉树节点*/
void  BiTree::release(BiNode  *bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        release(bt->lchild);
        release(bt->rchild);
    }
}
/*
    isSameStructure函数
    功能:接收两棵树的根节点指针,用来判断两棵树的结构是否相同
*/
bool  isSameStructure(BiNode  *  bt1,  BiNode  *  bt2)
{

    if (bt1 == NULL && bt2 == NULL)
    {
        return true;
    }
    if (bt1 == NULL || bt2 == NULL)
    {
        return false;
    }
    return isSameStructure(bt1->lchild, bt2->lchild) && isSameStructure(bt1->rchild, bt2->rchild);  //这里分开写更好看
    //bool left=isSameStructure(bt1->lchild, bt2->lchild) ;
    //bool right=isSameStructure(bt1->rchild, bt2->rchild);
    //return (left&&right);
}

int  main()
{
    BiNode  *root1,*root2;

    BiTree  tree1;
    root1  =  tree1.getRoot();
    BiTree  tree2;
    root2  =  tree2.getRoot();

    if(isSameStructure(root1,root2))
    {
        cout  <<  "Same  structure."<<  endl;
    }
    else
    {
        cout  <<  "Different  structure."  <<endl;
    }

    return  0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值