二叉树线索化

线索二叉树


按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列。在改序列中,除第一个结点外每个结点有且仅有一个直接前驱结点;除最后一个结点外每一个结点有且仅有一个
直接后继结点。这些指向直接前驱结点和指向直接后续结点的指针被称为线索(Thread),加了线索的二叉树称为线索二叉树。

  当用二叉链表作为二叉树的存储结构时,因为每个结点中只有指向其左、右儿子结点的指针,所以从任一结点出发只能直接找到该结点的左、右儿子。在一般情况下靠它无法直接找到该结点在某种

  遍历序下的前驱和后继结点。如果在每个结点中增加指向其前驱和后继结点的指针,将降低存储空间的效率。

  我们可以证明:在n个结点的二叉链表中含有n+1个空指针。因为含n个结点的二叉链表中含有2n个指针,除了根结点,每个结点都有一个从父结点指向该结点的指针,因此一共使用了n-1个指针,所  以在n个结点的二叉链表中含有n+1个空指针。

  因此可以利用这些空指针,存放指向结点在某种遍历次序下的前驱和后继结点的指针。这种附加的指针称为线索,加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(ThreadedBinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。

程序代码:
1
#include<iostream> 2 using namespace std; 3 typedef enum 4 { 5    LINK, 6   THREAD 7 }PointerTag; 8 template<class T> 9 struct BinaryTreeNodeThd 10 { 11   T _data; 12    BinaryTreeNodeThd<T>* _left; 13    BinaryTreeNodeThd<T>* _right; 14    PointerTag _leftTag; 15    PointerTag _rightTag; 16   BinaryTreeNodeThd() : _left(NULL), _right(NULL), _leftTag(LINK), _rightTag(LINK) 17   {} 18   BinaryTreeNodeThd(const T&data) 19    :_data(data), _left(NULL), _right(NULL), _leftTag(LINK), _rightTag(LINK) 20    {} 21 }; 22 23 template<class T> 24 class BinaryTreeThd 25 { 26 public: 27   BinaryTreeThd() :_root(NULL) 28   {} 29   BinaryTreeThd(const T*a, size_t size) 30   { 31     size_t index = 0; 32     _root = _CreateTree(a, size, index); 33   } 34   BinaryTreeThd(const BinaryTreeThd<T>& t) 35   { 36      _root = _Copy(t._root); 37    } 38   void InOrderThreading() 39   { 40      BinaryTreeNodeThd<T>* prev = NULL; 41      _InOrderThreading(_root, prev); 42   } 43   void PrevOrderThreading() 44   { 45      BinaryTreeNodeThd<T>* prev = NULL; 46      _PrevOrderThreading(_root, prev); 47    } 48   void PostOrderThreading() 49   { 50      BinaryTreeNodeThd<T>* prev = NULL; 51      _PostOrderThreading(_root, prev); 52   } 53 54 public: 55   void InOrderThd() 56    { 57      BinaryTreeNodeThd<T>* cur=_root; 58      while (cur) 59      { 60        while (cur->_leftTag == LINK) 61        { 62          cur = cur->_left; 63        } 64        cout<<cur->_data<<" "; 65        while(cur&&cur->_rightTag == THREAD) 66        { 67          cur = cur->_right; 68          cout << cur->_data; 69        } 70        cur = cur->_right; 71      } 72      cout << endl; 73    } 74   void PrevOrderThd() 75   { 76     BinaryTreeNodeThd<T> *cur =_root; 77     while (cur) 78      { 79        while (cur&&cur->_leftTag == LINK) 80        { 81          cout << cur->_data << " "; 82          cur = cur->_left; 83       } 84       cout << cur->_data << " "; 85        while (cur&&cur->_rightTag == THREAD) 86        { 87          cur = cur->_right; 88          cout << cur->_data << " "; 89        } 90        if (cur->_leftTag == LINK) 91       cur = cur->_left; 92        else 93      cur = cur->_right; 94      } 95   } 96 97 protected: 98   BinaryTreeNodeThd<T>* _CreateTree(const T*a, size_t size, size_t &index) 99    {   100      BinaryTreeNodeThd<T>* root = NULL; 101      if (index < size&&a[index] != '#') 102      { 103        root = new BinaryTreeNodeThd<T>(a[index]); 104        root->_left = _CreateTree(a, size, ++index); 105        root->_right = _CreateTree(a, size, ++index); 106     } 107     return root; 108    } 109 110   void _InOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev) 111   { 112       if (cur == NULL) 113       return; 114       _InOrderThreading(cur->_left, prev); 115        if (cur->_left == NULL) 116       { 117          cur->_leftTag = THREAD; 118         cur->_left = prev; 119        } 120 121       if (prev&&prev->_rightTag == NULL) 122       { 123          prev->_rightTag = THREAD; 124          prev->_right = cur; 125       } 126 127       prev = cur; 128 129       _InOrderThreading(cur->_right, prev); 130 131    } 132 133   void _PrevOrderThreading(BinaryTreeNodeThd<T> *cur, BinaryTreeNodeThd<T>*& prev) 134    { 135      if (cur == NULL) 136      { 137        return; 138      } 139      if (cur->_left == NULL) 140      { 141        cur->_leftTag = THREAD; 142        cur->_left = prev; 143      } 144 145     if (prev&&prev->_right== NULL) 146 147     { 148 149        prev->_rightTag = THREAD; 150 151        prev->_right = cur; 152 153     } 154 155     prev = cur; 156 157     if (cur->_leftTag == LINK) 158 159      { 160 161        _PrevOrderThreading(cur->_left, prev); 162 163     } 164 165     if (cur->_rightTag == LINK) 166 167     { 168 169       _PrevOrderThreading(cur->_right, prev); } 170 171      } 172 173      void _PostOrderThreading(BinaryTreeNodeThd<T> *cur, BinaryTreeNodeThd<T>*& prev) 174     { 175          if (cur == NULL) 176          { 177            return; 178          } 179          _PostOrderThreading(cur->_left, prev); 180         _PostOrderThreading(cur->_right, prev); 181 182         if (cur->_left == NULL) 183          { 184            cur->_leftTag = THREAD; 185            cur->_left = prev; 186          } 187          if (prev&&prev->_right == NULL) 188         {         189            prev->_rightTag = THREAD; 190            prev->_right = cur; 191         } 192         prev = cur; 193      } 194 195   BinaryTreeNodeThd<T>* _Copy(BinaryTreeNodeThd<T>* root) 196   { 197        if (root == NULL) 198        return NULL; 199       BinaryTreeNodeThd<T>* newRoot = new BinaryTreeNodeThd<T>(root->_data); 200       newRoot->_left = _Copy(root->_left); 201       newRoot->_right = _Copy(root->_right); 202        return newRoot; 203   } 204 205 206 207   /*BinaryTreeThd<T>& operator=(BinaryTreeThd<T>*& t) 208    { 209        if (this != &t) 210        { 211          this->_Destory(_root); 212          _root = _Copy(t._root); 213        } 214        return *this; 215    }*/ 216    //BinaryTreeNodeThd<T>& operator=(BinaryTreeNodeThd<T> t) 217    //{ 218     // swap(_root, t._root); 219      // return this; 220   //} 221 222 protected: 223    BinaryTreeNodeThd<T> *_root; 224 }; 225 int main() 226 { 227    int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; 228   BinaryTreeThd<int> t(a, 10); 229   BinaryTreeThd<int> temp; 230   t.InOrderThd(); 231    t.InOrderThreading(); 232   //t.PrevOrderThreading(); 233   //t.PostOrderThreading(); 234   cout << endl; 235   system("pause"); 236   return 0; 237 }

 

posted @ 2016-04-20 21:17  *尘封的记忆*  阅读(529)  评论(0编辑  收藏  举报