实验四 二叉树操作实现

实验四 二叉树操作实现
实验四 二叉树操作实现

实验四二叉树操作实现

实验日期:2017 年 4 月20 日

实验目的及要求

1. 熟练掌握树的基本概念、二叉树的基本操作及在链式存储结构上的实现;

2. 重点掌握二叉树的创建、遍历及求深度等算法;

3. 掌握运用递归方式描述算法及编写递归C程序的方法,提高算法分析和程序设计能力。实验内容

键盘输入一个字符串,利用二叉树前序遍历的结果建成一棵二叉树,并用三种遍历方法打印,比较是否与自己预先想象的相一致。再求树的深度、1度结点数、2度节点数,交换二叉树的左右子树并输出交换后的中序遍历结果验证交换的正确性。找到二叉树中序遍历最后一个结点并输出结点值。

二叉树结点类型定义:

typedef char datatype;

typedef struct tnode{

datatype data;

struct tnode *lchild,*rchild;

} BiTNode,*BiTree;

任务

1.题目要求

创建一个程序文件sy4.cpp,自定义相应函数完成以下操作:

(1)void visit(BiTree p) /*输出p指针指向的结点*/

(2)void Preorder(BiTree T) /*前序遍历*/

(3)void Inorder(BiTree T) /*中序遍历*/

(4)void Postorder(BiTree T) /*后序遍历*/

(5)BiTree CreateTree( ) /*以前序遍历的顺序建立二叉树*/

(6)int deep(BiTree T) /*求二叉树深度*/

(7)int leaf(BiTree T) /*求叶子结点数*/

(8)int OneChild(BiTree T) /*求1度结点数*/

(9)int TwoChild(BiTree T) /*求2度结点数*/

(10)void Exchange(BiTree T) /*二叉树左右子树交换*/

(11)BiTree InorderLastNode(BiTree T); /*找二叉树中序遍历最后一个结点*/

2.请回答下列问题

(1)在n个结点二叉树的二叉链表存储中,其指针域的总数为2n 个,其中n-1 个用于链接孩子结点,n+1 个空闲着。

(2)在二叉链表存储中,数据域值为data,左右子树的指针分别为left和right,则判断:

指针p所指结点为0度结点的条件是p->left==NULL&&p->right==NULL ;指针p所指结点为1度结点的条件是(p->left==NULL&&p->right!=NULL)||(p->left!=NULL&&p->right==NULL) ;

指针p所指结点为2度结点的条件是p->left!=NULL&&p->right!=NULL 。(3)T为二叉树的根的地址,该树是空二叉树满足条件:T==NULL 。

3.sy14.cpp源程序清单(含必要的注释)

#include

#include

typedef char datatype;

typedef struct tnode {

datatype data;

struct tnode *lchild, *rchild;

} BiTNode, *BiTree;

void visit(BiTree p); /*输出p指针指向的结点*/

void Preorder(BiTree T); /*前序遍历*/

void Inorder(BiTree T); /*中序遍历*/

void Postorder(BiTree T); /*后序遍历*/

BiTree CreateTree(); /*以前序遍历的顺序建立二叉树*/

int deep(BiTree T); /*求二叉树深度*/

int leaf(BiTree T); /*求叶子结点数*/

int OneChild(BiTree T); /*求1度结点数*/

int TwoChild(BiTree T); /*求2度结点数*/

void Exchange(BiTree T); /*二叉树左右子树交换*/

BiTree InorderLastNode(BiTree T); /*找二叉树中序遍历最后一个结点*/

void visit(BiTree p) { /*输出p指针指向的结点*/

if (p->data != '#') {

printf("%c ", p->data);

}

}

void Preorder(BiTree T) { /*前序遍历*/

if (T != NULL) {

visit(T); //访问根节点

Preorder(T->lchild); //访问左子节点

Preorder(T->rchild); //访问右子节点

}

}

void Inorder(BiTree T) { /*中序遍历*/

if (T != NULL) {

Inorder(T->lchild); //访问左子节点

visit(T); //访问根节点

Inorder(T->rchild); //访问右子节点

}

}

void Postorder(BiTree T) { /*后序遍历*/

if (T != NULL) {

Postorder(T->lchild); //访问左子节点

Postorder(T->rchild); //访问右子节点

visit(T); //访问根节点

}

}

BiTree CreateTree() { /*以前序遍历的顺序建立二叉树*/ char ch;

BiTree T;

if ((ch = getchar()) == '#') { /*#表示空树*/

return NULL;

}

else {

T = (BiTree)malloc(sizeof(BiTNode)); //生成根节点

T->data = ch;

T->lchild = CreateTree(); //构造左子树

T->rchild = CreateTree(); //构造右子树

return T;

}

}

int deep(BiTree T) { /*求二叉树深度*/

int lh, rh;

if (T == NULL) {

return 0;

}

else {

lh = deep(T->lchild);

rh = deep(T->rchild);

}

return (lh > rh ? lh : rh) + 1;

}

