贴出学习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> ©); 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> ©) 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> ©);//重载赋值运算符 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> ©) 236 { 237 if(©!=this) 238 { 239 DestroyHelp(root); 240 root=CopyTreeHelp(copy.root); 241 } 242 return *this; 243 }