美文网首页数据结构笔记
二叉树创建与遍历

二叉树创建与遍历

作者: yetx | 来源:发表于2018-10-12 12:54 被阅读0次
节点定义:
class BinNode {
public:
    char data;
    BinNode* parent;
    BinNode* lchild;
    BinNode* rchild;
    BinNode(){ lchild = NULL; rchild = NULL; parent = NULL; }
    BinNode(char data2):data(data2) {
        lchild = NULL; rchild = NULL; parent = NULL;
    }
    BinNode(char data2, BinNode* parent2):data(data2) {
        lchild = NULL; rchild = NULL; parent = parent2;
    }
    void insertAsLeft(char data) {
        lchild = new BinNode(data,this);
    }
    void insertAsRight( char data) {
        rchild = new BinNode(data,this);
    }
};
树的定义:
class BinTree {
private:
    BinNode* root;
    string strtree;

public:
    BinTree() {
        root = NULL;
    }
    BinNode* getRoot() { return root; }//获取根节点
    void creatBTreeBycengci(string arr);//层次遍历产生一颗树,参考层次遍历
    void creatBTreeByString(string str) ;//通过一个字符串创建一棵树,调用creatBTree
    BinNode* creatBTree(int& pos);//通过先序遍历产生一棵树,使用递归
    void preorder(BinNode* T) ;//先序遍历以T为根节点的子树,递归
    void inorder(BinNode* T) ;//中序遍历以T为根节点的子树,递归
    void postorder(BinNode* T) ;//后序遍历以T为根节点的字数,递归

    void preorderByStack(BinNode* T);//先序遍历以T为根节点的子树,非递归
    void inorderByStack(BinNode* T);//中序遍历以T为根节点的子树,非递归
    void cengciByQueue(BinNode* T);//层次遍历,利用队列
}
以下是各种方法的实现:

首先是通过一个字符串先序遍历创建一颗树

    void creatBTreeByString(string str) {
        int pos = 0;
        strtree.assign(str);
        root = creatBTree(pos);
    }
    BinNode* creatBTree(int& pos) {
        BinNode* T;
        char ch = strtree[pos++];
        if (ch == '0')  T = NULL;
        else {
            T = new BinNode(ch);
            T->lchild = creatBTree(pos);
            T->rchild = creatBTree(pos);
        }
        return T;
    }

先序遍历、中序遍历、后序遍历的递归版本,此处无传如visit函数,只是访问节点的数据并输出:

void preorder(BinNode* T) {
        if (T == NULL)  return;
        char ch = T->data;
        cout << ch;
        preorder(T->lchild);
        preorder(T->rchild);
    }
    void inorder(BinNode* T) {//中序遍历以T为根节点的子树
        if (T == NULL)  return;
        inorder(T->lchild);
        char ch = T->data;
        cout << ch;
        inorder(T->rchild);
        
    }
    void postorder(BinNode* T) {
        if (T == NULL)  return;
        postorder(T->lchild);
        postorder(T->rchild);
        char ch = T->data;
        cout << ch;
    }

先序遍历的非递归版本(使用栈):

void preorderByStack(BinNode* T) {
        stack<BinNode*> st;
        while (1) {
            while (T != NULL) {
                cout << T->data ;// visit(T),先访问左孩子
                st.push(T->rchild);//右孩子入栈,NULL也入栈,有进行判断,不会访问NULL
                T = T->lchild;//T 继续指向下一个左孩子
            }
            if (st.empty()) break;//所有右孩子都访问完了,结束。栈底是最上面的右孩子(它最先入栈)
            T = st.top(); st.pop();//pop出栈顶的右孩子,对其进行遍历
            
        }
    }

中序遍历的非递归版本(使用栈):

    void inorderByStack(BinNode* T) {
        stack<BinNode*> st;
        while (1)
        {
            while (T != NULL) {
                st.push(T); T = T->lchild;//当跑到最左下方时,
                                         //当前节点即是left root right 中的root节点,
                                        //此时left相当于已经访问过,故接下来应该将控制权转给right
            }
            if (!st.empty()) {
                T = st.top(); st.pop();
                cout << T->data;//visit();每个节点访问完后都会试图访问 以右孩子为根节点的树,
                               //完了之后才会访问这个节点对应的父节点(即当前的栈顶)
                T = T->rchild;
            }
            else {
                break;
            }
        }
    }

层次遍历(使用队列):

    void cengciByQueue(BinNode* T) {
        queue<BinNode*> q;
        q.push(T);//首先会push进根节点
        while (!q.empty()) {
            T = q.front(); q.pop();
            cout << T->data;//visit()
            if (T->lchild)  q.push(T->lchild);
            if (T->rchild)  q.push(T->rchild);
        }
    }
};

给出一个字符串,可参考层次遍历的方法创建一棵树(使用队列):

    void creatBTreeBycengci(string arr) {//层次遍历产生一颗树,参考层次遍历
        int pos = 0;
        queue<BinNode*> q2;
        char data = arr[pos++];
        root = new BinNode(data);
        
        q2.push(root);
        BinNode* T = root;
        while (pos!=arr.length() ) {
            T = q2.front(); q2.pop();

            data = arr[pos++];
            if (data != '0')        T->lchild = new BinNode(data);
            else                    T->lchild = NULL;
            data = arr[pos++];
            if (data != '0')    T->rchild = new BinNode(data);
            else                    T->rchild = NULL;
            
            if(T->lchild)   q2.push(T->lchild);//存在才推进去
            if(T->rchild)   q2.push(T->rchild);
        }

    }

相关文章

  • 数据结构

    二叉树的创建与遍历

  • 数据结构

    二叉树的创建与遍历 哈夫曼树的创建

  • 二叉树的递归遍历+非递归遍历,Swift实现

    定义二叉树模型 创建二叉树: 创建的二叉树如下: 这个二叉树的遍历分别为: 先序遍历: 124536 中序遍历:4...

  • 二叉树的基本操作

    一、基本内容 二叉树的创建(先顺遍历的方法) 二叉树的先序遍历 二叉树的中序遍历 二叉树的后序遍历 哈夫曼树的创建...

  • 数据结构之二叉树2

    二叉树的创建 二叉树的创建用到了辅助队列,通过辅助队列来创建二叉树; 二叉树的遍历 前(先)序遍历 1、递归实现 ...

  • 二叉树 基础操作

    二叉树的使用 二叉树结构 先序创建二叉树 DFS 先序遍历二叉树 中序遍历二叉树 后序遍历二叉树 BFS 层次遍历...

  • 记一次Tree的遍历

    统计利用先序遍历创建的二叉树的深度 利用先序递归遍历算法创建二叉树并计算该二叉树的深度。先序递归遍历建立二叉树的方...

  • 线索二叉树操作

    树节点 创建中序线索二叉树 遍历中序线索二叉树 创建前序线索二叉树 遍历前序线索二叉树 参考:https://bl...

  • 二叉树

    结构体 创建二叉树 递归遍历 栈操作 非递归遍历 层次遍历 完整代码

  • 二叉树遍历

    总结一下二叉树的深度遍历(DFS)和广度遍历(BFS)首先, 创建二叉树的节点: 一、深度遍历 1.1 先序遍历(...

网友评论

    本文标题:二叉树创建与遍历

    本文链接:https://www.haomeiwen.com/subject/reowaftx.html