zoukankan      html  css  js  c++  java
  • Tree

    //Header.h

    #ifndef _HEAD_
    #define _HEAD_
    
    #include <queue>
    #include <iostream>
    using namespace std;
    
    typedef char TElemType;
    typedef int Status;
    #define OK 0
    #define ERROR -2
    #define OverFlow -1
    
    //普通二叉树
    typedef struct BiTNode
    {
        TElemType data;
        struct BiTNode *lchild, *rchild;
    } BiTNode, *BiTree;
    
    //线索二叉树
    typedef enum {Link, Thread} PointerTag;
    
    typedef struct BiThrNode
    {
        TElemType data;
        struct BiThrNode *lchild, *rchild;
        PointerTag LTag, RTag;
    } BiThrNode, *BiThrTree;
    
    //仅为普通二叉树
    void CreateBiTree(BiTree &T);
    void PreOrderTraverse(BiTree T);
    void LevelTraverse(BiTree T);
    
    //线索二叉树
    void CreateBiThrTree(BiThrTree &T);
    Status InOrderThread_Head(BiThrTree &head, BiThrTree &T);
    Status InOrderTraverse_Thr(BiThrTree T);
    
    #endif

    //Functions.cpp

    #include "Header.h"
    
    //因为BiTree是一个结构体,所以这里必须用“引用&”,否则将会新建一个空的BiTree,导致在创建二叉树时,创建失败(我们指定的BiTree为空);
    //进而导致后面的遍历直接退出(因为传进去的BiTree不管是否为“引用&”都为空);
    //另外只要创建的树正确,那么在遍历的时候不论是否“引用&”都可以得到正确的遍历顺序
    
    //创建二叉树:过程理解为先序
    void CreateBiTree(BiTree &T)
    {
        TElemType ch;
        cin >> ch;
        if (ch == '#')
            T = NULL;
        else
        {
            T = (BiTree)malloc(sizeof(BiTNode));
            if (T == NULL)
            {
                cout << "Create BinaryTree failed!";
                exit(OverFlow);
            }
            T->data = ch;
            CreateBiTree(T->lchild);
            CreateBiTree(T->rchild);
        }
    }
    
    //先序遍历
    void PreOrderTraverse(BiTree T)
    {
        if (T == NULL)
            return;
        cout << T->data;
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
    
    //深度优先遍历
    
    //广度优先遍历
    
    //层次遍历
    void LevelTraverse(BiTree T)
    {
        BiTree temp;
        queue<BiTree>q;
        q.push(T);
        do
        {
            temp = q.front();
            cout << temp->data;
            q.pop();
            if (temp->lchild != NULL)
            {
                q.push(temp->lchild);
            }
            if (temp->rchild != NULL)
            {
                q.push(temp->rchild);
            }
        } while (!q.empty());
    }
    
    //前面是二叉树,下面是线索二叉树
    BiThrTree pre;
    
    void CreateBiThrTree(BiThrTree &T)
    {
        TElemType ch;
        cin >> ch;
        if (ch == '#')
            T = NULL;
        else
        {
            T = (BiThrTree)malloc(sizeof(BiThrNode));
            if (T == NULL)
            {
                cout << "Create BinaryTree failed!";
                exit(OverFlow);
            }
            T->data = ch;
            CreateBiThrTree(T->lchild);
            CreateBiThrTree(T->rchild);
        }
    }
    
    void SetPointerTag(BiThrTree &p)    //实际上只需要设置初始值就行
    {
        if (p)
        {
            p->LTag = Link;
            p->RTag = Link;
            SetPointerTag(p->lchild);
            SetPointerTag(p->rchild);
        }
    }
    void InThreading(BiThrTree &p)    //p:present
    {
        if (p)
        {
            InThreading(p->lchild);
            //两个if都是线索结点
            if (p->lchild == NULL)        //这里千万不要写错,要看清楚:这里是没有左孩子,而不是有左孩子
            {
                p->LTag = Thread;
                p->lchild = pre;
            }
            if (pre->rchild == NULL)    //前驱没有右孩子
            {
                pre->RTag = Thread;
                pre->rchild = p;
            }
            pre = p;
            InThreading(p->rchild);
        }
    }
    
    //建立头结点,中序线索二叉树本来的其余结点
    Status InOrderThread_Head(BiThrTree &head, BiThrTree &T)
    {
        if (head == NULL)
        {
            return ERROR;
        }
    
        head->rchild = head;
        head->RTag = Link;
    
        if (T == NULL)      //如果为NULL
        {
            head->lchild = head;
            head->LTag = Link;
        }
        else
        {
            pre = head;
            head->lchild = T;        //第一步
            head->LTag = Link;
            SetPointerTag(T);
            InThreading(T);         //找到最后一个结点
            pre->rchild = head;        //第四步
            pre->RTag = Thread;
            head->rchild = pre;      //第二步
        }
        return OK;
    }
    
    Status InOrderTraverse_Thr(BiThrTree T)
    {
        BiThrTree p;
        p = T->lchild;
        while (p != T)
        {
            while (p->LTag == Link)
                p = p->lchild;
            cout << p->data;
            while (p->RTag == Thread && p->rchild != T)
            {
                p = p->rchild;
                cout << p->data;
            }
            p = p->rchild;
        }
        return OK;
    }

    //Main.cpp

    #include "Header.h"
    
    int main()
    {
        int choice;
        cout << "1:普通二叉树" << endl << "2:线索二叉树" << endl;
        cin >> choice;
        switch (choice)
        {
        case 1:
            BiTree binaryTree;
            CreateBiTree(binaryTree);
            PreOrderTraverse(binaryTree);
            cout << endl;
            LevelTraverse(binaryTree);
            cout << endl;
            break;
        case 2:
            //必须用一个新的函数,新建一个树,因为数据结构已被改变——>然后建立头节点(就像链表),
            //并随即线索化——>像链表一样遍历(相对于普通树的遍历,减少了递归的堆栈导致的返回次数)
            BiThrTree threadBinaryTree;
            CreateBiThrTree(threadBinaryTree);
            BiThrTree head = (BiThrTree)malloc(sizeof(BiThrNode));
            InOrderThread_Head(head, threadBinaryTree);
            InOrderTraverse_Thr(head);
            cout << endl;
            break;
        }
        return 0;
    }
  • 相关阅读:
    把git项目放到个人服务器上
    关于fcitx无法切换输入法的问题解决
    博客变迁通知
    (欧拉回路 并查集 别犯傻逼的错了) 7:欧拉回路 OpenJudge 数据结构与算法MOOC / 第七章 图 练习题(Excercise for chapter7 graphs)
    (并查集) HDU 1856 More is better
    (并查集 不太会) HDU 1272 小希的迷宫
    (并查集 注意别再犯傻逼的错了) HDU 1213 How Many Tables
    (最小生成树 Kruskal算法) 51nod 1212 无向图最小生成树
    (并查集) HDU 1232 畅通工程
    (最小生成树 Prim) HDU 1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/quanxi/p/6079801.html
Copyright © 2011-2022 走看看