int leaf(BiTree T) { /*求叶子结点数*/

int m, n;

if (!T) { /*空树没有叶子*/

return 0;

}

else if (!T->lchild && !T->rchild) { /*叶子结点*/

return 1;

}

else { /*左子树的结点数加上右子树的结点数*/

m = leaf(T->lchild);

n = leaf(T->rchild);

return m + n;

}

}

int OneChild(BiTree T) { /*求1度结点数*/

int n = 0;

if (T == NULL) {

return 0;

}

else if ((T->lchild == NULL&&T->rchild != NULL) || (T->lchild != NULL&&T->rchild == NULL)) {

n = 1;

}

return OneChild(T->lchild) + OneChild(T->rchild) + n;

}

int TwoChild(BiTree T) { /*求2度结点数*/

int n = 0;

if (T == NULL) {

return 0;

}

else if ((T->lchild != NULL&&T->rchild != NULL))

{

n = 1;

}

return TwoChild(T->lchild) + TwoChild(T->rchild) + n;

}

void Exchange(BiTree T) { /*二叉树左右子树交换*/

BiTree temp;

if (T) {

temp = T->lchild;

T->lchild = T->rchild;

T->rchild = temp;

Exchange(T->lchild);

Exchange(T->rchild);

}

}

BiTree InorderLastNode(BiTree T) { /*找二叉树中序遍历最后一个结点*/ if(T)

while (T->rchild)

{

T = T->rchild;

}

return T;

}

int main() {

BiTree T;

printf("以前序遍历的二叉树:");

T = CreateTree();

printf("\n先序遍历:");

Preorder(T);

printf("\n");

printf("\n中序遍历:");

Inorder(T);

printf("\n");

printf("\n后序遍历:");

Postorder(T);

printf("\n");

printf("\n树的深度=%d\n", deep(T));

printf("叶子结点数=%d\n", leaf(T));

printf("1度结点数=%d\n", OneChild(T));

printf("2度结点数=%d\n", TwoChild(T));

printf("\n二叉树中序遍历最后一个结点为:%c", InorderLastNode(T)->data);

printf("\n");

printf("\n交换后的二叉树先序遍历为:");

Exchange(T); Preorder(T);

printf("\n交换后的二叉树中序遍历为:");

Inorder(T);

printf("\n交换后的二叉树后序遍历为:");

Postorder(T);

printf("\n");

printf("\n交换后的二叉树中序遍历最后一个结点为:%c", InorderLastNode(T)->data);

printf("\n");

return 0;

}

4.程序执行后屏幕上的输入输出内容

A

/

B

/ \

C D

/ \

E F

\

G

实验总结分析(本程序的重点与难点,调试中出现的问题及解决方法等)

实验三 二叉树的基本操作实现及其应用

