数据结构与算法——二叉树操作

 

本文主要探讨二叉树链式存储的建树过程。

 


1. 二叉树的存储结构(二叉链表)

 

typedef char ElemType;

//二叉树的二叉链表结构,也就是二叉树的存储结构,1个数据域,2个指针域(分别指向左右孩子)
typedef  struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

 


2. 二叉树的建立

 

//二叉树的建立,按前序遍历的方式建立二叉树,当然也可以以中序或后序的方式建立二叉树
void CreateBiTree(BiTree *T)
{
    ElemType ch;
    cin >> ch;
    if (ch == '#')
        *T = NULL;  //保证是叶结点
    else
    {
        *T = (BiTree)malloc(sizeof(BiTNode));
        //if (!*T)
            //exit(OVERFLOW); //内存分配失败则退出。
        (*T)->data = ch;//生成结点
        CreateBiTree(&(*T)->lchild);//构造左子树
        CreateBiTree(&(*T)->rchild);//构造右子树    
    }
}

另一种方法:

BiTree createBinaryTree()
{
    BiTree p;
    ElemType ch;
    scanf("%c",&ch);

    if(ch == '#')     //如果到了叶子节点,接下来的左、右子树分别赋值为0
    {
        p = NULL;
    }
    else
    {
        p = (BiTree)malloc(sizeof(BiTNode));
        p->data = ch;
        p->lchild  = createBinaryTree();  //递归创建左子树
        p->rchild = createBinaryTree();  //递归创建右子树
    }
    return p;
}

边插入边建树(有序二叉树):

//将结点插入二叉树,实际上允许从空树建立有序二叉树
void insertBiTree(BiTree *T,ElemType ch)
{
    if (*T==NULL){
        *T= (BiTree)malloc(sizeof(BiTNode));
        (*T)->data = ch;
        (*T)->lchild = (*T)->rchild = NULL;
    }else{
        if(ch==(*T)->data)return;
        if(ch < (*T)->data)insertBiTree(&(*T)->lchild);//构造左子树
        if(ch > (*T)->data)insertBiTree(&(*T)->rchild);//构造右子树    
    }
}

 


3. 二叉树的遍历

 

递归遍历:

//访问函数
void visit(ElemType ch){
  //do something
}

//
递归方式前序遍历二叉树 void PreOrderTraverse(BiTree T) { if (T == NULL)return;
visit(T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); } //递归方式中序遍历二叉树 void InOrderTraverse(BiTree T) {   if(T==NULL)return;
  InOrderTraverse(T
->lchild);   visit(T->data);
  InOrderTraverse(T->rchild); } //递归方式后序遍历二叉树 void PostOrderTraverse(BiTree T) {   if(T==NULL)return;
  PostOrderTraverse(T
->lchild);   PostOrderTraverse(T->rchild);   visit(T->data); }

层次遍历:

略。

 


4. 与二叉树有关的计算

 

统计二叉树结点数目:

int Nodenum(BiTree root)
{
    if(NULL == root)
    {
        return 0;
    }
    else
    {
        return 1+Nodenum(root->lchild)+Nodenum(root->rchild);
    }
}

二叉树深度:

int DepthOfTree(BiTree root)
{
    if(root)
    {
        return DepthOfTree(root->lchild)>DepthOfTree(root->rchild)?DepthOfTree(root->lchild)+1:DepthOfTree(root->rchild)+1;
    }
    if( root == NULL )
    {
        return 0;
    }
}

二叉树叶子结点数:

int Leafnum(BiTree root)
{
    if(NULL == root){
        return 0;
    }else if((root->lchild == NULL) && (root->rchild == NULL))
    {
        return 1;
    }else{
        return  (Leafnum(root->lchild) + Leafnum(root->rchild)) ;
    }
}

 


5. 注意

void CreateBiTree(BiTree *T);

参数T类型是 struct BiTNode 的指针的指针。如果改成 void CreateBiTree(BiTree T); ,则由于传入的是 struct BiTNode 的指针的值,当T==NULL时,函数返回后T的值仍然是NULL,则建树失败。

 


参考资料:

  1. https://blog.csdn.net/why850901938/article/details/51052936
  2. https://www.cnblogs.com/liuamin/p/6269950.html
  3. https://blog.csdn.net/ac_blood/article/details/77047877
posted @ 2018-10-11 15:09  怪猫佐良  阅读(264)  评论(0)    收藏  举报