zoukankan      html  css  js  c++  java
  • 二叉链表表示的二叉树和一些基本操作

      设计不同的结点结构可构成不同形式的链式储存结构。由二叉树的结点由一个数据元素和分别指向其左、右子树的两个分支构成,则表示二叉树的链表中的结点至少包含三个域:数据域和左、右指针域

    一下是二叉链表的定义和部分基本操作的函数原型说明:

    #ifndef BINARY_LINKED_LIST_TREE_H
    
    #define BINARY_LINKED_LIST_TREE_H
    
    //---------二叉树的二叉链表储存表示-----------
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define MYOVERFLOW -2
    typedef int Status;
    
    typedef char TElemType;
    
    typedef struct BiTNode
    {
        TElemType data;
        BiTNode *lchild, *rchild;
    }*BiTree; 
    //------------基本操作的函数原型说明(部分)------------
    
    Status CreateBiTree(BiTree &T);
    //T表示这个树的根节点的指针
    //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,
    //构造二叉链表表示的二叉树T
    
    Status VisitBiTree(BiTree);
    //输出结点的数据域
    
    Status PreOrderTraverse(BiTree T, Status(*Visit)(BiTree));
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    
    Status InOrderTraverse(BiTree T, Status(*Visit)(BiTree));
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    
    Status InOrderTraverse_2(BiTree T, Status(*Visit)(BiTree));
    //采用二叉链表储存结构,Visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit
    
    Status InOrderTraverse_3(BiTree T, Status(*Visit)(BiTree));
    //采用二叉链表储存结构,Visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit
    
    Status PostOrderTraverse(BiTree T, Status(*Visit)(BiTree));
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    
    Status LevelOrderTraverse(BiTree T, Status(*Visit)(BiTree));
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    

      Status Destroy(BiTree T);//摧毁T这个节点

    
    

      Status DestroyBiTree(BiTree &T);
      //摧毁二叉树T

    
    #endif

    在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理。这就提出了一个遍历二叉树的问题,即如何按某条搜索路径寻访树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。二叉树的遍历又有很多情况,其中先序、中序、后序、层序遍历是常见的情况

    上述操作的实现:

    #include"stdafx.h"
    #include"ADT.h"
    #include<deque>
    #include<stack>
    //------------基本操作的函数原型说明(部分)------------
    
    Status CreateBiTree(BiTree &T)
    //T表示这个树的根节点的指针
    //按先序次序输入二叉树中结点的值(一个字符),字符为空表示空树,
    //构造二叉链表表示的二叉树T
    {
        char ch;
        ch = getchar();
        if (ch == ' '){
            T = NULL; return OK;
        }
        else
        {
            if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))exit(MYOVERFLOW);
            T->data = ch;
            CreateBiTree(T->lchild);
            CreateBiTree(T->rchild);
        }
        return OK;
    }
    
    Status VisitBiTree(BiTree T)
    //输出结点的数据域
    {
            cout << T->data << " ";
        return OK;
    }
    
    Status Destroy(BiTree T){//摧毁T这个节点
        if (T){
            free(T);
        }
        return OK;
    }
    
    Status PreOrderTraverse(BiTree T, Status(*Visit)(BiTree))
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    {
        if (T){
            BiTree lchild = T->lchild, rchild = T->rchild;
            if(Visit(T))
            if (PreOrderTraverse(lchild,Visit))
            if (PreOrderTraverse(rchild, Visit))return OK;
            return ERROR;
        }
        return OK;
    }
    
    Status InOrderTraverse(BiTree T, Status(*Visit)(BiTree))
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    {
        if (T){
            BiTree lchild = T->lchild, rchild = T->rchild;
            if (InOrderTraverse(lchild, Visit))
            if (Visit(T))
            if (InOrderTraverse(rchild, Visit))return OK;
            return ERROR;
        }
        return OK;
    }
    
    Status InOrderTraverse_2(BiTree T, Status(*Visit)(BiTree))
    //采用二叉链表储存结构,Visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit
    {
        stack<BiTree> sta;
        sta.push(T);
        BiTree p;
        while (!sta.empty()){
            while (p = sta.top())sta.push(p->lchild);
            sta.pop();
            if (!sta.empty()){
                p = sta.top();
                sta.pop();
                if (!Visit(p))return ERROR;
                sta.push(p->rchild);
            }
        }
        return OK;
    }
    
    Status InOrderTraverse_3(BiTree T, Status(*Visit)(BiTree))
    //采用二叉链表储存结构,Visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit
    {
        stack<BiTree> sta;
        BiTree p = T;
        while (p || !sta.empty()){
            if (p){ sta.push(p); p = p->lchild; }
            else{
                p = sta.top();
                sta.pop();
                if (!Visit(p))return ERROR;
                p = p->rchild;
            }
        }
        return OK;
    }
    
    Status PostOrderTraverse(BiTree T, Status(*Visit)(BiTree))
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    {
        if (T){
            BiTree lchild = T->lchild, rchild = T->rchild;
            if (PostOrderTraverse(lchild, Visit))
            if (PostOrderTraverse(rchild, Visit))
            if (Visit(T))return OK;
            return ERROR;
        }
        return OK;
    }
    
    Status LevelOrderTraverse(BiTree T, Status(*Visit)(BiTree))
    //T表示这个树的根节点的指针
    //采用二叉链表储存结构,Visit是对结点操作的对应函数
    //层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
    //一旦visit()失败,则操作失败
    {
        deque<BiTree> deq;
        if (T){
            deq.push_back(T);
            while (!deq.empty()){
                auto temp  = deq.at(0);
                Visit(temp);
                if (temp->lchild)
                    deq.push_back(temp->lchild);
                if (temp->rchild)
                    deq.push_back(temp->rchild);
                deq.pop_front();
            }
        }
        cout << endl;
        return OK;
    }
    
    Status DestroyBiTree(BiTree &T)
    //摧毁二叉树T
    {
        if (PreOrderTraverse(T, Destroy))return OK;
        return FALSE;
    }

    主函数:

    // 二叉链表.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        BiTree T;
        cout << "中序输入二叉树,如果某个节点的左右子树为空,则输入两个空格:" << endl;
        CreateBiTree(T);
        cout << "先序遍历" << endl;
        PreOrderTraverse(T, VisitBiTree);
        cout << endl;
        cout << "中序遍历"<<endl;
        InOrderTraverse(T, VisitBiTree);
        cout << endl;
        InOrderTraverse_2(T, VisitBiTree);
        cout << endl;
        InOrderTraverse_3(T, VisitBiTree);
        cout << endl;
        cout << "后序遍历"<<endl;
        PostOrderTraverse(T, VisitBiTree);
        cout << endl;
        cout << "层序遍历"<<endl;
        LevelOrderTraverse(T, VisitBiTree);
        DestroyBiTree(T);
        return 0;
    }

    结果:(在vs2013中实现,注意要在stadfx.h中包含相应的头文件)

  • 相关阅读:
    GridView与ArrayAdapter的结合
    翻翻git之---闪烁动画的TextView RevealTextView
    希捷硬盘扩容软件-----DiscWizard
    项目管理的酸甜苦辣
    【转】Bootloader之uBoot简介(转)
    【转】uboot移植(一)BootLoader基本概念
    【转】U-boot分析与移植(1)----bootloader分析
    【转】MIPS交叉编译环境的建立
    【转】RTSP实例解析
    【转】Eclipse快捷键 10个最有用的快捷键----不错
  • 原文地址:https://www.cnblogs.com/csudanli/p/4908118.html
Copyright © 2011-2022 走看看