//Header.h

#ifndef _HEAD_
#define _HEAD_ #include <queue>
#include <iostream>
using namespace std; typedef char TElemType;
typedef int Status;
#define OK 0
#define ERROR -2
#define OverFlow -1 //普通二叉树
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree; //线索二叉树
typedef enum {Link, Thread} PointerTag; typedef struct BiThrNode
{
TElemType data;
struct BiThrNode *lchild, *rchild;
PointerTag LTag, RTag;
} BiThrNode, *BiThrTree; //仅为普通二叉树
void CreateBiTree(BiTree &T);
void PreOrderTraverse(BiTree T);
void LevelTraverse(BiTree T); //线索二叉树
void CreateBiThrTree(BiThrTree &T);
Status InOrderThread_Head(BiThrTree &head, BiThrTree &T);
Status InOrderTraverse_Thr(BiThrTree T); #endif

//Functions.cpp

#include "Header.h"

//因为BiTree是一个结构体,所以这里必须用“引用&”,否则将会新建一个空的BiTree,导致在创建二叉树时,创建失败(我们指定的BiTree为空);
//进而导致后面的遍历直接退出(因为传进去的BiTree不管是否为“引用&”都为空);
//另外只要创建的树正确,那么在遍历的时候不论是否“引用&”都可以得到正确的遍历顺序 //创建二叉树:过程理解为先序
void CreateBiTree(BiTree &T)
{
TElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiTNode));
if (T == NULL)
{
cout << "Create BinaryTree failed!";
exit(OverFlow);
}
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
} //先序遍历
void PreOrderTraverse(BiTree T)
{
if (T == NULL)
return;
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
} //深度优先遍历 //广度优先遍历 //层次遍历
void LevelTraverse(BiTree T)
{
BiTree temp;
queue<BiTree>q;
q.push(T);
do
{
temp = q.front();
cout << temp->data;
q.pop();
if (temp->lchild != NULL)
{
q.push(temp->lchild);
}
if (temp->rchild != NULL)
{
q.push(temp->rchild);
}
} while (!q.empty());
} //前面是二叉树,下面是线索二叉树
BiThrTree pre; void CreateBiThrTree(BiThrTree &T)
{
TElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = (BiThrTree)malloc(sizeof(BiThrNode));
if (T == NULL)
{
cout << "Create BinaryTree failed!";
exit(OverFlow);
}
T->data = ch;
CreateBiThrTree(T->lchild);
CreateBiThrTree(T->rchild);
}
} void SetPointerTag(BiThrTree &p) //实际上只需要设置初始值就行
{
if (p)
{
p->LTag = Link;
p->RTag = Link;
SetPointerTag(p->lchild);
SetPointerTag(p->rchild);
}
}
void InThreading(BiThrTree &p) //p:present
{
if (p)
{
InThreading(p->lchild);
//两个if都是线索结点
if (p->lchild == NULL) //这里千万不要写错,要看清楚:这里是没有左孩子,而不是有左孩子
{
p->LTag = Thread;
p->lchild = pre;
}
if (pre->rchild == NULL) //前驱没有右孩子
{
pre->RTag = Thread;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild);
}
} //建立头结点,中序线索二叉树本来的其余结点
Status InOrderThread_Head(BiThrTree &head, BiThrTree &T)
{
if (head == NULL)
{
return ERROR;
} head->rchild = head;
head->RTag = Link; if (T == NULL) //如果为NULL
{
head->lchild = head;
head->LTag = Link;
}
else
{
pre = head;
head->lchild = T; //第一步
head->LTag = Link;
SetPointerTag(T);
InThreading(T); //找到最后一个结点
pre->rchild = head; //第四步
pre->RTag = Thread;
head->rchild = pre; //第二步
}
return OK;
} Status InOrderTraverse_Thr(BiThrTree T)
{
BiThrTree p;
p = T->lchild;
while (p != T)
{
while (p->LTag == Link)
p = p->lchild;
cout << p->data;
while (p->RTag == Thread && p->rchild != T)
{
p = p->rchild;
cout << p->data;
}
p = p->rchild;
}
return OK;
}

//Main.cpp

#include "Header.h"

