码迷,mamicode.com
首页 > 编程语言 > 详细

线索化二叉树的构建与先序,中序遍历(C++版)

时间:2015-02-11 20:31:13      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

贴出学习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 }

 

线索化二叉树的构建与先序,中序遍历(C++版)

标签:

原文地址:http://www.cnblogs.com/ljwTiey/p/4286865.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!