• 线索化二叉树的构建与先序,中序遍历(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 }
  • 相关阅读:
    前端错误知识提示积累
    插件介绍之一:常用插件
    css小技巧积累
    设置网页地址栏小图标
    SEO优化篇——meta用法
    获取客户端的cookie
    come on,make a date progress bar together!
    教教你不用table制作出表格
    js实现快捷键绑定按钮点击事件
    Sublime Text3常用快捷键
  • 原文地址:https://www.cnblogs.com/ljwTiey/p/4286865.html
Copyright © 2020-2023  润新知