int main()
{
int choice;
cout << "1:普通二叉树" << endl << "2:线索二叉树" << endl;
cin >> choice;
switch (choice)
{
case :
BiTree binaryTree;
CreateBiTree(binaryTree);
PreOrderTraverse(binaryTree);
cout << endl;
LevelTraverse(binaryTree);
cout << endl;
break;
case :
//必须用一个新的函数,新建一个树,因为数据结构已被改变——>然后建立头节点(就像链表),
//并随即线索化——>像链表一样遍历(相对于普通树的遍历,减少了递归的堆栈导致的返回次数)
BiThrTree threadBinaryTree;
CreateBiThrTree(threadBinaryTree);
BiThrTree head = (BiThrTree)malloc(sizeof(BiThrNode));
InOrderThread_Head(head, threadBinaryTree);
InOrderTraverse_Thr(head);
cout << endl;
break;
}
return ;
}

Tree的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  3. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

  4. 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  5. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  6. Leetcode 笔记 100 - Same Tree

    题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...

  7. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  8. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  9. Leetcode 笔记 101 - Symmetric Tree

    题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...

  10. Tree树节点选中及取消和指定节点的隐藏

    指定节点变色 指定节点隐藏 单击节点 未选中则选中该节点 已选中则取消该节点 前台: 1.HTML <ul id="listDept" name="listDept ...

随机推荐

  1. sharepoint app 开发环境配置

    1. 配置脚本如下: .通过打开命令提示符并键入以下命令来确保 spadmin 和 sptimer 服务正在运行. net start spadminv4 net start sptimerv4 .作 ...

  2. JNI在C 和 C++ 函数实现的不同

    在C中,JNI 函数调用由“(*env)->”作前缀,目的是为了取出函数指针所引用的值. 在 C++ 中,JNIEnv 类拥有处理函数指针查找的内联成员函数. 下面这两行代码访问同一函数,但每种 ...

  3. GCD同步异步 串行并行大解析

    /** 核心概念 任务:block里需要执行的操作 队列:把任务添加进入队列中,按照先进先出的原则来执行任务  串行队列:一个一个的执行 并行队列:可以让多个任务并发(同时)执行(自动开启多个线程同时 ...

  4. iOS开发之集成百度地图踩过的那些坑(基于 Xcode7.0/iOS9.2)

    本篇分4步讲述如何在项目中集成百度地图: 第一步:创建项目 第二步:利用 cocoaPod 导入百度地图的 SDK(pod 'BaiduMapKit' #百度地图SDK) 第三步:在 pch 文件中导 ...

  5. Photo Shop 设置

    1. 编辑 > 首选项 > 单位与标尺 2. 面板 在『窗口』 菜单下开启: 工具 选项 信息(F8) 图层(F7) 历史记录 可以将设置好的面板保存下来,这样下次别人弄乱了你的面板后,你 ...

  6. XMLA连接器--免费但不开源通过ODBO、XMLA

    XMLA 连接器(驱动) :来自ARQUERY   http://jaist.dl.sourceforge.net/project/xmlaconnect/XMLA_Provider_v1.0.0.1 ...

  7. 软件开发与UML的关系

    今天,我们上<统一建模语言UML>.课上老师给我们讲解了软件开发与UML之间的关系:UML常用于建立软件系统的模型,适用于系统开发的不同阶段.UML的应用贯穿于系统开发的不同阶段.1.需求 ...

  8. 全面理解JavaScript中的闭包的含义及用法

    1.什么是闭包 闭包:闭包就是能够读取其他函数内部变量的函数;闭包简单理解成“定义在一个函数内部的函数”. 闭包的形式:即内部函数能够使用它所在级别的外部函数的参数,属性或者内部函数等,并且能在包含它 ...

  9. 旧项目如何切换到Entity Framework Code First

    Entity Framework Code First固然是好东西,然而如果是已经存在的旧有项目,如何简单方便的使用切换呢? 这里介绍一个VS的插件Entity Framework Power Too ...

  10. 如何分析解读systemstat dump产生的trc文件

    ORACLE数据库的systemstat dump生成trace文件虽然比较简单,但是怎么从trace文件中浩如烟海的信息中提炼有用信息,并作出分析诊断是一件技术活,下面收集.整理如何分析解读syst ...