二叉树的基本操作实现及其应用 一、实验目的 1.熟悉二叉树结点的结构和对二叉树的基本操作。 2.掌握对二叉树每一种操作的具体实现。 3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 4.会用二叉树解决简单的实际问题。 二、实验内容 设计程序实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。 1 按先序次序建立一个二叉树, 2按(A:先序 B:中序 C:后序)遍历输出二叉树的所有结点 以上比做,以下选做 3求二叉树中所有结点数 4求二叉树的深度 三、实验步骤 ㈠、数据结构与核心算法的设计描述 /* 定义DataType为char类型 */ typedef char DataType; /* 二叉树的结点类型 */ typedef struct BitNode { DataType data; struct BitNode *lchild,*rchild; }*BitTree; 相关函数声明: 1、/* 初始化二叉树,即把树根指针置空 */ void BinTreeInit(BitTree *BT) { BT=(BitTree)malloc(sizeof(BitNode)); BT->data=NULL; cout<<"二叉树初始化成功!"<>ch; if(ch=='#') BT=NULL; else { if(!(BT=(BitTree)malloc(sizeof(BitNode)))) exit(0);

数据结构二叉树实验报告

实验三二叉树的遍历 一、实验目的 1、熟悉二叉树的结点类型和二叉树的基本操作。 2、掌握二叉树的前序、中序和后序遍历的算法。 3、加深对二叉树的理解,逐步培养解决实际问题的编程能力。 二、实验环境 运行C或VC++的微机。 三、实验内容 1、依次输入元素值,以链表方式建立二叉树,并输出结点的值。 2、分别以前序、中序和后序遍历二叉树的方式输出结点内容。 四、设计思路 1. 对于这道题,我的设计思路是先做好各个分部函数,然后在主函数中进行顺序排列,以此完成实验要求 2.二叉树采用动态数组 3.二叉树运用9个函数,主要有主函数、构建空二叉树函数、建立二叉树函数、访问节点函数、销毁二叉树函数、先序函数、中序函数、后序函数、范例函数,关键在于访问节点 五、程序代码 #include #include #include #define OK 1 #define ERROR 0 typedef struct TNode//结构体定义 {

int data; //数据域 struct TNode *lchild,*rchild; // 指针域包括左右孩子指针 }TNode,*Tree; void CreateT(Tree *T)//创建二叉树按,依次输入二叉树中结点的值 { int a; scanf("%d",&a); if(a==00) // 结点的值为空 *T=NULL; else // 结点的值不为空 { *T=(Tree)malloc(sizeof(TNode)); if(!T) { printf("分配空间失败!!TAT"); exit(ERROR); } (*T)->data=a; CreateT(&((*T)->lchild)); // 递归调用函数,构造左子树 CreateT(&((*T)->rchild)); // 递归调用函数,构造右子树 } } void InitT(Tree *T)//构建空二叉树 { T=NULL; } void DestroyT(Tree *T)//销毁二叉树 { if(*T) // 二叉树非空 { DestroyT(&((*T)->lchild)); // 递归调用函数,销毁左子树 DestroyT(&((*T)->rchild)); // 递归调用函数,销毁右子树 free(T); T=NULL; } } void visit(int e)//访问结点 { printf("%d ",e); }

实验三 二叉树的操作及应用

实验三二叉树的操作及应用 实验课程名:数据结构与算法 专业班级:15计科1班学号:201540410109 姓名:刘江 实验时间:2016.10.24-10.31 实验地点:K4-102 指导教师:冯珊 成绩: 一、实验目的及要求 1、进一步掌握指针变量、动态变量的含义。 2、掌握二叉树的结构特性,以及各种存储结构的特点和适用范围。 3、掌握用指针类型描述、访问和处理二叉树的运算。 二、实验内容 任务一:完成下列程序,该程序以二叉链表作存储结构,构建如图1所示的二叉树, 并依次进行二叉树的前序、中序、后序及层次遍历。 图1 解答: (1)源代码:#include #include #define OK 1 #define ERROR 0 typedef char DataType; /* 二叉树节点的存储类型 */ typedef struct Node //define stricture BiTree { DataType data; struct Node *lchild,*rchild; }Node, *BiTree; /*按先序序列建立一棵二叉树*/ BiTree CreatBiTree(BiTree &T) { DataType ch; scanf("%c",&ch); if(ch==' ') {T=NULL;}

else { if(!(T=(Node*)malloc(sizeof(Node)))){printf("Overflow.\n") ;exit(0);} T->data =ch; CreatBiTree(T->lchild ); CreatBiTree(T->rchild ); } return T; } void PrintData(DataType x) { printf("%c",x); } void PreOrder(BiTree T, void (*Visit)( DataType item)) /*前序遍历二叉树T,访问操作为Visit()函数*/ { if(T!= NULL) { Visit(T->data); PreOrder(T->lchild, Visit); PreOrder(T->rchild, Visit); } } void InOrder(BiTree T, void (*Visit)( DataType item)) /*中序t */ { if(T!= NULL) { InOrder(T->lchild, Visit); Visit(T->data); InOrder(T->rchild, Visit); } } void PostOrder(BiTree T, void (*Visit)( DataType item)) /*后序 */ { if(T!= NULL) { PostOrder(T->lchild, Visit); PostOrder(T->rchild, Visit); Visit(T->data); }

数据结构实验二叉树

实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。求二叉树的深度。十进制的四则运算的计算器可以接收用户来自键盘的输入。由输入的表达式字符串动态生成算术表达式所对应的二叉树。自动完成求值运算和输出结果。四、实验环境 PC微机 DOS操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、测试数据 1、输入数据:*(+)3 正确结果: 2、输入数据:(1+2)*3+(5+6*7);

正确输出:56 七、表达式求值 由于表达式求值算法较为复杂,所以单独列出来加以分析: 1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。 例如有如下的中缀表达式: a+b-c 转换成后缀表达式为: ab+c- 然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。 2、求值过程 一、将原始的中缀表达式中的操作数、操作符以及括号按顺序分解出来,并以字符串的 形式保存。 二、将分解的中缀表达式转换为后缀表达式的形式,即调整各项字符串的顺序,并将括 号处理掉。 三、计算后缀表达式的值。 3、中缀表达式分解 DivideExpressionToItem()函数。分解出原始中缀表达式中的操作数、操作符以及括号,保存在队列中,以本实验中的数据为例,分解完成后队列中的保存顺序如下图所示:

实验三 二叉树的基本运算

实验三二叉树的基本运算 一、实验目的 1、使学生熟练掌握二叉树的逻辑结构和存储结构。 2、熟练掌握二叉树的各种遍历算法。 二、实验内容 [问题描述] 建立一棵二叉树,试编程实现二叉树的如下基本操作: 1. 按先序序列构造一棵二叉链表表示的二叉树T; 2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列; 3. 求二叉树的深度/结点数目/叶结点数目;(选做) 4. 将二叉树每个结点的左右子树交换位置。(选做) [基本要求] 从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立), [测试数据] 如输入:ABCффDEфGффFффф(其中ф表示空格字符) 则输出结果为 先序:ABCDEGF 中序:CBEGDFA 后序:CGEFDBA 层序:ABCDEFG [选作内容] 采用非递归算法实现二叉树遍历。

三、算法设计 1、主要思想:二叉树是n(n>=0)个元素的有限集合,此集合或者为空集,或者由一个根结点及两棵互不相交的左右子树组成,并且左右子树都是二叉树。在本实验中根据要求操作先序遍历二叉树:思想:利用栈来实现;根结点进栈,之后栈非空,弹出,接着根节点的右结点进栈,之后,左节点进栈;接着,弹出栈顶元素(输出),此结点的右结点进栈,之后左节点进栈,弹出栈顶元素(输出)...一直这样下去,直到栈为空。中序遍历二叉树:思想:利用栈。从根节点开始,循环,只要有左子节点则进栈,直到左子节点为空。接着弹出栈顶输出,判断该结点是否有右子节点,若有则进栈,若没有继续弹栈。有右子节点的情况,判断该节点是否有左子节点,有则进栈,直到左子节点为空;若该右子节点没左子节点,则弹栈;判断弹出的节点,是否有右子节点,若有则进栈,没有继续弹栈;接着又要判断刚进栈的这个节点,是否有左子节点,有则进栈,没有则继续弹栈。重复下去....栈空,是判定条件。后序遍历二叉树算法:思想:利用栈来实现。从根结点开始,只要左子节点非空,则进栈,直到左子节点为空为止。取出栈顶元素(只是取,并去弹栈),判断1:取出的栈顶元素是否有右子节点,或者右子节点是否被访问过,若满足条件(无右子节点,或者右子节点被访问过),则输出该结点,同时弹栈,并且记录下该访问的节点2:取出的栈顶元素,若有右子节点,且未被访问过,则指针继续移动到右子节点,重复一开始是否又左子节点的判断。 2、本程序包含七个模块 1)主函数

