二叉树基本操作(完整版)

本文全面探讨了二叉树的基本操作,包括插入、删除、遍历等核心算法,旨在帮助读者深入理解数据结构中的二叉树概念。
摘要由CSDN通过智能技术生成
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>

//1二叉树中节点的的结构
struct treenode{
    struct treenode *lchild;
    struct treenode *rchild;
    struct treenode *father;
    int level;       //当前节点在第几层
    char value;      //节点的数据

}*root;

//2利用前序序列建立二叉树
//例如"ABC##DE#G##F###"
/*
//建树方法一:
treenode *creat1tree1(treenode *root)  
{                                  
    char ch;
    scanf("%c",&ch);
    if(ch == '#')
        root = NULL; //该节点为空
    else
    {
        root = new treenode;
        root->value = ch;
        creattree1(root->lchild);
        creattree1(root->rchild);
    }
    return root;
}*/
/*
int main()
{
    treenode *root;
    creattree1(root);
    return 0;
}
*/

//建树方法二:
int creattree2(treenode **root)  //指向指针的指针
{                              //在原数据上修改
    char data;
    scanf("%c",&data);
    if(data == '#')
    {
        (*root) = NULL;
        return 0;
    }
    else
    {
        (*root) = (treenode *)malloc(sizeof(treenode));
        (*root)->value = value;
        creattree2(&(*root)->lchild);
        creattree2(&(*root)->rchild);
    }
    return 0;
}
/*
int main()
{
    treenode *root;
    creattree2(&root);
    return 0;
}
*/


//3二叉树的遍历
//前序遍历二叉树
void preorder(treenode *T)
{
    if(T != NULL)
    {
        printf("%c ",T->value);
        preorder(T->lchild);
        preorder(T->rchild);
    }
}

//中序遍历二叉树
void inorder(treenode *T)
{
    if(T)
    {
        inorder(T->lchild);
        printf("%c ",T->value);
        inorder(T->rchild);
    }
}

//后序遍历二叉树
void postorder(treenode *T)
{
    if(T)
    {
        postorder(T->lchild);
        postorder(T->rchild);
        printf("%c ",T->value);
    }
}

//层次遍历二叉树
void levelorder(treenode *T)
{
    queue <treenode *> que;      //队列里的元素是rchild,lchild都是treenode *型
    que.push(T);
    while(!que.empty())
    {
        treenode *tmp = que.front();
        que.pop();
        printf("%c ", tmp->value);
        if(tmp->lchild != NULL)
            que.push(tmp->lchild);
        if(tmp->rchild != NULL)
            que.push(tmp->rchild);
    }
}

//4二叉树的计数
//计算二叉树的节点的个数(等于左子树+右子树+根节点)
int tree_size(treenode *T)
{
    if(T == NULL)
        return 0;
    else
        return 1 + tree_size(T->lchild) + tree_size(T->rchild);
}

//计算二叉树的高度(如果二叉树为空那么高度为0,否则高度就是取左右子树中高的那个+根节点)
int high(treenode *T)
{
    if(T == NULL)
        return 0;
    else
    {
        int left = high(T->lchild);
        int right = high(T->rchild);
        return left < right ? right + 1 : left + 1;
    }
}

//5二叉树的复制,返回复制后的根节点
treenode *copy(treenode *T)
{
    if(T == NULL)
      return NULL;
   treenode *tmp = new treenode;
   tmp->value = T->value;
   tmp->lchild = copy(T->lchild);
   tmp->rchild = copy(T->rchild);
   return tmp;
}

//6判断两棵二叉树是否相等
bool isequal(treenode *root1, treenode *root2)
{
    if(root1 == NULL && root2 == NULL)
        return true;
    if(root1 != NULL && root2 != NULL && root1->value == root2->value
       && isequal(root1->lchild, root2->lchild)
       && isequal(root2->rchild, root2->rchild)
       )
        return true;
    else
        return false;
}

//7二叉树的重建(节点编号从1~n)

//由前序序列和中序序列构造二叉树(len是序列的长度,pre为前序序列 mid为中序序列,返回根节点)
treenode *rebuildtree_1(char *pre, char *mid, int len)
{
    if(!len)
        return NULL;
    int index = 0;
    while(mid[index] !=  pre[0]) //在中序序列找根节点,前序序列第一个就是根
        index++;
    treenode *root = new treenode;
    root->value = pre[0];
    root->lchild = rebuildtree_1(pre, mid, index);
    root->rchild = rebuildtree_1(pre+index+1, mid+index+1, len-index-1);//右边len-index-1个元素是右子树的,扣除根节点
    return root;
}

//由中序和后序建立二叉树(len是序列的长度,mid是中序序列,post是后序序列,返回根节点)
//重点是利用好 中序序列
treenode *rebuildtree_2(char *mid, char *post, int len)
{
    if(len == 0)
        return NULL;
    int index = 0;                      //在中序序列中进行查找根节点,并用index记录在中序序列的索引
    while(mid[index] != post[len - 1])  //在中序序列中找根节点,后序序列的最后一个是根
        index++;
    treenode *root = new treenode; //造根节点
    root->value = post[len - 1];
    root->lchild = rebuildtree_2(mid, post, index);
    //index在中序序列中左边是左子树,index在后序序列中,左边也是左子树,
    //index-1就是左子后右再根中的根,最后传过去index成len,len-1就是左子树的根
    root->rchild = rebuildtree_2(mid+index+1, post+index, len-index-1);
    //根序号的右边是右子树,所以是从这mid+index+1开始找右子树的根,
    //index在中序序列中的右边是右子树,后序序列是先左子树再右子树最后根节点,
    //所以index在后序序列中左边也是左子树,右边是右子树和根,而index不一定是根的
    //位置了,所以从post[index]开始找右子树的根
    return root;
}
//通过返回重建的树的根节点把整个树复制回去,再利用先序,中序,后序遍历
    //中的一种就能输出重建好的树的先,中,后序列号了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值