/*****/二叉树基础问题

创建一棵二叉树(先序创建):

以{1,2,3,’#’,’#’,4,’#’,’#’,5,6}为例:
先创建左路,每创建一个结点就入栈,cur指向当前结点:

这里写图片描述

左路创建完毕之后用一个变量top保存栈顶元素3,然后将栈顶的元素3抛出:
这里写图片描述
然后再创建top的右子树且cur=top->_right,然后再重复上述操作,直到创建完毕。

非递归:  
       TreeNonR(const T* a, size_t size, const T& invalid)  
       {  
              Node* cur = NULL;  
              stack<Node*> s;  
              size_t index = 0;  
              while (index < size)  
              {  
                     while (index < size&&a[index] != invalid)  
                     {  
                           if (index == 0)                     //根节点特殊处理  
                           {  
                                  _root = new Node(a[index++]);  
                                  cur = _root;  
                           }  
                           else  
                           {  
                                  cur->_left = new Node(a[index++]);  
                                  cur = cur->_left;  
                           }  
                           s.push(cur);  
                     }  
                     index++;  
                     Node* top = s.top();  
                     s.pop();  
                     if (index < size&&a[index] != invalid)  //如果右子树的根节点不为空再创建  
                     {  
                           cur = top;  
                           cur->_right = new Node(a[index++]);  
                           cur = cur->_right;  
                           s.push(cur);  
                     }  
              }  
       }  

递归:  
       BinaryTree(const T *array,size_t size,const T& invalid)  
       {  
              size_t index = 0;  
              _root=_CreatTree(array,size,index,invalid);  
       }  

       Node* _CreatTree(const T *array, size_t size, size_t& index, const T& invalid)  
       {  
              assert(array);  
              Node *root=NULL;  
              if (index < size&&array[index] != invalid)  
              {  
                     root = new Node(array[index]);                                  //创建根节点  
                     root->_left = _CreatTree(array,size,++index,invalid);           //递归创建左子树  
                     root->_right= _CreatTree(array,size,++index,invalid);           //递归创建右子树  
              }  
              return root;  
       }  

1.前序遍历一棵二叉树:
BinaryTreeTopic.h

//面向过程
#pragma once
namespace BT_TOPIC
{
    struct Node
    {
        Node* _left;
        Node* _right;
        int _data;

        Node(int  x)
            :_data(x)
            ,_left(NULL)
            ,_right(NULL)
        {}
    };
    //前序遍历
    void PrevOrder(Node* root)
    {
        if (root == NULL)
            return;
            cout << root->_data << "";
            PrevOrder(root->_left);
            PrevOrder(root->_right);
        }
void test1()
        {
            Node* n1 = new Node(1);
            Node* n2 = new Node(2);
            Node* n3 = new Node(3);
            Node* n4 = new Node(4);
            Node* n5 = new Node(5);
            Node* n6 = new Node(6);

            n1->_left = n2;
            n1->_right = n5;

            n2->_left = n3;
            n2->_right = n4;

            n5->_left = n6;

            PrevOrder(n1);
            cout << endl;
        }
    }

test.cpp

#include<iostream>
#include<assert.h>
using namespace std;
#include "BinaryTreeTopic.h"


int main()
{
    BT_TOPIC::test1();
    return 0;
}

这里写图片描述
中序遍历

 void InOder()      //中序遍历  
       {  
              _InPrint(_root);  
              cout << endl;  
       }  
       void _InPrint(Node *root)  
       {  
              Node *cur = root;  
              if (cur)  
              {  
                     _InPrint(cur->_left);  
                     cout << cur->_data << " ";  
                     _InPrint(cur->_right);  
              }  
       }  

后序遍历:

递归:  
       void PostOder()      //后序遍历  
       {  
              _BackPrint(_root);  
              cout << endl;  
       }  
       void _BackPrint(Node *root)  
       {  
              Node *cur = root;  
              if (cur)  
              {  
                     _PostPrint(cur->_left);  
                     _PostPrint(cur->_right);  
                     cout << cur->_data << " ";  
              }  
       }  

2.销毁
BinaryTreeTopic.h

void DestoryTree(Node*& root)
        {
            if (root == NULL)
                return;
            DestoryTree(root->_left);
            DestoryTree(root->_right);
            delete root;
            root = NULL;
        }

3.求二叉树节点的个数:
BinaryTreeTopic.h

//面向过程
#pragma once
namespace BT_TOPIC
{
    struct Node
    {
        Node* _left;
        Node* _right;
        int _data;

        Node(int  x)
            :_data(x)
            , _left(NULL)
            , _right(NULL)
        {}
    };
    求二叉树节点的个数  //全局/静态-》线程安全问题
    void _GetTreeSize(Node* root, size_t& size)
    {
        if (root == NULL)
            return;

        ++size;
        _GetTreeSize(root->_left, size);
        _GetTreeSize(root->_right, size);
    }
    size_t GetTreeSize(Node* root)
    {
        if (root == NULL)
            return 0;
        return GetTreeSize(root->_left) +
            GetTreeSize(root->_right) + 1;
    }



    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        cout << "Size?" << GetTreeSize(n1) << endl;

    }
}