数据结构实验报告-二叉树的实现与遍历

《数据结构》第六次实验报告 学生姓名 学生班级 学生学号 指导老师

一、实验内容 1) 采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序 以及按层次遍历的操作,求所有叶子及结点总数的操作。 2) 输出树的深度,最大元,最小元。 二、需求分析 遍历二叉树首先有三种方法,即先序遍历,中序遍历和后序遍历。 递归方法比较简单,首先获得结点指针如果指针不为空,且有左子,从左子递归到下一层,如果没有左子,从右子递归到下一层,如果指针为空,则结束一层递归调用。直到递归全部结束。 下面重点来讲述非递归方法: 首先介绍先序遍历: 先序遍历的顺序是根左右,也就是说先访问根结点然后访问其左子再然后访问其右子。具体算法实现如下:如果结点的指针不为空,结点指针入栈,输出相应结点的数据,同时指针指向其左子,如果结点的指针为空,表示左子树访问结束,栈顶结点指针出栈,指针指向其右子,对其右子树进行访问,如此循环,直至结点指针和栈均为空时,遍历结束。 再次介绍中序遍历: 中序遍历的顺序是左根右,中序遍历和先序遍历思想差不多,只是打印顺序稍有变化。具体实现算法如下:如果结点指针不为空,结点入栈,指针指向其左子,如果指针为空,表示左子树访问完成,则栈顶结点指针出栈,并输出相应结点的数据,同时指针指向其右子,对其右子树进行访问。如此循环直至结点指针和栈均为空,遍历结束。 最后介绍后序遍历: 后序遍历的顺序是左右根,后序遍历是比较难的一种,首先需要建立两个栈,一个用来存放结点的指针,另一个存放标志位,也是首先访问根结点,如果结点的指针不为空,根结点入栈,与之对应的标志位也随之入标志位栈,并赋值0,表示该结点的右子还没有访问,指针指向该结点的左子,如果结点指针为空,表示左子访问完成,父结点出栈,与之对应的标志位也随之出栈,如果相应的标志位值为0,表示右子树还没有访问,指针指向其右子,父结点再次入栈,与之对应的标志位也入栈,但要给标志位赋值为1,表示右子访问过。如果相应的标志位值为1,表示右子树已经访问完成,此时要输出相应结点的数据,同时将结点指针赋值为空,如此循环直至结点指针和栈均为空,遍历结束。 三、详细设计 源代码:

数据结构实验六二叉树操作代码实现

#include using namespace std; #define MAXLEN 20 //最大长度 int num; typedef char DATA;//定义元素类型 struct CBTType// 定义二叉树结点类型 { DATA data;//元素数据 CBTType * left;//左子树结点指针 CBTType * right;//右子树结点指针 int leftSize = 0; }; /*********************初始化二叉树***********************/ CBTType *InitTree() { CBTType * node; if (node = new CBTType)//申请内存 { num++; cout << "请先输入一个根节点数据:" << endl; cin >> node->data; node->left = NULL; node->right = NULL; if (node != NULL)//如果二叉树结点不为空 { return node; } else { return NULL; } } return NULL; } /***********************查找结点*************************/ CBTType *TreeFindNode(CBTType *treeNode, DATA data) { CBTType *ptr; if (treeNode == NULL) { return NULL; } else {

