線索化二叉樹的構建與先序,中序遍歷(C++版)


貼出學習C++數據結構線索化二叉樹的過程,

方便和我一樣的新手進行測試和學習

同時歡迎各位大神糾正。

不同與普通二叉樹的地方會用背景色填充

//BinTreeNode_Thr.h

 1 enum PointTag  2 {Link,Thread};  3 
 4 template<typename ElemType>
 5 struct BinTreeNode
 6 {
 7     ElemType data;                     //數據元素
 8     PointTag LTag,RTag;                 //左標志,右標志
 9     BinTreeNode<ElemType> *leftChild;  //指向左孩子的指針
10     BinTreeNode<ElemType> *rightChild; //指向右孩子的指針
11     //函數構造
12     BinTreeNode();
13     BinTreeNode(const ElemType &val,
14         BinTreeNode<ElemType> *lChild=NULL,
15         BinTreeNode<ElemType> *rChild=NULL);
16     BinTreeNode<ElemType> &operator =(const BinTreeNode<ElemType> &copy);
17 };
18 
19 template<typename ElemType>
20 BinTreeNode<ElemType>::BinTreeNode()
21 {
22     leftChild=rightChild=NULL;
23     LTag=RTag=Link;               //此處初始化為Link,即存在孩子
24 }
25 
26 template<typename ElemType>
27 BinTreeNode<ElemType>::BinTreeNode(const ElemType &val,
28                         BinTreeNode<ElemType> *lChild,
29                         BinTreeNode<ElemType> *rChild)
30 {
31     data=val;
32     LTag=RTag=Link;               //初始化為Link
33     leftChild=lChild;
34     rightChild=rChild;
35 }
36 
37 template<typename ElemType>
38 BinTreeNode<ElemType> &BinTreeNode<ElemType>::operator =(const BinTreeNode<ElemType> &copy)
39 {
40     data=copy.data;
41     leftChild=copy.leftChild;
42     rightChild=copy.leftChild;
43     LTag=copy.LTag; 44     RTag=copy.RTag; 45 }

 

 

//BinaryTree_Thr.h

 1 #include"BinTreeNode_Thr.h"
  2 template<typename ElemType>
  3 class BinaryTree_Thr
  4 {
  5 protected:
  6     //數據成員
  7     BinTreeNode<ElemType> *root;
  8     //輔助函數
  9     BinTreeNode<ElemType> *CopyTreeHelp(const BinTreeNode<ElemType> *r);//復制二叉樹
 10     void DestroyHelp(BinTreeNode<ElemType> *&r);//銷毀r為根的二叉樹
 11     void PreThreadingHelp(BinTreeNode<ElemType> *p,BinTreeNode<ElemType> *&pre);   //先序線索化
 12     void InThreadingHelp(BinTreeNode<ElemType> *p,BinTreeNode<ElemType> *&pre);   //中序線索化
 13     void CreateBTreeHelp(BinTreeNode<ElemType> *&r,ElemType pre[],ElemType in[],int,int,int,int);//用中序和先序序列構造樹
 14 public:
 15     BinaryTree_Thr(){root=NULL}//無參構造
 16     BinaryTree_Thr(BinTreeNode<ElemType> *r){ root=r;}//建立以r為根的二叉樹
 17     virtual ~BinaryTree_Thr();//有指針自定義虛構,且用虛虛構
 18     BinaryTree_Thr<ElemType> &CreateBTree(ElemType pre[],ElemType in[],int n); //構造樹
 19     void PreTreading();//先序線索化
 20     void InTreading();//中序線索化
 21     void PreOrderTraverse_Thr(void (*visit) (const ElemType &))const;                       //先序遍歷
 22     void InOrderTraverse_Thr(void (*visit) (const ElemType &))const;                       //中序遍歷
 23     void LevelOrder(void (*visit) (const ElemType &))const;
 24     BinaryTree_Thr<ElemType> &operator =(const BinaryTree_Thr<ElemType> &copy);//重載賦值運算符
 25 };