非递归:  
       size_t Size()  
       {  
              size_t count = 0;  
              Node* cur = _root;  
              stack<Node*> s;  
              while (cur || !s.empty())  
              {  
                     while (cur)  
                     {  
                           count++;        //遍历一个结点就让count++  
                           s.push(cur);  
                           cur = cur->_left;  
                     }  
                     Node * top = s.top();  
                     s.pop();  
                     cur = top->_right;  
              }  
              return count;  
       }  

4.求叶子节点的个数:
BinaryTreeTopic.h

//面向过程
#pragma once
namespace BT_TOPIC
{
    struct Node
    {
        Node* _left;
        Node* _right;
        int _data;

        Node(int  x)
            :_data(x)
            , _left(NULL)
            , _right(NULL)
        {}
    };
    //求叶子节点的个数:
    size_t GetLeafSize(Node* root)
    {
        if (root == NULL)
            return 0;
        if (root->_left == NULL&&root->_right == NULL)
        {
            return 1;
        }
        return GetLeafSize(root->_left)
            + GetLeafSize(root->_right);
    }
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        cout << "Size?" << GetSize(n1) << endl;

    }
}

这里写图片描述

非递归:  
       size_t Leaft()  
       {  
              size_t count = 0;  
              Node* cur = _root;  
              stack<Node*> s;  
              while (cur || !s.empty())  
              {  
                     while (cur)  
                     {  
                           //如果左右子树都为空,则为叶子结点  
                           if (cur->_left == NULL&&cur->_right == NULL)  
                                  count++;  
                           s.push(cur);  
                           cur = cur->_left;  
                     }  
                     Node * top = s.top();  
                     s.pop();  
                     cur = top->_right;  
              }  
              return count;  
       }  

5.求第k层节点个数:

size_t GetKLevel(Node* root, size_t k)
    {
        if (root == NULL)
            return 0;
        if (k == 1)
            return 1;
        return GetKLevel(root->_left, k - 1)
            + GetKLevel(root->_right, k - 1);

    }
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        cout << "K Level" << GetKLevel(n1,2) << endl;

    }
}

这里写图片描述

求第i层的结点的个数
非递归:使用队列,将每一层的元素的个数都统计出来。

 size_t GetLeveSize(size_t i)  
       {  
              //空树返回0  
              if (NULL == _root)  
                     return 0;  
              //第0或第1层返回层号  
              if (i<=1)  
                     return i;  
              queue<Node*> q;  
              q.push(_root);  
              size_t leve =1;              //标记层号  
              size_t  NodeNum = 1;          //统计有多少数据入过队  
              size_t  LeveLast = 1;         //标记正在访问的这层的最后一个数据的序号  
              size_t  VisitNum = 0;         //统计已经有多少数据已经出队  
              while (!q.empty())  
              {  
                     Node* cur = q.front();  
                     q.pop();  
                     VisitNum++;  
                     if (NULL != cur->_left)  
                     {  
                           q.push(cur->_left);  
                           NodeNum++;  
                     }  
                     if (NULL != cur->_right)  
                     {  
                           q.push(cur->_right);  
                           NodeNum++;  
                     }  

                     if (VisitNum == LeveLast)   //如果以出队的个数等于这一层的最后一个数据的序号  
                     {  
                           leve++;  
                           if (leve == i)  
                                  break;   
                           LeveLast = NodeNum;        //更新到下一层的最后一个数据的位置  
                     }  
              }        
              //用已经入队过的数据个数减去已经出队的个数,得到要求的这一层的个数  
              return NodeNum - VisitNum;    
       }  