if (treeNode->data == data) { return treeNode; } else//分别向左右子树查找 { if (ptr = TreeFindNode(treeNode->left, data))//左子树递归查找 { return ptr; } else if (ptr = TreeFindNode(treeNode->right, data))//右子树递归查找 { return ptr; } else { return NULL; } } } } /**********************添加结点*************************/ void AddTreeNode(CBTType *treeNode) { CBTType *pnode, *parent; DATA data; char menusel; if (pnode = new CBTType) //分配内存 { cout << "输入添加的二叉树结点数据:" << endl; cin >> pnode->data; pnode->left = NULL; //设置左子树为空 pnode->right = NULL; //设置左子树为空 cout << "输入该结点的父结点数据:" << endl; cin >> data; parent = TreeFindNode(treeNode, data); //查找父结点,获得结点指针 if (!parent) //没找到 { cout << "没有找到父结点!" << endl; delete pnode; return; } cout << "**********************" << endl;

数据结构实验-二叉树的操作

******************************* 实验题目:二叉树的操作 实验者信息:班级13007102,姓名庞文正,学号1300710226 实验完成的时间3:00 ****************************** 一、实验目的 1,掌握二叉树链表的结构和二叉树的建立过程。 2,掌握队列的先进先出的运算原则在解决实际问题中的应用。 3,进一步掌握指针变量、指针数组、动态变量的含义。 4,掌握递归程序设计的特点和编程方法。 二、实验内容 已知以二叉链表作存储结构,试编写按层次遍历二叉树的算法。(所谓层次遍历,是指从二叉树的根结点开始从上到下逐层遍历二叉树,在同一层次中从左到右依次访问各个节点。)调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加深对算法的理解。 三、算法设计与编码 1.本实验用到的理论知识 总结本实验用到的理论知识,实现理论与实践相结合。总结尽量简明扼要,并与本次实验密切相关,最好能加上自己的解释。 本算法要采用一个循环队列que,先将二叉树根结点入队列,然后退队列,输出该结点;若它有左子树,便将左子树根结点入队列;若它有右子树,便将右子树根结点入队列,直到队列空为止。因为队列的特点是先进先出,从而达到按层次顺序遍历二叉的目的。2.算法概要设计 给出实验的数据结构描述,程序模块、功能及调用关系 #include #include #define M 100 typedef struct node //二叉链表节点结构 {int data; //数据域 struct node *lchild,*rchild; //左孩子右孩子链 }bitree; bitree *que[M]; //定义一个指针数组,说明队列中的元素bitree 指针类型 int front=0, rear=0; //初始化循环列队 bitree *creat() //建立二叉树的递归算法 {bitree *t; int x; scanf("%d",&x); if(x==0) t=NULL; //以x=0 表示输入结束 else {t=malloc(sizeof(bitree)); //动态生成节点t,分别给节点t 的数据域,t->data=x; //左右孩子域赋值,给左右孩子赋值时用到 t->lchild=creat(); // 了递归思想 t->rchild=creat(); }

实验三 二叉树操作的实现 代码及运行结果图

二叉树操作的实现 #include #include #include typedef struct BiTNode { int data; BiTNode *lchild,*rchild; }BiTNode,*BiTree; int Nil=0; // 设整型以0为空 void visit(int e) { printf("%d ",e); } void CreateBiTree(BiTree &T) { int number; scanf("%d",&number); if(number==Nil) T=NULL; else // 结点的值不为空 { T=(BiTree)malloc(sizeof(BiTNode)); // 生成根结点 if(!T) exit(-2); T->data=number; // 将值赋给T所指结点 CreateBiTree(T->lchild); //C 递归构造左子树 CreateBiTree(T->rchild); // 递归构造右子树 } } void DestroyBiTree(BiTree &T) { if(T) // 非空树 { DestroyBiTree(T->lchild); DestroyBiTree(T->rchild); free(T); } } void PreOrderTraverse(BiTree T,void (*Visit)(int)){

{ Visit(T->data); PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树 PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树} } void InOrderTraverse(BiTree T,void(*Visit)(int)) { if(T) { InOrderTraverse(T->lchild,Visit); // 先中序遍历左子树 Visit(T->data); // 再访问根结点 InOrderTraverse(T->rchild,Visit); // 最后中序遍历右子树} } void PostOrderTraverse(BiTree T,void(*Visit)(int)) { if(T) // T不空 { PostOrderTraverse(T->lchild,Visit); PostOrderTraverse(T->rchild,Visit); Visit(T->data); // 最后访问根结点 } } int LeafNum( BiTree T){ if(!T) return 0; else if(!T->lchild&&!T->rchild) return 1; else // printf("nihao"); return LeafNum(T->lchild)+LeafNum(T->rchild); }

数据结构实验报告之树与二叉树

学生实验报告 学院:软通学院 课程名称:数据结构与算法 专业班级:软件142 班 姓名:邹洁蒙 学号: 0143990

学生实验报告 (二) 一、实验综述 1、实验目的及要求 目的:1)掌握树与二叉树的基本概念; 2)掌握二叉树的顺序存储,二叉链表的先序遍历中序遍历和后序遍历算法; 3)掌握树的双亲表示法。 要求:1)编程:二叉树的顺序存储实现; 2)编程:二叉链表的先序遍历中序遍历和后序遍历实现; 3)编程:树的双亲表示法实现。 2、实验仪器、设备或软件 设备:PC 软件:VC6 二、实验过程(编程,调试,运行;请写上源码,要求要有注释) 1.编程:二叉树的顺序存储实现 代码: BiTree::BiTree()//建立存储空间 { data = new int[MAXSIZE]; count = 0; } void BiTree::AddNode(int e)//加结点 { int temp = 0; data[count] = e; count++;//从编号0开始保存 }

