线索二叉树实例(前序创建,中序遍历)--2018.5.15

#include <stdio.h>
#include <stdlib.h>

#define ERROR  0
#define OK  1

typedef enum{Link, Thread} PointerTag;      //link = 0表示指向左右孩子指针
                                            //Thread = 1表示指向前驱或后继的线索
typedef struct BitNode
{
    char data;                              //结点数据
    struct BitNode *lchild;                 //左右孩子指针
    struct BitNode *rchild;
    PointerTag ltag;                        //左右标志
    PointerTag rtag;
}BitNode, *BiTree;

BiTree pre;                                 //全局变量,始终指向刚刚访问过的结点

//前序创建二叉树
void CreateTree(BiTree *t)
{
    char ch;
    scanf("%c", &ch);

    if(ch == ‘#‘)
    {
        *t = NULL;
    }
    else
    {
        (*t) = (BiTree)malloc(sizeof(BitNode));
        if((*t) == NULL)
        {
            return;
        }
        (*t)->data = ch;
        (*t)->ltag = Link;
        (*t)->rtag = Link;
        CreateTree(&((*t)->lchild));
        CreateTree(&((*t)->rchild));
    }
}

//t指向头结点,头结点左链lchild指向根结点,头结点右链rchild指向中序遍历的最后一个结点。
//中序遍历二叉线索树表示的二叉树t
int InOrderThraverse_Thr(BiTree t)
{
    BiTree p;
    p = t->lchild;           //p指向根结点
    while(p != t)
    {
        while(p->ltag == Link)   //当ltag = 0时循环到中序序列的第一个结点
        {
            p = p->lchild;
        }
        printf("%c ", p->data);  //显示结点数据,可以更改为其他对结点的操作
        while(p->rtag == Thread && p->rchild != t)
        {
            p = p->rchild;
            printf("%c ", p->data);
        }

        p = p->rchild;           //p进入其右子树
    }

    return OK;
}

//中序遍历进行中序线索化
void InThreading(BiTree p)
{
    if(p)
    {
        InThreading(p->lchild);              //递归左子树线索化
        if(!p->lchild)                       //没有左孩子
        {
            p->ltag = Thread;                //前驱线索
            p->lchild = pre;             //左孩子指针指向前驱,这里是第3步
        }
        if(!pre->rchild)                 //没有右孩子
        {
            pre->rtag = Thread;              //后继线索
            pre->rchild = p;             //前驱右孩子指针指向后继(当前结点p)
        }
        pre = p;

        InThreading(p->rchild);              //递归右子树线索化
    }
}
//建立头结点,中序线索二叉树
int InOrderThread_Head(BiTree *h, BiTree t)
{
    (*h) = (BiTree)malloc(sizeof(BitNode));
    if((*h) == NULL)
    {
        return ERROR;
    }

    (*h)->rchild = *h;
    (*h)->rtag = Link;

    if(!t)      //如果为NULL
    {
        (*h)->lchild = *h;
        (*h)->ltag = Link;
    }
    else
    {
        pre = *h;
        (*h)->lchild = t;        //第一步
        (*h)->ltag = Link;
        InThreading(t);         //找到最后一个结点
        pre->rchild = *h;        //第四步
        pre->rtag = Thread;
        (*h)->rchild = pre;      //第二步
    }
}

int main(int argc, char **argv)
{
    BiTree t;
    BiTree temp;

    printf("请输入前序二叉树的内容:\n");
    CreateTree(&t);                 //建立二叉树
    InOrderThread_Head(&temp, t);       //加入头结点,并线索化
    printf("输出中序二叉树的内容:\n");
    InOrderThraverse_Thr(temp);

    printf("\n");
    return 0;
}
[email protected]:~/Desktop/DSC$ ./test
请输入前序二叉树的内容:
ABDG##H###CE#I##F##
输出中序二叉树的内容:
G D H B A E I C F
[email protected]:~/Desktop/DSC$ 

原文地址:https://www.cnblogs.com/MrRS/p/9042711.html

时间: 2024-08-01 01:06:05

线索二叉树实例(前序创建,中序遍历)--2018.5.15的相关文章

线索二叉树的前序、中序

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历.用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继. 而线索二叉树利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息 结点信息如下 enum PointerTag{ THREAD, LINK }; template<class T> struct BinaryTreeNodeThd { T _data;                      

已知二叉树的前序和中序遍历,重构该二叉树

这套题来自于牛客网剑指offer的第四题,由于本题涉及到了对树的递归操作,而且在边界上自己计算时犯了小错误,这里记录一下: 题目描述如下: 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 解题思路: 1.由树的先序遍历可以求树的根节点, 2.根据根节点的位置在中序遍历中找到树左右子树的元素, 3.递

二叉树的前序,中序遍历

前序递归于循环 #include <iostream> #include <stack> using namespace std; struct TreeNode { int val; TreeNode *left,*right; }; void create(TreeNode *&p) { int k; cin>>k; //1 2 0 0 3 0 0; if(k!=0) { p=new TreeNode; p->val=k; create(p->l

笔试算法题(36):寻找一棵二叉树中最远节点的距离 &amp; 根据二叉树的前序和后序遍历重建二叉树

出题:求二叉树中距离最远的两个节点之间的距离,此处的距离定义为节点之间相隔的边数: 分析: 最远距离maxDis可能并不经过树的root节点,而树中的每一个节点都可能成为最远距离经过的子树的根节点:所以计算出以每个节点为根节点的子树的最 远距离,最后取他们的最大值就是整棵树的最远距离: 如果递归层次过多造成系统栈溢出,则可以使用stack堆栈结构存储递归节点,从而使用循环实现 解题: 1 struct Node { 2 int value; 3 Node *left; 4 Node *right

二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: 1 typedef struct TreeNode{ 2 int data; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 }TreeNode; 2.创建根节点: 1 TreeNode *creatRoot(){ 2 TreeNode * root =(TreeNode *)malloc(sizeof(TreeNode)); 3 if(NULL=

二叉树的前序、中序、后序遍历的递归和非递归算法实现

1 /** 2 * 二叉树的前序.中序.后序遍历的递归和非递归算法实现 3 **/ 4 5 //二叉链表存储 6 struct BTNode 7 { 8 struct BTNode *LChild; // 指向左孩子指针 9 ELEMENTTYPE data; // 结点数据 10 struct BTNode *RChild; // 指向右孩子指针 11 }; 12 13 /** 14 * 前序遍历 15 **/ 16 // 递归实现 17 void PreorderTraversal(BTNo

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

leetcode题解:Construct Binary Tree from Preorder and Inorder Traversal (根据前序和中序遍历构造二叉树)

题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 说明: 1)二叉树可空 2)思路:a.根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root),  然后在中序序列(InSequence)中查找此根(

【Tree】已知前序和中序遍历还原二叉树

1 /************************** 2 https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 3 @date 2015.5.16 4 @description 5 根据前序和中序遍历,重构二叉树 6 可用迭代,也可以使用递归. 7 递归前面已经写过,耗时,这里再次做使用迭代. 8 9 @tags tree, array, depth-first se

(编程训练)再回首,数据结构——二叉树的前序、中序、后序遍历(非递归)

最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会. 希望这些能提供给初学者一些参考. 在VC++6.0下可运行,当初还写了不少注释. 可以和(编程训练)再回首,数据结构--二叉树的前序.中序.后序遍历(递归)对比着看 [问题描述] 根据顺序存储结构建立二叉树的二叉链表,并对二叉树进行先序.中序.后序遍历. [基本要求] ·功能:根据顺序存储结构建立二叉树的二叉链表,并进行先序.中序.后序遍历. ·输入:输入二叉树的顺序存储. ·输出:二叉树的先序.中序.后序遍历序