6.判断一个节点是否在一棵二叉树中

bool IsInTree(Node* root, int x)
    {
        if (root == NULL)
        {
            return false;
        }
        if (root->_data == x)
        {
            return true;
        }
        return IsInTree(root->_left, x) || IsInTree(root->_right, x);
    }
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        cout << "Is in Tree?" << IsInTree(n1, 6) << endl;

    }
}

这里写图片描述

7.层序遍历一棵二叉树:
8.//判断一棵树是否是完全二叉树

9.求二叉树中节点的最远距离:

int _FindMaxLen(Node* root, int& maxLen)
{
    if (root == NULL)
        return 0;
    int left = _FindMaxLen(root->_left, maxLen);
    int right = _FindMaxLen(root->_left, maxLen);

    if ((left +right ) > maxLen)
    {
        maxLen = left + right;
    }
    return left > right ? left + 1 : right + 1;
}

10.非递归遍历

//非递归前序遍历
void PrevOrderNonR(Node* root)
{
    Node* cur = root;
    stack<Node*> s;
    while (cur || !s.empty())
    {
        //1.访问一棵树的开始
        //这些节点的右子树还没访问,依次从栈里面取出来访问
        while (cur)
        {
            cout << cur->_data << "";
            s.push(cur);
            cur = cur->_left;
        }
        Node* top = s.top();
        s.pop();
        cur = top->_right;
    }
    cout << endl;
}
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        PrevOrderNonR(n1);
        cout << endl;

    }
}
//非递归中序遍历
void InOrderNonR(Node* root)
{
    stack<Node*> s;
    Node* cur = root;
    while (cur || !s.empty())
    {
        //访问一棵树的开始
        while (cur)
        {
            s.push(cur);
            cur = cur->_left;
        }
        //栈里面取出来意味着左子树已经访问过了
        Node* top = s.top();
        s.pop();
        cout << top->_data << "";
        //子问题
        cur = top->_right;
    }
    cout << endl;
}
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        InOrderNonR(n1);
        cout << endl;

    }
}

//非递归后序遍历
void PostOrderNonR(Node* root)
{
    Node* prev = NULL;
    Node* cur = root;
    stack<Node*> s;
    while (cur || !s.empty())
    {
        while (cur)
        {
            s.push(cur);
            cur = cur->_left;
        }
        Node* top = s.top();
        if (top->_right == NULL || top->_right == prev)
        {
            cout << top->_data << "";
            prev = top;
            s.pop();
        }
        else
        {
            cur = top->_right;
        }
    }

}
    void test1()
    {
        Node* n1 = new Node(1);
        Node* n2 = new Node(2);
        Node* n3 = new Node(3);
        Node* n4 = new Node(4);
        Node* n5 = new Node(5);
        Node* n6 = new Node(6);

        n1->_left = n2;
        n1->_right = n5;

        n2->_left = n3;
        n2->_right = n4;

        n5->_left = n6;

        PostOrderNonR(n1);
        cout << endl;

    }
}

11.查找一个结点:

非递归:  
Node* Find(const T& x)  
       {  
              Node* cur = _root;  
              stack<Node*> s;  
              while(cur||!s.empty())  
              {  
                     while (cur)  
                     {  
                           if (cur->_data == x)         //如果找到则直接返回  
                                  return cur;  
                           s.push(cur);  
                           cur = cur->_left;  
                     }  
                     Node* top = s.top();  
                     s.pop();  
                     cur = top->_right;  
              }  
              return NULL;  
       }  