26 //Copy 27 template<typename ElemType> 28 BinTreeNode<ElemType> *BinaryTree_Thr<ElemType>::CopyTreeHelp(const BinTreeNode<ElemType> *r) 29 { 30 BinTreeNode<ElemType> *cur; 31 if(r==NULL) cur=NULL; 32 else 33 { 34 BinTreeNode<ElemType> *lChild=CopyTreeHelp(r->leftChild);//復制左子樹 35 BinTreeNode<ElemType> *rChild=CopyTreeHelp(r->rightChild);//復制右子樹 36 cur=new BinTreeNode<ElemType>(r->data,lChild,rChild); 37 //復制根節點 38 } 39 return cur; 40 } 41 42 template<typename ElemType> 43 void BinaryTree_Thr<ElemType>::InThreadingHelp(BinTreeNode<ElemType> *p,BinTreeNode<ElemType> *&pre)//中序遍歷 44 { 45 if(p) 46 { 47 if(p->LTag==Link) 48 InThreadingHelp(p->leftChild,pre); //線索化左子樹. 49 if(!p->leftChild) //左孩子空 50 { 51 p->LTag=Thread; 52 p->leftChild=pre; 53 } 54 if(!pre->rightChild) //前驅 的右孩子空 55 { 56 pre->RTag=Thread; 57 pre->rightChild=p; 58 } 59 pre=p; 60 if(p->RTag==Link) 61 InThreadingHelp(p->rightChild,pre); //線索化右子樹 62 } 63 64 } 65 66 template<typename ElemType> 67 void BinaryTree_Thr<ElemType>::PreThreadingHelp(BinTreeNode<ElemType> *p,BinTreeNode<ElemType> *&pre)//先序遍歷 68 { 69 if(p) 70 { 71 if(!p->leftChild) //左孩子空 72 { 73 p->LTag=Thread; 74 p->leftChild=pre; 75 } 76 if(!pre->rightChild) //前驅 的右孩子空 77 { 78 pre->RTag=Thread; 79 pre->rightChild=p; 80 } 81 pre=p; 82 if(p->LTag==Link) 83 PreThreadingHelp(p->leftChild,pre); //線索化左子樹. 84 if(p->RTag==Link) 85 PreThreadingHelp(p->rightChild,pre); //線索化右子樹 86 } 87 88 } 89 90 template<typename ElemType> 91 void BinaryTree_Thr<ElemType>::DestroyHelp(BinTreeNode<ElemType> *&r) 92 { 93 if(r!=NULL) 94 { 95 if(r->LTag==Link) 96 DestroyHelp(r->leftChild); 97 if(r->RTag==Link) 98 DestroyHelp(r->rightChild); 99 delete r; 100 r=NULL; 101 } 102 } 103 104 //虛構 105 template<typename ElemType> 106 BinaryTree_Thr<ElemType>::~BinaryTree_Thr() 107 { 108 DestroyHelp(root); 109 } 110 111 template<typename ElemType> 112 //Thr為頭節點,T為根. 113 void BinaryTree_Thr<ElemType>::InTreading() 114 { 115 BinTreeNode<ElemType> *pre=root; 116 InThreadingHelp(root,pre); //中序線索化 117 if(pre->rightChild==NULL) 118 pre->RTag=Thread; //處理最后一個節點 119 } 120 121 template<typename ElemType> 122 void BinaryTree_Thr<ElemType>::PreTreading() 123 { 124 BinTreeNode<ElemType> *pre=root; 125 PreThreadingHelp(root,pre); //先序線索化 126 if(pre->rightChild==NULL) 127 pre->RTag=Thread; //處理最后一個節點 128 } 129 130 template<typename ElemType> 131 void print(const ElemType &e ) 132 { 133 cout<<e<<" "; 134 } 135 136 template<typename ElemType> 137 void BinaryTree_Thr<ElemType>::InOrderTraverse_Thr(void (*visit) (const ElemType &))const 138 { 139 visit=print; 140 if(root!=NULL){ 141 BinTreeNode<ElemType> *p=root; //p指向根 142 while(p->LTag==Link) p=p->leftChild; //左走至最左下角 143 while(p) 144 { 145 (*visit)(p->data); //訪問結點元素 146 if(p->RTag==Thread) //右孩子為線索,則p指向后繼 147 { 148 p=p->rightChild; 149 } 150 else //右孩子存在 151 { 152 p=p->rightChild; //遍歷右孩子 153 while(p->LTag==Link) 154 p=p->leftChild; 155 } 156 } 157 } 158 } 159 160 template<typename ElemType> 161 void BinaryTree_Thr<ElemType>::PreOrderTraverse_Thr(void (*visit) (const ElemType &))const 162 { 163 visit=print; 164 if(root!=NULL){ 165 BinTreeNode<ElemType> *p=root; //p指向根 166 while(p) 167 { 168 (*visit)(p->data); 169 if(p->RTag==Thread) 170 p=p->rightChild; 171 else 172 { 173 if(p->LTag==Link) 174 p=p->leftChild; 175 else 176 p=p->rightChild; 177 } 178 } 179 } 180 } 181 182 template<typename ElemType> 183 void BinaryTree_Thr<ElemType>::CreateBTreeHelp(BinTreeNode<ElemType> *&r, 184 ElemType pre[],ElemType in[], 185 int preLeft,int preRight,int inLeft,int inRight) 186 187 { 188 if(preLeft>preRight||inLeft>inRight) 189 r=NULL; 190 else 191 { 192 r=new BinTreeNode<ElemType>(pre[preLeft]);//生成根結點 193 int mid=inLeft; 194 while(in[mid]!=pre[preLeft]) 195 mid++; 196 CreateBTreeHelp(r->leftChild,pre,in,preLeft+1,preLeft+mid-inLeft,inLeft,mid-1); //這里如果不懂建議自己畫圖手工實現一遍。 197 CreateBTreeHelp(r->rightChild,pre,in,preLeft+mid-inLeft+1,preRight,mid+1,inRight); 198 } 199 } 200 201 template<typename ElemType> 202 //構造樹 203 BinaryTree_Thr<ElemType>& BinaryTree_Thr<ElemType>::CreateBTree(ElemType pre[],ElemType in[],int n) 204 { 205 BinTreeNode<ElemType> *r; // 206 CreateBTreeHelp(r,pre,in,0,n-1,0,n-1); 207 //return BinaryTree<ElemType>(r);//,不能這么返回,Error:不應該返回局部變量的地址 208 *this = BinaryTree_Thr<ElemType>(r); 209 return *this; 210 } 211 212 #include<queue> 213 template<typename ElemType> 214 void BinaryTree_Thr<ElemType>::LevelOrder(void (*visit) (const ElemType &))const 215 { //隊列實現 216 visit=print; 217 queue<BinTreeNode<ElemType> *> q; 218 BinTreeNode<ElemType> *t=root; 219 if(t!=NULL) q.push(t); //根非空,入隊 220 while(!q.empty()) //隊不空 221 { 222 t=q.front(); 223 q.pop(); //出隊 224 (*visit)(t->data); //一層一層進行遍歷,無法理解還是自己畫圖實現一遍 225 if(t->leftChild) 226 q.push(t->leftChild); //遍歷左孩子 227 if(t->rightChild) 228 q.push(t->rightChild); //遍歷右孩子 229 } 230 231 } 232 233 //operator = 234 template<typename ElemType> 235 BinaryTree_Thr<ElemType> &BinaryTree_Thr<ElemType>::operator=(const BinaryTree_Thr<ElemType> &copy) 236 { 237 if(&copy!=this) 238 { 239 DestroyHelp(root); 240 root=CopyTreeHelp(copy.root); 241 } 242 return *this; 243 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM