二叉树基本操作

二叉树作为一种非常重要的数据结构,以下对二叉树的基本操作做一些示例
1、二叉树的定义

typedef char ElementType;  
  
typedef struct BiTreeNode  
{  
    ElementType data;  
    struct BiTreeNode* lchild;  
    struct BiTreeNode* rchild;  
}BiTreeNode, *BiTree;  

2、 二叉树的建立和销毁
(1)利用先序序列递归建立二叉树

//递归的建立一棵二叉树   
//输入为二叉树的先序序列   
void createBiTree(BiTree &T)  
{  
    char data;  
    data = getchar();  
    if(data == '#')  
    {  
        T = NULL;  
    }  
    else  
    {  
        T = new BiTreeNode;  
        T->data = data;  
        createBiTree(T->lchild);  
        createBiTree(T->rchild);  
    }  
}  

(2)利用广义表建立二叉树

//通过广义表建立二叉树   
void createBiTreeWithGenList(BiTree &T)  
{  
    stack<BiTree> s;//存放待输入孩子的结点   
    BiTree p = NULL;//用于生成新的结点  
    int k = 0;//记录期待的结点, k==1表示期待左孩子结点,k==2期待右孩子结点  
    char ch = getchar();  
      
    //处理根结点   
    if(ch!='#')  
    {  
        p = new BiTreeNode;  
        p->data = ch;  
        p->lchild = NULL;  
        p->rchild = NULL;  
        T = p;//根结点   
    }  
    while((ch=getchar())!='#')  
    {  
        switch(ch)  
        {  
            case '(':  
                s.push(p);//上一个生成的结点,即p入栈,p有孩子   
                k = 1;  //下一个插入的应为左孩子结点   
                break;  
            case ',':  
                k = 2;  //下一个插入的应为右孩子结点   
                break;  
            case ')':  
                s.pop();//结点完成孩子的输入,出栈   
                break;  
            default:  
                p = new BiTreeNode;  
                p->data = ch;  
                p->lchild = NULL;  
                p->rchild = NULL;  
                if(k==1)  
                    s.top()->lchild = p;  
                else   
                    s.top()->rchild = p;  
        }         
    }  
}  

(3)输出二叉树的广义表表示

//以广义表的方式输出二叉树  
void printBiTreeWithGenList(const BiTree&T)  
{  
    if(T)  
    {  
        cout<<T->data;  
        if(T->lchild ||T->rchild)//左右子树不全空   
        {  
            cout<<"(";  
            printBiTreeWithGenList(T->lchild);//递归输出左子树 ,可能为空   
            if(T->rchild)          
            {  
                cout<<",";  
                printBiTreeWithGenList(T->rchild);  
            }  
            cout<<")";  
        }  
    }  
}  

(4)二叉树的销毁

//递归销毁一棵二叉树  
void destroyBiTree(BiTree &T)  
{  
    if(T)  
    {  
        destroyBiTree(T->lchild);  
        destroyBiTree(T->rchild);  
        delete T;  
        T = NULL;  
    }  
}  

3 、二叉树的递归遍历
(1)先序递归遍历

//递归先序遍历二叉树   
void preOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        cout<<T->data<<" ";//输出根节点值   
        preOrderTraverse(T->lchild);//遍历左子树   
        preOrderTraverse(T->rchild);//遍历右子树   
    }  
}  

(2)中序递归遍历

//递归中序遍历二叉树  
void inOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        inOrderTraverse(T->lchild);//遍历左子树   
        cout<<T->data<<" ";//输出根节点值   
        inOrderTraverse(T->rchild);//遍历右子树   
    }  
}  

(3)后序递归遍历

//递归后序遍历二叉树  
void postOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        postOrderTraverse(T->lchild);//遍历左子树   
        postOrderTraverse(T->rchild);//遍历右子树   
        cout<<T->data<<" ";//输出根节点值   
    }   
}  

4 、二叉树的其他常见递归算法

(1)递归求树的深度(高度)

//递归求树的深度   
int depthOfBiTree(const BiTree &T)  
{  
    int ldepth;  
    int rdepth;  
      
    if(T==NULL)//空树   
        return 0;  
    ldepth = depthOfBiTree(T->lchild);  
    rdepth = depthOfBiTree(T->rchild);  
      
    return (ldepth>rdepth)?(ldepth+1):(rdepth+1);  
}  

(2)递归求树的叶子结点个数

//递归求二叉树的叶子结点个数  
int leafCountOfBiTree(const BiTree &T)  
{     
    if(T==NULL)  
        return 0;  
    if(T->lchild==NULL && T->rchild==NULL)  
        return 1;  
    return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);  
}  

(3)递归交换左右子女

//交换二叉树的左右子女  
void exchangeChild(BiTree &T)  
{  
    if(T)  
    {  
        BiTree temp = NULL;  
          
        if(T->lchild ||T->rchild)  
        {  
            temp = T->lchild;  
            T->lchild = T->rchild;  
            T->rchild = temp;  
            exchangeChild(T->lchild);  
            exchangeChild(T->rchild);  
        }  
    }  
}  

5、完整的测试代码




#include <cstdlib>  
#include <iostream>  
#include <stack>  
  
using namespace std;  
  
//二叉树定义   
typedef char ElementType;  
  
typedef struct BiTreeNode  
{  
    ElementType data;  
    struct BiTreeNode* lchild;  
    struct BiTreeNode* rchild;  
}BiTreeNode, *BiTree;  
  
  
//递归的建立一棵二叉树   
//输入为二叉树的先序序列   
void createBiTree(BiTree &T)  
{  
    char data;  
    data = getchar();  
    if(data == '#')  
    {  
        T = NULL;  
    }  
    else  
    {  
        T = new BiTreeNode;  
        T->data = data;  
        createBiTree(T->lchild);  
        createBiTree(T->rchild);  
    }  
}  
  
//通过广义表建立二叉树   
void createBiTreeWithGenList(BiTree &T)  
{  
    stack<BiTree> s;//存放待输入孩子的结点   
    BiTree p = NULL;//用于生成新的结点  
    int k = 0;//记录期待的结点, k==1表示期待左孩子结点,k==2期待右孩子结点  
    char ch = getchar();  
      
    //处理根结点   
    if(ch!='#')  
    {  
        p = new BiTreeNode;  
        p->data = ch;  
        p->lchild = NULL;  
        p->rchild = NULL;  
        T = p;//根结点   
    }  
    while((ch=getchar())!='#')  
    {  
        switch(ch)  
        {  
            case '(':  
                s.push(p);//上一个生成的结点,即p入栈,p有孩子   
                k = 1;  //下一个插入的应为左孩子结点   
                break;  
            case ',':  
                k = 2;  //下一个插入的应为右孩子结点   
                break;  
            case ')':  
                s.pop();//结点完成孩子的输入,出栈   
                break;  
            default:  
                p = new BiTreeNode;  
                p->data = ch;  
                p->lchild = NULL;  
                p->rchild = NULL;  
                if(k==1)  
                    s.top()->lchild = p;  
                else   
                    s.top()->rchild = p;  
        }         
    }  
}  


//以广义表的方式输出二叉树  
void printBiTreeWithGenList(const BiTree&T)  
{  
    if(T)  
    {  
        cout<<T->data;  
        if(T->lchild ||T->rchild)//左右子树不全空   
        {  
            cout<<"(";  
            printBiTreeWithGenList(T->lchild);//递归输出左子树 ,可能为空   
            if(T->rchild)          
            {  
                cout<<",";  
                printBiTreeWithGenList(T->rchild);  
            }  
            cout<<")";  
        }  
    }  
}  
   
//递归销毁一棵二叉树  
void destroyBiTree(BiTree &T)  
{  
    if(T)  
    {  
        destroyBiTree(T->lchild);  
        destroyBiTree(T->rchild);  
        delete T;  
        T = NULL;  
    }  
}   
  
//递归先序遍历二叉树   
void preOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        cout<<T->data<<" ";//输出根节点值   
        preOrderTraverse(T->lchild);//遍历左子树   
        preOrderTraverse(T->rchild);//遍历右子树   
    }  
}  
  
//递归中序遍历二叉树  
void inOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        inOrderTraverse(T->lchild);//遍历左子树   
        cout<<T->data<<" ";//输出根节点值   
        inOrderTraverse(T->rchild);//遍历右子树   
    }  
}  
  
//递归后序遍历二叉树  
void postOrderTraverse(const BiTree &T)  
{  
    if(T)  
    {  
        postOrderTraverse(T->lchild);//遍历左子树   
        postOrderTraverse(T->rchild);//遍历右子树   
        cout<<T->data<<" ";//输出根节点值   
    }   
}  
  
//递归求树的深度   
int depthOfBiTree(const BiTree &T)  
{  
    int ldepth;  
    int rdepth;  
      
    if(T==NULL)//空树   
        return 0;  
    ldepth = depthOfBiTree(T->lchild);  
    rdepth = depthOfBiTree(T->rchild);  
      
    return (ldepth>rdepth)?(ldepth+1):(rdepth+1);  
}  
  
//递归求二叉树的叶子结点个数  
int leafCountOfBiTree(const BiTree &T)  
{     
    if(T==NULL)  
        return 0;  
    if(T->lchild==NULL && T->rchild==NULL)  
        return 1;  
    return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);  
}   
  
//递归交换二叉树的左右子女  
void exchangeChild(BiTree &T)  
{  
    if(T)  
    {  
        BiTree temp = NULL;  
          
        if(T->lchild ||T->rchild)  
        {  
            temp = T->lchild;  
            T->lchild = T->rchild;  
            T->rchild = temp;  
            exchangeChild(T->lchild);  
            exchangeChild(T->rchild);  
        }  
    }  
}  
   
int main(int argc, char *argv[])  
{  
    BiTree T = NULL;  
      
    createBiTree(T);//建立二叉树 如输入AB#D##CE###   
//  createBiTreeWithGenList(T);//如输入A(B(,D),C(E))#  
      
    cout<<"preOrder: "; //先序遍历   
    preOrderTraverse(T);  
    cout<<endl;  
      
    cout<<"inOrder: ";//中序遍历   
    inOrderTraverse(T);  
    cout<<endl;  
      
    cout<<"postOrder: ";//后序遍历   
    postOrderTraverse(T);  
    cout<<endl;  
      
    cout<<"depth: "<<depthOfBiTree(T)<<endl;//树的高度   
      
    cout<<"the count of leaf: "<<leafCountOfBiTree(T)<<endl;//叶子结点数   
      
    cout<<"The tree after exchange: ";  
    exchangeChild(T);  
    printBiTreeWithGenList(T);  
      
    destroyBiTree(T);//销毁二叉树,释放空间   
      
    system("PAUSE");  
    return EXIT_SUCCESS;  
}  

注:本文为转载文章,转载原因:以后方便自己查看。
原文:http://blog.csdn.net/sysu_arui/article/details/7865873

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值