递归:  
       Node* Find(const T& x)  
       {  
              return _Find(_root,x);  
       }  
       Node* _Find(Node* root,const T& x)  
       {  
              if (root == NULL)  
                     return NULL;  
              if (root->_data == x)  
                     return root;  
              Node* cur = _Find(root->_left,x);  
              if (cur == NULL)  
                     cur = _Find(root->_right,x);  
              return cur;  
       }  

12.求树的深度:

非递归:借助队列,一层一层的访问,每访问完一层,deep加一,直到队列为空,则求得深度。

size_t Depth()  
       {  
              if (_root == NULL)  
                     return 0;  
              queue<Node*> q;  
              size_t deep = 0;              
              size_t  NodeNum = 1;      //统计有多少数据入过队  
              size_t  LeveLast = 1;      //标记正在访问的这层的最后一个数据的序号  
              size_t  VisitNum=0;       //统计已经出队的数据的个数  
              q.push(_root);  
              while (!q.empty())  
              {  
                     Node* cur =q.front();  
                     q.pop();  
                     VisitNum++;  
                     if (NULL != cur->_left)  
                     {  
                           q.push(cur->_left);  
                           NodeNum++;  
                     }  
                     if (NULL != cur->_right)  
                     {  
                           q.push(cur->_right);  
                           NodeNum++;  
                     }  
                     //如果以出队的个数等于这一层的最后一个数据的序号  
                     if (LeveLast == VisitNum)      
                     {  
                           deep++;                //访问完一层就让深度加一  
                           LeveLast = NodeNum;    //更新到下一层的最后一个数据的位置  
                     }  
              }  
              return deep;  
       }  

递归:  
       size_t Depth()          //求深度  
       {  
              return _Depth(_root);  
       }  
       size_t _Depth(Node *root)  
       {  
              Node *cur = root;  
              if (NULL == cur)  
                     return 0;  
              size_t left = _Depth(cur->_left);  
              size_t right = _Depth(cur->_right);  
              return left > right ? left + 1 : right + 1;  
       }  

线索化二叉树为我们提供了一种不需要递归和借助栈就能遍历一颗二叉树的方法,如果将二叉树写成STL的形式,那么线索化就可以为之提供迭代器,这也是线索化二叉树的最主要的用法。线索化二叉树有三种方式,前序线索化,中序线索化和后序线索化。一般只要掌握前序线索化和中序线索化就可以了。后序线索化遍历的时候要借助于三叉链表或者FindParent(寻找父亲结点的函数)。
将一颗搜索二叉树转换成有序双向链表,借助中序线索化的思想,将当前结点的left当成链表的前驱指针,将prev的right当成双向链表的后继指针。

前序线索化:  
#pragma once  
enum  
{  
       LINK,  
       THREAD,  
};  
template<typename T>  
struct ThreadTreeNode  
{  
       T _data;  
       ThreadTreeNode<T> *_left;  
       ThreadTreeNode<T> *_right;  
       int _leftTag;  
       int _rightTag;  
       ThreadTreeNode(const T& data)  
              :_data(data)  
              , _left(NULL)  
              , _right(NULL)  
              , _leftTag(LINK)  
              , _rightTag(LINK)  
       {}  
};  
template<typename T>  
class ThreadBinaryTree  
{  
       typedef  ThreadTreeNode<T> Node;  
public:  
       ThreadBinaryTree()  
              :_root(NULL)  
       {}  
       ThreadBinaryTree(const T* a, size_t size, const T& invalid)  
       {  
              size_t index = 0;  
              _root = _CreatTree(a, size, index, invalid);      //构造一颗二叉树  
              PrevThreadTree();                                  //前序线索化二叉树  
       }  
       //前序遍历 前序线索化二叉树  
       void PrevOder()  
       {  
              if (_root == NULL)  
                     return;  
              Node* cur = _root;  
              while (cur)  
              {  
                     while (cur->_leftTag == LINK)  
                     {  
                           cout << cur->_data << " ";  
                           cur = cur->_left;  
                     }  
                     cout << cur->_data << " ";  
                     cur = cur->_right;  
              }  
              cout << endl;  
       }  
protected:  
       //前序线索化二叉树  
       void PrevThreadTree()  
       {  
              Node* prev = NULL;  
              _PrevThreadTree(_root, prev);  
              prev->_rightTag = THREAD;  
       }  
       Node* _CreatTree(const T* a, size_t size, size_t& index, const T& invalid)  
       {  
              //创建一颗二叉树  
              Node* root = NULL;  
              if (index < size&&a[index] != invalid)  
              {  
                     root = new Node(a[index]);  
                     root->_left = _CreatTree(a, size, ++index, invalid);  
                     root->_right = _CreatTree(a, size, ++index, invalid);  
              }  
              return root;  
       }  
       //前序 线索化二叉树  
       void _PrevThreadTree(Node* root, Node* &prev)  
       {  
              if (root == NULL)  
                     return;  
              if (root->_left != NULL)  
              {  
                     if (prev&&prev->_right == NULL)  
                     {  
                           prev->_right = root;  
                           prev->_rightTag = THREAD;  
                     }  
                     prev = root;  
              }  
              else  
              {  
                     root->_leftTag = THREAD;  
                     root->_left = prev;  
                     if (prev->_right == NULL)  
                     {  
                           prev->_right = root;  
                           prev->_rightTag = THREAD;  
                     }  
                     prev = root;  
              }  
              if (root->_leftTag != THREAD)  
              {  
                     _PrevThreadTree(root->_left, prev);  
              }  
              if (root->_rightTag != THREAD)  
              {  
                     _PrevThreadTree(root->_right, prev);  
              }  
       }  
protected:  
       Node* _root;  
};  