运行截图: 2.编程:二叉链表的先序遍历中序遍历和后序遍历实现代码: void InOrderTraverse(BiTree* Head)//中序遍历 { if (Head) { InOrderTraverse(Head->LeftChild); cout << Head->data<<" "; InOrderTraverse(Head->RightChild); } } void PreOrderTraverse(BiTree* Head)//先序遍历 { if (Head) { cout << Head->data << " "; PreOrderTraverse(Head->LeftChild); PreOrderTraverse(Head->RightChild); } } void PostOrderTraverse(BiTree* Head)//后序遍历 { if (Head) { PostOrderTraverse(Head->LeftChild); PostOrderTraverse(Head->RightChild); cout << Head->data << " "; } } 运行截图:

数据结构实验报告—二叉树

算法与数据结构》课程实验报告

一、实验目的 1、实现二叉树的存储结构 2、熟悉二叉树基本术语的含义 3、掌握二叉树相关操作的具体实现方法 二、实验内容及要求 1. 建立二叉树 2. 计算结点所在的层次 3. 统计结点数量和叶结点数量 4. 计算二叉树的高度 5. 计算结点的度 6. 找结点的双亲和子女 7. 二叉树前序、中序、后序遍历的递归实现和非递归实现及层次遍历 8. 二叉树的复制 9. 二叉树的输出等 三、系统分析 (1)数据方面:该二叉树数据元素采用字符char 型,并且约定“ #”作为二叉树输入结束标识符。并在此基础上进行二叉树相关操作。 (2)功能方面:能够实现二叉树的一些基本操作,主要包括: 1. 采用广义表建立二叉树。 2. 计算二叉树高度、统计结点数量、叶节点数量、计算每个结点的度、结点所在层次。 3. 判断结点是否存在二叉树中。 4. 寻找结点父结点、子女结点。 5. 递归、非递归两种方式输出二叉树前序、中序、后序遍历。 6. 进行二叉树的复制。 四、系统设计 (1)设计的主要思路 二叉树是的结点是一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树、互不相交的二叉树组成。根据实验要求,以及课上老师对于二叉树存储结构、基本应用的讲解,同时课后研究书中涉及二叉树代码完成二叉树模板类,并将所需实现各个功能代码编写完成,在建立菜单对功能进行调试。 (2)数据结构的设计 二叉树的存储结构有数组方式和链表方式。但用数组来存储二叉树有可能会消耗大量的存储空间,故在此选用链表存储,提高存储空间的利用率。根据二叉树的定义,二叉

实验3 二叉树及其应用

