先序线索化二叉树

  先序线索化在很多书上都有详细解读,这里只是写了一个较为完整的一个程序罢了

  1 #include <iostream>
  2 using namespace std;
  3
  4 enum flag{Child, nChild};
  5
  6 struct Node {
  7     char data;
  8     Node * lchild;
  9     Node * rchild;
 10     flag ltag, rtag;    // Child 表示是左或右孩子  nChild 表示前驱或后继
 11 };
 12
 13 class Tree {
 14 public:
 15     Tree();
 16     ~Tree();
 17     Node * getRoot();
 18     void Show_preTree(Node *);    // 先序遍历输出
 19 private:
 20     Node * root;
 21     Node * Create();        // 供构造函数调用初始化二叉树
 22     void Delete(Node *);    // 供析构函数析构二叉树
 23     void _preTree(Node *, Node *&);        // 先序 线索化
 24 };
 25
 26 int main() {
 27     cout << "以先序方式输入二叉树:";
 28
 29     Tree T;
 30     T.Show_preTree(T.getRoot());
 31
 32     system("pause");
 33     return 0;
 34 }
 35
 36 Tree::Tree() {
 37     root = Create();        // 先创建一个默认的二叉树
 38     Node * pre = NULL;
 39     _preTree(root, pre);
 40 }
 41
 42 Tree::~Tree() {
 43     Node * p = NULL;
 44     while (root != NULL) {
 45         p = root;                        // 待删除结点
 46         if (root->ltag == Child) {
 47             root = root->lchild;        // 有左孩子,则指向左孩子
 48         } else {
 49             root = root->rchild;        // 没有左孩子,指向右孩子或者 后继
 50         }
 51         delete p;
 52     }
 53 }
 54
 55 Node * Tree::Create() {
 56     Node * root;
 57     char ch;
 58     cin >> ch;
 59     if (ch == ‘#‘) {
 60         root = NULL;
 61     } else {
 62         root = new Node();
 63         root->data = ch;
 64         root->ltag = root->rtag = Child;        //  默认设置左右指针域 为孩子
 65         root->lchild = Create();
 66         root->rchild = Create();
 67     }
 68     return root;
 69 }
 70
 71 Node * Tree::getRoot() {
 72     return root;
 73 }
 74
 75 void Tree::_preTree(Node * root, Node * &pre) {
 76     if (root == NULL) {                // 空结点,不操作,返回
 77         return;
 78     }
 79
 80     if (root->lchild == NULL) {        // 左孩子为空,设置前驱,前驱为pre, pre表示上一次访问过的结点
 81         root->lchild = pre;
 82         root->ltag = nChild;        // 左标志置为 nChild 表示是前驱
 83     }
 84     if (pre != NULL && pre->rchild == NULL) {        // 上一个结点的,即上一次访问过的结点右孩子为空,则在此时设置后继
 85         pre->rchild = root;
 86         pre->rtag = nChild;            // 右标志置为 nChild 表示是后继
 87     }
 88
 89     pre = root;                        // pre 指向当前结点,下面开始递归一次,递归时,pre作为上一次访问过的结点,即当前指向的结点
 90
 91     if (root->ltag == Child) {        // 当前结点还有左孩子,递归一次
 92         _preTree(root->lchild, pre);
 93     }
 94     if (root->rtag == Child) {        // 当前结点还有右孩子,递归一次
 95         _preTree(root->rchild, pre);
 96     }
 97 }
 98
 99 void Tree::Show_preTree(Node * root) {
100     Node * p = root;
101     if (p == NULL) {
102         return;
103     } else if (p->ltag == Child) {
104         cout << p->data << " ";
105         Show_preTree(p->lchild);
106     } else {
107         cout << p->data << " ";
108         Show_preTree(p->rchild);
109     }
110     /*
111     由于先序线索化(遍历根、左、右),可以看出(画图看最清晰):
112         当 this(当前结点)的 ltag为Child的时候表示它是有孩子的应该先遍历左子树,直接可以 p = p->lchild然后输出当前结点
113         当 this 的 ltag为 nChild的时候,表示没有了左孩子,这个时候就应该遍历它的右孩子 或者 是它的后继 ( p = p->rchild)
114         由于 当某个结点没有右孩子的时候,它会存在后继,所以可以当做是“右孩子”一样,当结点不存在右孩子或后继时,表明已经到了右子树的尾端
115     */
116 }
时间: 2024-10-13 16:20:23