中序线索化:  
#pragma once  
enum  
{  
       LINK,  
       THREAD,  
};  
template<typename T>  
struct ThreadTreeNode  
{  
       T _data;  
       ThreadTreeNode<T> *_left;  
       ThreadTreeNode<T> *_right;  
       int _leftTag;  
       int _rightTag;  
       ThreadTreeNode(const T& data)  
              :_data(data)  
              , _left(NULL)  
              , _right(NULL)  
              , _leftTag(LINK)  
              , _rightTag(LINK)  
       {}  
};  
template<typename T>  
class ThreadBinaryTree  
{  
       typedef  ThreadTreeNode<T> Node;  
public:  
       ThreadBinaryTree()  
              :_root(NULL)  
       {}  
       ThreadBinaryTree(const T* a,size_t size,const T& invalid)  
       {  
              size_t index = 0;  
              _root =_CreatTree(a,size,index,invalid);  
           InThreadTree();  
       }  

       //中序遍历 中序线索化 二叉树  
       /*void InOder() 
       { 
              if (_root == NULL) 
                     return; 
              Node* cur = _root; 
              while (cur) 
              { 
                     while (cur->_leftTag == LINK) 
                           cur = cur->_left; 
                     cout << cur->_data << " "; 
                     while (cur->_rightTag == THREAD) 
                     { 
                           cur = cur->_right; 
                           cout << cur->_data << " "; 
                     } 
                     cur = cur->_right; 
              } 
              cout << endl; 
       }*/  
       //中序遍历 (2)  
       void InOder()  
       {  
              Node* cur = NULL;  
              for (cur = Frist(_root); cur != NULL; cur = Next(cur))  
              {  
                     cout << cur->_data << " ";  
              }  
              cout << endl;  
       }  
       //先序遍历   中序线索化二叉树  
       void PrevOder()  
       {  
              if (_root == NULL)  
              {  
                     return;  
              }  
              Node* cur = _root;  
              while (cur)  
              {  
                     while (cur->_leftTag!=THREAD)  
                     {  
                           cout << cur->_data<<" ";  
                           cur = cur->_left;  
                     }  
                     cout << cur->_data<<" ";  
                     if (cur->_rightTag == LINK)  
                     {  
                           cur = cur->_right;  
                     }  
                     else  
                     {  
                           while (cur&&cur->_rightTag == THREAD)  
                           {  
                                  cur = cur->_right;  
                           }  
                           if (cur != NULL)  
                           {  
                                  cur = cur->_right;  
                           }               
                     }  
              }  
              cout << endl;  
       }  
       //后序遍历 中序线索化二叉树  
       void PostOder()  
       {  
              if (_root == NULL)  
                     return;  
              Node* cur = _root;  
              while (cur->_leftTag == LINK || cur->_rightTag == LINK)       //寻找第一个访问的结点  
              {  
                     if (cur->_leftTag == LINK)  
                           cur = cur->_left;  
                     else if (cur->_rightTag==LINK)  
                         cur = cur->_right;               
              }  
              cout << cur->_data << " ";           //访问第一个结点  
              Node* p = NULL;  
              while ((p=Parent(cur))&&p!=NULL)  
              {  
                     if (p->_right == cur||p->_rightTag==THREAD)  //如果已经访问完了右子树,或者右子树是线索  
                           cur = p;                                  //cur跳转到父节点  
                     else  
                     {  
                           cur =p->_right;  
                           while (cur->_leftTag == LINK                //找到右子树下第一个访问的结点  
                                  || cur->_rightTag == LINK)    
                           {  
                                  if (cur->_leftTag == LINK)  
                                         cur = cur->_left;  
                                  else if (cur->_rightTag==LINK)  
                                         cur = cur->_right;  
                           }                      
                     }  
                     cout << cur->_data << " ";  
              }  
              cout << endl;  
       }  
protected:  
       //中序线索化二叉树  
       void InThreadTree()  
       {  
              Node* prev = NULL;  
              _InThreadTree(_root, prev);  
              prev->_rightTag = THREAD;  
       }  
       Node* Parent(Node* root)          //寻找root结点的父节点  
       {  
              if (root == NULL || root == _root) //如果root是空结点或根结点,则返回NULL  
                     return NULL;  
              Node* cur =root;  
              while (cur->_leftTag != THREAD)  
                     cur = cur->_left;  
              if (cur->_left != NULL)  
              {  
                     for (cur = cur->_left;  
                           cur&&cur->_left!=root&&cur->_right!= root;  
                           cur = cur->_right);  
              }  
              if (cur == NULL|| cur->_left == NULL)  
              {  
                     cur = root;  
                     while (cur->_rightTag != THREAD)  
                     {  
                           cur = cur->_right;  
                     }  
                     for (cur = cur->_right;  
                           cur&&cur->_left != root&&cur->_right != NULL;  
                           cur=cur->_left);  
              }  
              return cur;  
       }  
       Node* Frist(Node* root)        //寻找以root为根节点的树,中序遍历下的第一个结点  
       {  
              if (root == NULL)  
                     return NULL;  
              Node* cur = root;  
              while (cur->_leftTag != THREAD)  
              {  
                     cur = cur->_left;  
              }  
              return cur;  
       }  
       Node* Next(Node *root)          //寻找中序遍历下root的后继结点  
       {  
              if (root == NULL)  
                     return NULL;  
              Node* cur = root;  
              if(cur->_rightTag ==THREAD)  
                     return cur->_right;                   //直接返回后继  
              return Frist(cur->_right);                 //返回右子树下访问的第一个结点  
       }  
       Node* Last(Node *root)         //寻找以root为根节点的树,中序遍历下的最后一个结点  
       {  
              if (root == NULL)  
                     return NULL;  
              Node* cur = root;  
              while (cur->_right==LINK)  
                     cur = cur->_right;  
              return cur;  
       }  
       Node* Prior(Node *root)        //寻找中序遍历下root的前继结点  
       {  
              if (root == NULL)  
                     return NULL;  
              Node* cur = root;  
              if (cur->_leftTag == THREAD)  
                     return cur->_left;              //直接返回前继几点  
              return Last(cur->_left);            //返回左子树下最后一个访问的结点  
       }  
       Node* _CreatTree(const T* a, size_t size, size_t& index, const T& invalid)  
       {  
              //创建一颗二叉树  
              Node* root = NULL;  
              if (index < size&&a[index] != invalid)  
              {  
                     root = new Node(a[index]);  
                     root->_left = _CreatTree(a, size, ++index, invalid);  
                     root->_right = _CreatTree(a, size, ++index, invalid);  
              }  
              return root;  
       }  
       //中序线索化二叉树  
       void _InThreadTree(Node* root, Node* &prev)  
       {  
              if (NULL == root)  
                     return;  
              _InThreadTree(root->_left, prev);  
              if (root->_left == NULL)                //线索化前驱  
              {  
                     root->_leftTag = THREAD;  
                     root->_left = prev;  
                     prev = root;  
              }  
              if (prev != root&&prev->_right == NULL)      //线索化后继  
              {  
                     prev->_rightTag = THREAD;  
                     prev->_right = root;  
                     prev = root;  
              }  
              _InThreadTree(root->_right, prev);  
       }  
protected:  
       Node* _root;  
};  



