二叉树操作总结

来源:互联网 发布:网络直播名人排名 编辑:程序博客网 时间:2024/06/05 17:51
#include<iostream>#include<stack>#include<queue>#include<string>#include<vector>using namespace std;template<class T>struct Node{    T value;    Node* pLeft;    Node* pRight;    bool isFirst;    Node(T value){        this->value = value;        pLeft = pRight = NULL;        isFirst = true;    }};template<class T>class Tree{private:        Node<T>* root;public:    Tree(){        root = NULL;    }    //插入值    /*1.如果当前节点为空,则插入值到当前节点     *2.如果当前节点不为空,且待插入值大于当前节点,则进入当前节点的右子节点     *3.如果当前节点不为空,且待插入值小于当前节点,则进入当前节点的左子节点     * */    void insert(T value){        mInsert(root, value);    }    //递归前中后遍历    void recursive(){        mRecursive(root);    }    //前序遍历(非递归)    /*     * 1.将二叉树的根节点设为p     * 2.访问节点p,如果p不为空,则将p压入栈     * 3.访问p的左子节点,如果不为空,则将p的值设为p的左子节点,将p压入栈,循环此过程     * 4.如果p的左子节点为空,则弹出栈顶元素,判断top节点的右子节点是否为空     * 5.如果top节点的右子节点不为空,则将p的值设为top节点的右子节点,并将p压入栈,执行3过程     * 6.如果top节点的右子节点为空,则继续弹出栈顶元素,循环此过程,直至找到一个右子节点不为空的top节点     * 7.直到栈空为止结束     * */    void DLR(){        stack<Node<T>*> s;        Node<T>* p = root;        while(p || !s.empty()){            while(p){                cout << p->value << ' ';                s.push(p);                p = p->pLeft;            }            if(!s.empty()){                p = s.top();                s.pop();                p = p->pRight;            }        }    }    //中序遍历(非递归)    /*     * 思路和前序遍历非递归过程十分相似     **/    void LDR(){        stack<Node<T>*> s;        Node<T>* p = root;        while(p || !s.empty()){            while(p){                s.push(p);                p = p->pLeft;            }            if(!s.empty()){                p = s.top();                s.pop();                cout << p->value << ' ';                p = p->pRight;            }        }    }    //后序遍历(非递归需要辅助节点isFirst)    /*     *思路:程序保证满足两个条件:     *1.当一个节点有未访问过的子节点时,需要先访问其子节点     *2.不能重复访问一个节点的子节点     *      *1.将根节点压入栈,设根节点为Node     *2.按照顺序将Node节点的右子节点(不为空并且之前没有访问过)和左子节点(不为空并且之前没有访问过)压入栈     *3.判断Node节点是否等于栈顶节点,如果不等于,则让Node节点等于栈顶节点,继续2过程     *4.如果Node节点等于栈顶节点,此时说明已经到了最底层叶子节点,退出循环     *5.判断栈是否为空,不为空的话,让Node节点等于栈顶节点,输出值,并弹出此节点,让Node节点等于下一个栈顶节点,进入2过程,循环此过程     *6.直到栈为空,结束此过程     * */    void LRD_ONE(){        stack<Node<T>*> s;        Node<T>* p = root;        s.push(p);        p->isFirst = false;        while(p || !s.empty()){            while(p){                if(p->pRight && p->pRight->isFirst){                    p->pRight->isFirst = false;                    s.push(p->pRight);                }                if(p->pLeft && p->pLeft->isFirst){                    p->pLeft->isFirst = false;                    s.push(p->pLeft);                }                if(s.empty())                    break;                p == s.top() ? p = NULL : p = s.top();            }            if(!s.empty()){                p = s.top();                s.pop();                cout << p->value << ' ';                s.empty() ? p = NULL : p = s.top();            }        }    }    //后续遍历(非递归不需要辅助节点isFirst)    /*     *思路:程序保证满足两个条件:     *1.当一个节点有未访问过的子节点时,需要先访问其子节点     *2.不能重复访问一个节点的子节点     **/    void LRD_TWO(){        stack<Node<T>*> s;        s.push(root);        Node<T>* cur = NULL;        Node<T>* pre = NULL;        while(!s.empty()){            cur = s.top();            //下面这行代码可以满足上面两个条件            if((cur->pLeft == NULL && cur->pRight == NULL) || (pre != NULL && (pre == cur->pLeft || pre == cur->pRight))){                cout << cur->value << ' ';                s.pop();                pre = cur;            }else{                if(cur->pRight != NULL)                    s.push(cur->pRight);                if(cur->pLeft != NULL)                    s.push(cur->pLeft);            }        }    }    //按层打印    void treeShow(){        queue<Node<T>*> in;        Node<T>* last = NULL;        in.push(root);        while(!in.empty()){            while(!in.empty() && in.front() != last){                Node<T>* p = in.front();                in.pop();                cout << p->value << ' ';                if(p->pLeft){                    if(!last) last = p->pLeft;                    in.push(p->pLeft);                }                if(p->pRight){                    if(!last) last = p->pRight;                    in.push(p->pRight);                }            }            cout << endl;            last = NULL;        }    }    //按照层遍历模式进行序列化    //思路:广度优先搜索    string seriaByLayer(){        string result;        queue<Node<T>*> in;        Node<T>* last = NULL;        in.push(root);        while(!in.empty()){            while(!in.empty() && (!last || (last && in.front() != last))){                Node<T>* p = in.front();                in.pop();                if(p) {                    result += (p->value+'0');                    in.push(p->pLeft);                    in.push(p->pRight);                    if(p->pLeft && !last) last = p->pLeft;                    if(p->pRight && !last) last = p->pRight;                }                else result += '#';                result += '!';            }            last = NULL;        }        return result;    }    //按照层遍历模式进行反序列化    //思路:    /*     * 1.把root放入队列     * 2.读字符串的值,     *      每次遇到一个有效的值,就把该值压入队列,     *      遇到一个空值或者有效的值,就将该值赋给队列首节点的左右子树,     *      当队列首节点的左右子树都赋值后,就弹出首节点     *      继续往下读字符串的值     * 3.循环此过程     * */    void deSeriaByLayer(string str){        if(str.length() < 1) return;        Node<T>* root = new Node<T>(str[0] - 48);        queue<Node<T>*> in;        in.push(root);        int index = 0; //0表示应该赋值给左子树,1表示应该赋值给右子树        for(int i = 1; i < int(str.length()); i++){            if(str[i] == '!') continue;            else if(str[i] == '#'){                if(index == 0) index = 1;                else if(index == 1) {                    index = 0;                    in.pop();                }            }            else{                Node<T>*& p = in.front();                Node<T>* node = new Node<T>(str[i] - 48);                in.push(node);                if(index == 0) {                    p->pLeft = node;                    index = 1;                }                else if(index == 1){                    p->pRight = node;                    in.pop();                    index = 0;                }            }        }        this->root = root;    }protected:    void mInsert(Node<T>*& root, T value){        if(!root){            Node<T>* node = new Node<T>(value);            root = node;        }        else if(value > root->value)            mInsert(root->pRight, value);        else if(value < root->value)            mInsert(root->pLeft, value);    }    void mRecursive(Node<T>* root){        if(root){            cout << root->value << ' ';//前序            mRecursive(root->pLeft);            //cout << root->value << ' ';//中序            mRecursive(root->pRight);            //cout << root->value << ' ';//后序        }    }    //将一个只知道根节点的树赋给指定的树    void setRootToTree(Node<T>* root){        this->root = root;    }};int main1(){    Tree<int> tree;    for(int i = 0; i < 100; i++){        if(i%2) tree.insert(i);        else tree.insert(-i);    }    tree.treeShow();    return 0;}
0 0
原创粉丝点击