实验3 二叉树及其应用 实验目的 1.加深对二叉树的结构特性的理解; 2.熟练掌握二叉树的存储结构,特别是二叉链表类的描述及其实现方法; 3.熟练掌握二叉树的遍历算法原理及实现; 4.学会编写实现二叉树的各种算法; 5.掌握二叉树的应用方法。 实验学时:建议2~4学时 实验内容 内容1:二叉树及其操作 【问题描述】 设计二叉树的二叉链表类,操作主要有建二叉树、遍历二叉树、求该二叉树中、的结点个数等。 【基本要求】 (1)建立二叉树可用先序方式建立,也可根据二叉树的先序和中序序列建立。 (2)对二叉树的遍历可采用递归或非递归的算法。 【实现提示】 (1)二叉链表的结点结构描述 struct btnode{ // 定义结点类型 ElemType data; //数据域 btnode * lchild,* rchild; //左、右指针域/ }; // btnode (2)可设计以下功能函数: btnode* createbitree(); //建立二叉链表 void preorder(btnode* bt); //先序遍历二叉树 int sum(btnode* bt); //求二叉树中的结点个数 算法可用递归或非递归实现。 建立二叉树可用以下两种算法实现: 方案1:btnode * createBT ( ) //前序建树 { bitree T; char ch; cin >>ch ; if(ch==’#’) return NULL; //二叉树为空 T=new BinTNode; //申请根结点 T->data=ch; T->lchild=createBTpre(); //创建根的左子树 1

实验3 二叉树

实验三:二叉树 学时:2学时 实验目的:掌握树形结构的特点,二叉树的存储方式以及相应操作。 实验内容: 按先序遍历序列建立二叉树的二叉链表,已知先序序列为(F表示空格):ABCFFDEFGFFFFFF。并写一个函数treenodes()统计该二叉树的节点个数。如果有可能,写一个输出函数treeprint()用树形结构打印出该二叉树。 提示: 1,统计结点数也是一种遍历操作,要首先理解遍历,递归程序。 2,由于printf打印是一行行按顺序的,要打印出树形结构,必须按层次遍历,并且利用空格。关键是控制每一层次打印的空格的数量,以及子树为空的情形。 可参考如下代码: 树的遍历:ch6_traverse.c /* 树的遍历 author: kk.h date: 2006.10 https://www.360docs.net/doc/d010741857.html, */ #include "stdio.h" typedef char ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild; }BiTNode; /* 先根遍历*/ void preorder(BiTNode *bt) { if(bt!=NULL) { printf("%c ",bt->data); preorder(bt->lchild); preorder(bt->rchild); } } /* 中根遍历*/ void inorder(BiTNode *bt) { if(bt!=NULL) { inorder(bt->lchild);

printf("%c ",bt->data); inorder(bt->rchild); } } /* 后根遍历*/ void postorder(BiTNode *bt) { if(bt!=NULL) { postorder(bt->lchild); postorder(bt->rchild); printf("%c ",bt->data); } } /* 非递归算法的中根遍历(后进先出,用了栈的思想)*/ void inorder_fdg(BiTNode *bt) { int i=0; BiTNode *p,*s[20]; p=bt; do { while(p!=NULL) { s[i++]=p; p=p->lchild; } if(i>0) { p=s[--i]; printf("%c ",p->data); p=p->rchild; } }while(i>0||p!=NULL); } /* 用队列实现层次遍历*/ void lev_traverse(BiTNode* T) { BiTNode *q[100],*p; int head,tail, i; q[0]=T;head=0;tail=1; while(headdata); if(p->lchild!=NULL)

数据结构实验3二叉树

一、实验目的 1.进一步掌握指针变量的含义。 2.掌握二叉树的结构特征,以及各种存储结构的特点及使用范围。 3.掌握用指针类型描述、访问和处理二叉树的运算。 二、实验要求 1.认真阅读和掌握本实验的参考程序。 2.按照对二叉树的操作需要,在创建好二叉树后再通过遍历算法验证创建结果。3.保存程序的运行结果,并结合程序进行分析。 三、实验内容 以下参考程序是按完全二叉树思想将输入的字符串生成二叉树,并通过遍历来验证二叉树创建正确与否,但不能创建非完全二叉树,请认真研究该程序,然后模仿教材例6.4初始化方式创建二叉树:所有的空指针均用#表示,如教材图 6-13对应的二叉树,建立时的初始序列为:AB#D##CE##F##。然后通过遍历算法验证二叉树是否正确(先递归验证后非递归验证)。 参考程序略 程序代码如下: #include "stdio.h" #include "stdlib.h" typedef char Datatype; #define MAXSIZE 100 typedef struct bnode { Datatype data; struct bnode *lchild,*rchild; }BNode,*BTree; typedef struct{ BTree data[MAXSIZE]; int front,rear; }seqqueue,*Pseqqueue; typedef struct{ BNode *node; int flag; }Data; typedef struct node { Data Data[MAXSIZE]; int top; }SeqStack,*PSeqStack; PSeqStack Init(void)

数据结构二叉树的实验报告

数据结构 实 验 报 告

1. 实验目的和内容: 掌握二叉树基本操作的实现方法2. 程序分析 2.1存储结构 链式存储 2.程序流程

2.3关键算法分析 算法一:Create(BiNode* &R,T data[],int i,int n) 【1】算法功能:创建二叉树 【2】算法基本思想:利用顺序存储结构为输入,采用先建立根结点,再建立左右孩子的方法来递归建立二叉链表的二叉树 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑: 如果位置小于数组的长度则 {创建根结点 将数组的值赋给刚才创建的结点的数据域 创建左子树,如果当前结点位置为i,则左孩子位置为2i 创建右子树,如果当前结点位置为i,则右孩子位置为2i+1 } 否则R为空 算法二:CopyTree(BiNode*sR,BiNode* &dR) ) 【1】算法功能:复制构造函数 【2】算法基本思想:按照先创建根结点,再递归创建左右子树的方法来实现。 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑: 如果源二叉树根结点不为空 则{ 创建根结点 调用函数自身,创建左子树 调用函数自身,创建右子树 } 将该函数放在复制构造函数中调用,就可以实现复制构造函数

算法三:PreOrder(BiNode*R) 【1】算法功能:二叉树的前序遍历 【2】算法基本思想:这个代码用的是优化算法,提前让当前结点出栈。【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑(伪代码) 如果当前结点为非空,则 { 访问当前结点 当前结点入栈 将当前结点的左孩子作为当前结点} 如果为空 { 则栈顶结点出栈 则将该结点的右孩子作为当前结点 } 反复执行这两个过程,直到结点为空并且栈空 算法四:InOrder(BiNode*R) 【1】算法功能:二叉树的中序遍历 【2】算法基本思想:递归 【3】算法空间时间复杂度分析:未知 【4】代码逻辑: 如果R为非空: 则调用函数自身遍历左孩子 访问该结点 再调用自身访问该结点的右孩子 算法五:LevelOrder(BiNode*R) 【1】算法功能:二叉树的层序遍历 【2】算法基本思想: 【3】算法空间时间复杂度分析:O(n) 【4】代码逻辑(伪代码): 若根结点非空,入队