后序线索化:  
#pragma once  
enum  
{  
       LINK,  
       THREAD,  
};  
template<typename T>  
struct ThreadTreeNode  
{  
       T _data;  
       ThreadTreeNode<T> *_left;  
       ThreadTreeNode<T> *_right;  
       ThreadTreeNode<T> *_parent;  
       int _leftTag;  
       int _rightTag;  
       ThreadTreeNode(const T& data)  
              :_data(data)  
              , _left(NULL)  
              , _right(NULL)  
              , _parent(NULL)  
              , _leftTag(LINK)  
              , _rightTag(LINK)  
       {}  
};  
template<typename T>  
class ThreadBinaryTree  
{  
       typedef ThreadTreeNode<T> Node;  
public:  
       ThreadBinaryTree()  
              :_root(NULL)  
       {}  
       ThreadBinaryTree(const T* a,size_t size,const T& invalid)  
       {  
              size_t index = 0;  
              Node* prev = NULL;  
              _root = _CreatTree(a,size,index,invalid,prev);  
              PostThreadTree();  
       }  
       void PostOder()          //后序遍历  后序线索化二叉树  
       {  
              if (_root == NULL)  
                     return;  
              Node* cur = _root;  
              while (cur->_leftTag == LINK || cur->_rightTag == LINK) //找到左子树后序遍历下的第一个结点  
              {  
                     if (cur->_leftTag == LINK)  
                           cur = cur->_left;  
                     else if (cur->_rightTag == LINK)  
                           cur = cur->_right;  
              }  
              cout << cur->_data << " ";  
              Node* p = NULL;  
              while ((p = cur->_parent) != NULL)  
              {  
                     if (p->_right == cur || p->_rightTag == THREAD)  
                           cur = p;  
                     else  
                     {  
                           cur = p->_right;  
                           while (cur->_leftTag == LINK || cur->_rightTag == LINK)  
                           {  
                                  if (cur->_leftTag == LINK)  
                                         cur = cur->_left;  
                                  else if (cur->_rightTag == LINK)  
                                         cur = cur->_right;  
                           }  
                     }  
                     cout << cur->_data << " ";  
              }  
              cout << endl;  
       }  
protected:  
       Node* _CreatTree(const T* a,size_t size,size_t& index,const T& invalid,Node* prev)  
       {  
              Node* root = NULL;  
              if (index <size&&a[index] != invalid)  
              {  
                     root = new Node(a[index]);  
                     root->_parent = prev;  
                     prev = root;  
                     root->_left = _CreatTree(a,size,++index,invalid,prev);  
                     root->_right = _CreatTree(a,size,++index,invalid,prev);  
              }  
              return root;  
       }  
       void PostThreadTree()        //后序线索化二叉树  
       {  
              Node* prev = NULL;  
              _PostThreadTree(_root,prev);  
              if (prev->_right == NULL)  
                     prev->_rightTag = THREAD;  
       }  
       void _PostThreadTree(Node* root,Node* &prev)  
       {  
              if (root == NULL)  
                     return;  
              _PostThreadTree(root->_left, prev);  
              _PostThreadTree(root->_right, prev);  
              if (root->_left == NULL)             //线索化前驱  
              {  
                     root->_left = prev;  
                     root->_leftTag = THREAD;  
                     if (prev&&prev->_right == NULL)  
                     {  
                           prev->_right = root;  
                           prev->_rightTag = THREAD;  
                     }  
                     prev = root;  
              }  
              else if(prev&&prev->_right==NULL)                 //线索化后继  
              {  
                     prev->_right = root;  
                     prev->_rightTag = THREAD;  
                     prev = root;  
              }        
       }  
protected:  
       Node* _root;  
};  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值