先序线索化二叉树的相关文章

中序线索化二叉树

中序线索化二叉树 1 void Tree::_inTree(Node * root, Node * &pre) { 2 if (root == NULL) { // 结点为空, 1:二叉树为空 2:已到达右子树的最后一个右结点的 rchild 3 return; 4 } 5 _inTree(root->lchild, pre); // 到达当前结点的左子树的底部左结点 6 if (root->lchild == NULL) { 7 root->ltag = nChild; //

中序线索化二叉树[C语言实现及注释]

根据我自己的理解给代码加了注释. /* 中序线索二叉树 2014/11/14 */ #include<stdio.h> #include<stdlib.h> typedef struct BiTrNoDe{ char data; struct BiTrNoDe *lchild; struct BiTrNoDe *rchild; unsigned ltag : 1; //LINK是1 此处也可以用枚举类型或者宏定义去写 unsigned rtag : 1; //threading是0

C++中序线索化二叉树

1 #include <iostream> 2 using namespace std; 3 4 typedef struct TBTNode 5 { 6 char data; 7 int ltag,rtag; 8 struct TBTNode * lchild; 9 struct TBTNode * rchild; 10 }TBTNode; 11 12 TBTNode * initTBTNode() 13 { 14 TBTNode * p=(TBTNode*)malloc(sizeof(TB

数据结构例程——线索化二叉树(中序)

本文是数据结构基础系列(6):树和二叉树中第14课时线索二叉树的例程. #include <stdio.h> #include <malloc.h> #define MaxSize 100 typedef char ElemType; typedef struct node { ElemType data; int ltag,rtag; //增加的线索标记 struct node *lchild; struct node *rchild; } TBTNode; void Creat

【数据结构】线索化二叉树中序线索化的递归写法和非递归写法

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历.用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继. 为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息.所以引入了线索化二叉树.下面我们讲一下线索化二叉树中序线索化的两种实现方法: (1).递归实现中序线索化二叉树 首先我们先看一下线索化二叉树的结构 enum PointerTag{ THREAD, LINK 

java实现线索化二叉树的前序、中序、后续的遍历(完整代码)

java实现线索化二叉树的前序.中序.后续的遍历 比如创建一个二叉树 1 / 3 6 / \ / 8 10 14 线索化二叉树几个概念: n个节点的二叉链表中含有n+1 [公式2n-(n-1)=n+1]个空指针域.利用二叉链表中的空指针域,存放指向该节点在某种遍历次序下的前驱和后继节点的指针(这种附加指针成为线索).如下面的就是6+1=7个空指针域 (8,10,14各有连个指针没有指向 6有一个) 加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树.分为前序线索二叉树.中序线索二叉树.

数据结构与算法---线索化二叉树(Threaded BinaryTree)

先看一个问题 将数列 {1, 3, 6, 8, 10, 14  } 构建成一颗二叉树 问题分析: 当我们对上面的二叉树进行中序遍历时,数列为 {8, 3, 10, 1, 6, 14 } 但是 6, 8, 10, 14 这几个节点的 左右指针,并没有完全的利用上. 如果我们希望充分的利用 各个节点的左右指针, 让各个节点可以指向自己的前后节点,怎么办? 解决方案-线索二叉树 线索二叉树基本介绍 1.n个结点的二叉链表中含有n+1  [公式 2n-(n-1)=n+1] 个空指针域.利用二叉链表中的空

JAVA递归实现线索化二叉树

JAVA递归实现线索化二叉树 基础理论 首先,二叉树递归遍历分为先序遍历.中序遍历和后序遍历. 先序遍历为:根节点+左子树+右子树 中序遍历为:左子树+根节点+右子树 后序遍历为:左子树+右子树+根节点 (只要记住根节点在哪里就是什么遍历,且都是先左再右) 线索化 现在有这么一棵二叉树,它的数据结构由左节点+权+右节点构成. 可以看到4,5,6,7这几个节点的左右节点空间被浪费了.因此,线索化是指有效利用这些空间. 中序遍历的顺序为:4 2 5 1 6 3 7 现在引入前驱节点以及后继节点. 前

线索化二叉树的构建与先序,中序遍历(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