数据结构实验+理解1 基于c++的二叉树函数实现

        本实验设计为类外函数
        二叉树的函数设计精髓是递归函数的调用,设计时函数的形参传入的是tree,实际上是传入了此树的根节点,因此“当前树的根节点”概念比较重要。在递归之后,替代形参的是以此根节点的左右孩子节点为根节点的左右子树,实现将树不断简化直到只有叶子。尤其注意在递归之后有些量的值不可以改变,下面会有所提及。

tips:
        节点声明中:普通节点为node,将树连根视为整体用tree。
        创建树的递归,可以理解为创建完当前根节点后,继续创建其左右子树。
        计算高度函数中, 可以理解为不断计算的是其左右子树的树高,比较后获得最大值。直到只有子叶,然后递归累积即可。
        中序遍历+求高度函数中,高度的求解实际上是层次数的求解,易得:层次数=总树高-此节点的树的高度+1得到层次数。注意此处的总树高需要提前求出作为形参,在函数中进行计算会随着递归改变总高度的值。
        中序调前k个函数中,和先序不同的是调处于中间位置的根节点时还需要判断溢出是否过k,原因是防止count在遍历完左子后已经到k了。
        计算总节点数中,空节点返回0,其他情况都是返回1(此节点)+左右子树的节点数目。
        复制树函数,按照先序先复制当前节点(视为根节点),再复制以此节点为根的左右子树。
        交换左右叶子函数中,当扫描判断到空指针,则按照前面的create函数,没有键入data,不可以交换其data域(使用->data),只可以交换其指针值。

//binary_tree_code_test
#include <iostream>
using namespace std;
typedef char elementtype;

typedef struct TreeNode {
    char data;//数据域
    TreeNode* Lchild;//左孩子
    TreeNode* Rchild;//右孩子
}*Tree,TreeNode;

//1.树的创建(先序)
void CreateTree(Tree &T){
    char x;cin>>x;
    if(x=='*'){T=NULL;return;}
    else{
        T=new TreeNode;
        T->data=x;
        CreateTree(T->Lchild);
        CreateTree(T->Rchild);
    }
}

//2.计算高度
int TreeDepth(const Tree &T){
    if(T==NULL)return 0;
    else{
        int i=TreeDepth(T->Lchild);
        int j=TreeDepth(T->Rchild);
        return i>j?i+1:j+1;
    }
}

//3.先序遍历
void Pre_Traversal(const Tree &T){
    if(T){
        cout<<T->data<<" ";
        Pre_Traversal(T->Lchild);
        Pre_Traversal(T->Rchild);
    }
}

//4.先序调前k个
void Pre_Traversal_k(const Tree &T,int k){
    static int count=1;
    if(T&&count<=k){
        cout<<T->data<<" ";count++;
        Pre_Traversal_k(T->Lchild,k);
        Pre_Traversal_k(T->Rchild,k);
    }
}

//5.中序遍历
void Ino_Traversal(const Tree &T){
    if(T){
        Ino_Traversal(T->Lchild);
        cout<<T->data<<" ";
        Ino_Traversal(T->Rchild);
    }
}

//6.中序遍历+求高度
void Ino_Traversal_h(const Tree &T,int height){
    if(T){
        Ino_Traversal_h(T->Lchild,height);
        cout<<T->data<<height-TreeDepth(T)+1<<" ";
        Ino_Traversal_h(T->Rchild,height);
    }
}

//7.中序调前k个
void Ino_Traversal_k(const Tree &T,int k){
    static int count=1;
    if(T&&count<=k){
        Ino_Traversal_k(T->Lchild,k);
        if(count<=k){cout<<T->data<<" ";count++;}
        Ino_Traversal_k(T->Rchild,k);
    }
}

//8.后序遍历
void Pos_Traversal(const Tree &T){
    if(T){
        Pos_Traversal(T->Lchild);
        Pos_Traversal(T->Rchild);
        cout<<T->data<<" ";
    }
}

//9.后序调前k个
void Pos_Traversal_k(const Tree &T,int k){
    static int count=1;;
    if(T&&count<=k){
        Pos_Traversal_k(T->Lchild,k);
        Pos_Traversal_k(T->Rchild,k);
        if(count<=k){cout<<T->data<<" ";count++;}
    }
}

//10.二叉树求度(叶子个数)
int TreeDegree(const Tree &T){
    int degree;
    if(T->Lchild&&T->Rchild)degree=2;
    else if((T->Lchild&&!T->Rchild)||(!T->Lchild&&T->Rchild))degree=1;
    else if(!T->Lchild&&!T->Rchild)degree=0;
    return degree;
}

//11.度为2的节点个数
int search_node1(const Tree &T){
    static int count=0;
    if(T){
        if(TreeDegree(T)==2)count++;
        search_node1(T->Lchild);
        search_node1(T->Rchild);
    }
    return count;
}

//12.叶子节点(度为0)个数
int search_node2(const Tree &T){
    static int count=0;
    if(T){
        if(TreeDegree(T)==0)count++;
        search_node2(T->Lchild);
        search_node2(T->Rchild);
    }
    return count;
}

//13.计算总节点数
int TreeNodeCount(const Tree &T){
    if(T==NULL)return 0;
    //else if(T->Lchild==NULL&&T->Rchild==NULL)return 1;
    else return TreeNodeCount(T->Lchild)+TreeNodeCount(T->Rchild)+1;
}

//14.复制树
void copy(const Tree &T,Tree &T1){
    if(T==NULL)T1=NULL;
    else{
        T1=T;
        copy(T->Lchild,T1->Lchild);
        copy(T->Rchild,T1->Rchild);
    }
}

//15.交换左右叶子
void exchange(Tree &T){
    if(T==NULL)return;
    else{
        TreeNode *T0=new TreeNode;
        T0=T->Lchild;
        T->Lchild=T->Rchild;
        T->Rchild=T0;
        exchange(T->Lchild);
        exchange(T->Rchild);
    }
}

//ABC*D**E*F**GH**I**
int main(){
    //创建二叉树
    cout<<"请按照先序输入一个二叉树,空指针用*表示:"<<endl;
    Tree T;CreateTree(T);
    //先序、中序、后续遍历
    cout<<"先序序列为:";Pre_Traversal(T);cout<<endl;
    cout<<"中序序列为:";Ino_Traversal(T);cout<<endl;
    cout<<"后序序列为:";Pos_Traversal(T);cout<<endl;
    //先序求前k个
    cout<<"请输入需要输出的节点个数k:";int k;cin>>k;
    cout<<"先序中前k个节点值为:";Pre_Traversal_k(T,k);cout<<endl;
    //求高度
    int height=TreeDepth(T);
    cout<<"树的高度为:"<<height<<endl;
    //求度为2个数、叶子个数
    cout<<"度为2的节点数目为:"<<search_node1(T);cout<<endl;
    cout<<"叶子节点数目为:"<<search_node2(T);cout<<endl;
    //计算总节点数
    cout<<"总节点数目为:"<<TreeNodeCount(T);cout<<endl;
    //中序遍历以及层次数
    cout<<"中序序列及各节点层次数为:";
    Ino_Traversal_h(T,height);cout<<endl;
    //将T复制给T1
    Tree T1;copy(T,T1);
    cout<<"由T复制而来的T1的先序序列为:";
    Pre_Traversal(T1);cout<<endl;
    //交换每个节点的左右孩子指针的值
    exchange(T);
    cout<<"交换后的二叉树先序序列为:";
    Pre_Traversal(T);cout<<endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值