数据结构实验三——二叉树基本操作及运算实验报告

《数据结构与数据库》 实验报告 实验题目 二叉树的基本操作及运算 一、需要分析 问题描述: 实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。 问题分析: 二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。处理本问题,我觉得应该:

1、建立二叉树; 2、通过递归方法来遍历(先序、中序和后序)二叉树; 3、通过队列应用来实现对二叉树的层次遍历; 4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等; 5、运用广义表对二叉树进行广义表形式的打印。 算法规定: 输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。 输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。对二叉树的一些运算结果以整型输出。 程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。 测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E 预测结果:先序遍历ABCDEGF 中序遍历CBEGDFA 后序遍历CGEFDBA 层次遍历ABCDEFG 广义表打印A(B(C,D(E(,G),F))) 叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2 查找5,成功,查找的元素为E 删除E后,以广义表形式打印A(B(C,D(,F))) 输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B 预测结果:先序遍历ABDEHCFG 中序遍历DBHEAGFC 后序遍历DHEBGFCA 层次遍历ABCDEFHG 广义表打印A(B(D,E(H)),C(F(,G))) 叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3 查找10,失败。

实验二叉树及其应用(严选材料)

实验6:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 1、 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算 a) 统计叶子结点的个数。 b) 求二叉树的深度。 2、 十进制的四则运算的计算器可以接收用户来自键盘的输入。 3、 由输入的表达式字符串动态生成算术表达式所对应的二叉树。 4、 自动完成求值运算和输出结果。 四、实验环境 PC 微机 DOS 操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; - + / a * b - e f C d

4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、功能分析 存储结构 typedef union{ int Operator; // 操作符 float Operand; // 操作数 }Int_Float; //表达式树 typedef struct BinaryTreeNode{ Int_Float Data; //数据域 int IsOperator; //判断是不是操作数的标志位 struct BinaryTreeNode *RChild;//左子树 struct BinaryTreeNode *LChild;//右子树 }BiTreeNode, *lpBiTreeNode; //栈的定义 typedef struct { lpBiTreeNode *base; lpBiTreeNode *top; int stacksize; }SqStack; 函数一览表 lpBiTreeNode GetTop( SqStack s );//取栈顶结点函数 int IsEmpty( SqStack s );//判空函数 int InitStack( SqStack &s );//初始化栈函数 int Pop( SqStack &s, lpBiTreeNode &e );//出栈函数 int Push( SqStack &s, lpBiTreeNode e );//入栈函数 int In( int c, int* op );// 判断c是否在op中 int Precede( int theta1, int theta2 );//比较运算符号的优先级 int isNum( int c );//判断是不是数 int GetInput(Int_Float *Result);//读入输入的数 lpBiTreeNode CreateBiTree();//创建二叉树 bool calculate(lpBiTreeNode Root, float *result);//计算二叉树化表达式的值int getLeafNum(lpBiTreeNode Root);//计算二叉树的叶子结点数

二叉树实验报告

实验题目:实验九——二叉树实验 算法设计(3) 问题分析: 1、题目要求:编写算法交换二叉树中所有结点的左右子树 2、设计思路:首先定义一个二叉树的数据类型,使用先序遍历建立该二叉树,遍历二叉树,设计左右子树交换的函数,再次遍历交换之后的二叉树,与先前二叉树进行比较。遍历算法与交换算法使用递归设计更加简洁。 3、测试数据: A、输入:1 2 4 0 0 5 0 0 3 0 0 交换前中序遍历:4 2 5 1 3 交换后中序遍历:3 1 5 2 4 交换前:交换后: B、输入:3 7 11 0 0 18 17 0 0 19 0 0 6 13 0 0 16 0 0 交换前中序遍历:11 7 17 18 19 3 13 6 16 交换后中序遍历:16 6 13 3 19 18 17 7 11 概要设计: 1、为了实现上述功能:①构造一个空的二叉树;②应用先序遍历输入,建立二叉树;③中序遍历二叉树;④调用左右子树交换函数;⑤中序遍历交换过后的二叉树。 2、本程序包括4个函数: ①主函数main() ②先序遍历二叉树建立函数creat_bt() ③中序遍历二叉树函数inorder() ④左右子树交换函数 exchange()

各函数间关系如下: 详细设计: 1、结点类型 typedef struct binode //定义二叉树 { int data; //数据域 struct binode *lchild,*rchild; //左孩子、右孩子 }binode,*bitree; 2、各函数操作 ① 先序遍历建二叉树函数 bitree creat_bt() { 输入结点数据; 判断是否为0{ 若是,为空; 不是,递归;} 返回二叉树; } ② 左右子树交换函数 void exchange(bitree t) { 判断结点是否为空{ 否,交换左右子树; 递归;} } ③ 中序遍历函数 void inorder(bitree bt) { 判断是否为空{ 递归左子树; 输出; 递归右子树;} } main () creat_bt () inorder () exchange ()

相关文档
最新文档