二叉树操作实验报告(精.选)

合集下载

二叉树实验报告

二叉树实验报告

二叉树实验报告二叉树实验报告引言:二叉树作为一种常用的数据结构,在计算机科学领域中具有广泛的应用。

本实验旨在通过实际操作和观察,深入理解二叉树的特性和运用。

一、二叉树的基本概念1.1 二叉树的定义二叉树是一种特殊的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

树的最顶层节点称为根节点。

1.2 二叉树的特点二叉树具有以下特点:- 每个节点最多有两个子节点,分别称为左子节点和右子节点;- 左子节点的值小于等于父节点的值,右子节点的值大于等于父节点的值;- 二叉树的左子树和右子树也是二叉树。

二、二叉树的遍历方式2.1 先序遍历先序遍历是指先访问根节点,然后按照先序遍历的方式依次访问左子树和右子树。

2.2 中序遍历中序遍历是指按照中序遍历的方式依次访问左子树,根节点和右子树。

2.3 后序遍历后序遍历是指按照后序遍历的方式依次访问左子树,右子树和根节点。

三、二叉树的实验操作3.1 二叉树的创建为了便于实验操作,我们选择使用Python编程语言来实现二叉树的创建和操作。

首先,我们需要定义一个二叉树节点的类,包含节点的值、左子节点和右子节点。

3.2 二叉树的插入在已有的二叉树中插入一个新的节点,需要遵循二叉树的规则。

如果插入的节点值小于当前节点的值,则将节点插入到当前节点的左子树;如果插入的节点值大于当前节点的值,则将节点插入到当前节点的右子树。

3.3 二叉树的查找在二叉树中查找一个特定的节点,需要遍历整个二叉树。

从根节点开始,如果要查找的节点值小于当前节点的值,则继续在左子树中查找;如果要查找的节点值大于当前节点的值,则继续在右子树中查找;如果要查找的节点值等于当前节点的值,则找到了目标节点。

3.4 二叉树的删除在二叉树中删除一个节点,需要考虑多种情况。

如果要删除的节点没有子节点,直接将其删除即可;如果要删除的节点只有一个子节点,将子节点替换为要删除的节点;如果要删除的节点有两个子节点,需要找到其右子树中的最小节点,将其值替换到要删除的节点,然后删除最小节点。

二叉排序树的实验报告

二叉排序树的实验报告

二叉排序树的实验报告二叉排序树的实验报告引言:二叉排序树(Binary Search Tree,简称BST)是一种常用的数据结构,它将数据按照一定的规则组织起来,便于快速的查找、插入和删除操作。

本次实验旨在深入了解二叉排序树的原理和实现,并通过实验验证其性能和效果。

一、实验背景二叉排序树是一种二叉树,其中每个节点的值大于其左子树的所有节点的值,小于其右子树的所有节点的值。

这种特性使得在二叉排序树中进行查找操作时,可以通过比较节点的值来确定查找的方向,从而提高查找效率。

二、实验目的1. 理解二叉排序树的基本原理和性质;2. 掌握二叉排序树的构建、插入和删除操作;3. 验证二叉排序树在查找、插入和删除等操作中的性能和效果。

三、实验过程1. 构建二叉排序树首先,我们需要构建一个空的二叉排序树。

在构建过程中,我们可以选择一个节点作为根节点,并将其他节点插入到树中。

插入节点时,根据节点的值与当前节点的值进行比较,如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

重复这个过程,直到所有节点都被插入到树中。

2. 插入节点在已有的二叉排序树中插入新的节点时,我们需要遵循一定的规则。

首先,从根节点开始,将新节点的值与当前节点的值进行比较。

如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

如果新节点的值与当前节点的值相等,则不进行插入操作。

3. 删除节点在二叉排序树中删除节点时,我们需要考虑不同的情况。

如果要删除的节点是叶子节点,即没有左右子树,我们可以直接删除该节点。

如果要删除的节点只有一个子树,我们可以将子树连接到要删除节点的父节点上。

如果要删除的节点有两个子树,我们可以选择将其右子树中的最小节点或左子树中的最大节点替代该节点,并删除相应的替代节点。

四、实验结果通过对二叉排序树的构建、插入和删除操作的实验,我们得到了以下结果:1. 二叉排序树可以高效地进行查找操作。

实验六 二叉树的基本操作实验报告

实验六  二叉树的基本操作实验报告

实验名称二叉树的基本操作实验日期实验成绩1、实验目的:1. 掌握二叉树链表的结构和二叉树的建立过程2. 掌握用递归方法实现二叉树遍历的操作2、实验内容:1、编写一个程序实现二叉树的各种运算,并完成如下功能:(1)输出二叉树b;(b为下图所示的二叉树)(2)输出H节点的左、右孩子节点值;(3)输出二叉树b的深度;(4)输出二叉树b的节点个数;(5)输出二叉树b的叶子节点个数;(6)释放二叉树b。

2、编写一个程序,实现二叉树的先序遍历、中序遍历和后序遍历的各种递归算法。

并以第1题图所示的二叉树b给出求解结果。

3、核心算法或代码片段:代码一:#include <stdio.h>#include <malloc.h>#define MaxSize 100typedef char ElemType;typedef struct node{ElemType data;//数据元素struct node *lchild;//指向左孩子struct node *rchild;//指向右孩子} BTNode;void CreateBTNode(BTNode *&b, char *str);void DispBTNode(BTNode *b);BTNode *FindNode(BTNode *b, ElemType x);BTNode *LchildNode(BTNode *p);BTNode *RchildNode(BTNode *p);int BTNodeDepth(BTNode *b);int Nodes(BTNode *b);int LeafNodes(BTNode *b);void DestroyBTNode(BTNode *&b);void CreateBTNode(BTNode *&b, char *str)//由str串创建二叉链{BTNode *St[MaxSize], *p = NULL;int top = -1, k, j = 0;char ch;b = NULL;//建立的二叉树初始时为空ch = str[j];while (ch != '\0')//str未扫描完时循环{switch (ch){case '(':top++; St[top] = p; k = 1; break;//为左节点case ')':top--; break;case ',':k = 2; break; //为右节点default:p = (BTNode *)malloc(sizeof(BTNode));p->data = ch; p->lchild = p->rchild = NULL;if (b == NULL) //p指向二叉树的根节点b = p;else //已建立二叉树根节点{switch (k){case 1:St[top]->lchild = p; break;case 2:St[top]->rchild = p; break;}}}j++;ch = str[j];}}void DispBTNode(BTNode *b)//以括号表示法输出二叉树{if (b != NULL){printf("%c", b->data);if (b->lchild != NULL || b->rchild != NULL){printf("(");DispBTNode(b->lchild);if (b->rchild != NULL) printf(",");DispBTNode(b->rchild);printf(")");}}}BTNode *FindNode(BTNode *b, ElemType x)//返回data域为x的节点指针{BTNode *p;if (b == NULL)return NULL;else if (b->data == x)return b;else{p = FindNode(b->lchild, x);if (p != NULL)return p;elsereturn FindNode(b->rchild, x);}}BTNode *LchildNode(BTNode *p)//返回*p节点的左孩子节点指针{return p->lchild;}BTNode *RchildNode(BTNode *p)//返回*p节点的右孩子节点指针{return p->rchild;}int BTNodeDepth(BTNode *b)//求二叉树b的深度{int lchilddep, rchilddep;if (b == NULL)return(0); //空树的高度为0 else{lchilddep = BTNodeDepth(b->lchild);//求左子树的高度为lchilddeprchilddep = BTNodeDepth(b->rchild);//求右子树的高度为rchilddepreturn (lchilddep>rchilddep) ? (lchilddep + 1) : (rchilddep + 1);}}int Nodes(BTNode *b)//求二叉树b的节点个数{int num1, num2;if (b == NULL)return 0;else if (b->lchild == NULL && b->rchild == NULL)return 1;else{num1 = Nodes(b->lchild);num2 = Nodes(b->rchild);return (num1 + num2 + 1);}}int LeafNodes(BTNode *b)//求二叉树b的叶子节点个数{int num1, num2;if (b == NULL)return 0;else if (b->lchild == NULL && b->rchild == NULL)return 1;else{num1 = LeafNodes(b->lchild);num2 = LeafNodes(b->rchild);return (num1 + num2);}}void DestroyBTNode(BTNode *&b) //摧毁树{if (b != NULL){DestroyBTNode(b->lchild);DestroyBTNode(b->rchild);free(b);}}int main(){BTNode *b, *p, *lp, *rp;;CreateBTNode(b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");printf("二叉树的基本运算如下:\n");printf(" (1)输出二叉树:"); DispBTNode(b); printf("\n");printf(" (2)H节点:");p = FindNode(b, 'H');if (p != NULL){lp = LchildNode(p);if (lp != NULL)printf("左孩子为%c ", lp->data);elseprintf("无左孩子");rp = RchildNode(p);if (rp != NULL)printf("右孩子为%c", rp->data);elseprintf("无右孩子");}printf("\n");printf(" (3)二叉树b的深度:%d\n", BTNodeDepth(b));printf(" (4)二叉树b的节点个数:%d\n", Nodes(b));printf(" (5)二叉树b的叶子节点个数:%d\n", LeafNodes(b));printf(" (6)释放二叉树b\n");DestroyBTNode(b);return 0;}代码二:#include<iostream>#define maxsize 50using namespace std;class node{private:char data;node* lchild;node* rchild;public:void createnode(node *&,char *);//先序遍历void fnode(node* b){if(b!=NULL){cout << b->data ;fnode(b->lchild);fnode(b->rchild);}}//中序遍历void mnode(node* b){if(b!=NULL){mnode(b->lchild);cout << b->data ;mnode(b->rchild);}}//后序遍历void lnode(node* b){if(b!=NULL){lnode(b->lchild);lnode(b->rchild);cout << b->data ;}}void fnode1(node *);void mnode1(node *);void lnode1(node *);void all(node *);};void node::createnode(node* &b,char* a) {node *st[maxsize],*p;int top=-1,k,j=0;char ch;b=NULL;ch=a[j];while(ch!='\0'){switch(ch){case '(':top++;st[top]=p;k=1;break;case ')':top--;break;case ',':k=2;break;default:p=new node;p->data=ch;p->lchild=p->rchild=NULL;if(b==NULL){b=p;}else{switch(k){case 1:st[top]->lchild=p;break;case 2:st[top]->rchild=p;break;}}}j++;ch=a[j];}}int main(){node *b;char a[]="A(B(D,E(H(J,K(L,M(,N))),)),C(F,G(,I)))";b->createnode(b,a);cout << "递归先序编历:";b->fnode(b);cout << endl ;cout << "递归中序编历:";b->mnode(b);cout << endl ;cout << "递归后序编历:";b->lnode(b);cout << endl ;cout << endl ;}一:二:总结体会:在第一个实验对树的操作,利用树广义表的表示法输入一个str,对str进行遍历,通过对括号和字母的判断创建二叉树CreateBTNode(),输出二叉树DispBTNode()同样采用广义表表示法,在找寻某一结点的左右孩子结点首先FindNode()对是否存在左右孩子,由于该二叉树存储采用的二叉链表所以通过指针指向输出左右孩子,在输出二叉树DispBTNode(),找左右孩子FindNode(),计算深度BTNodeDepth(),计算结点数Nodes(),都采用了函数的递归,都是利用左右孩子指针进行操作,进行对整个数的遍历。

二叉树的操作实验报告

二叉树的操作实验报告

二叉树的操作实验报告二叉树的操作实验报告引言二叉树是计算机科学中常用的数据结构,它具有良好的搜索性能和灵活的插入和删除操作。

本实验旨在通过实际操作,深入理解二叉树的基本操作和特性。

1. 二叉树的定义和基本概念二叉树是一种特殊的树状结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

二叉树的节点由数据和指向左右子节点的指针组成。

根据节点的位置,可以将二叉树分为左子树、右子树和根节点。

2. 二叉树的遍历二叉树的遍历是指按照一定的顺序访问二叉树中的所有节点。

常用的遍历方式有前序遍历、中序遍历和后序遍历。

前序遍历先访问根节点,然后按照左子树、右子树的顺序遍历;中序遍历先访问左子树,然后根节点,最后右子树;后序遍历先访问左子树,然后右子树,最后根节点。

3. 二叉树的插入操作插入操作是将一个新节点插入到二叉树中的特定位置。

插入操作需要考虑节点的大小关系,小于当前节点则插入到左子树,大于当前节点则插入到右子树。

插入操作可以保持二叉树的有序性。

4. 二叉树的删除操作删除操作是将指定节点从二叉树中删除。

删除操作需要考虑被删除节点的子节点情况,如果被删除节点没有子节点,则直接删除;如果有一个子节点,则将子节点替代被删除节点的位置;如果有两个子节点,则选择被删除节点的后继节点或前驱节点替代被删除节点。

5. 二叉树的查找操作查找操作是在二叉树中搜索指定的节点。

二叉树的查找操作可以使用递归或迭代的方式实现。

递归方式会自动遍历整个二叉树,直到找到目标节点或遍历完整个树。

迭代方式则需要手动比较节点的值,并根据大小关系选择左子树或右子树进行进一步查找。

6. 二叉树的平衡性二叉树的平衡性是指左子树和右子树的高度差不超过1。

平衡二叉树可以提高搜索效率,避免出现极端情况下的性能下降。

常见的平衡二叉树有AVL树和红黑树。

7. 二叉树应用场景二叉树在计算机科学中有广泛的应用场景。

例如,文件系统的目录结构可以使用二叉树来表示;数据库中的索引结构也可以使用二叉树来实现。

实验报告(二叉树)

实验报告(二叉树)

实验报告课程:数据结构(c语言)实验名称:二叉树的构建、基本操作和遍历系别:数字媒体技术实验日期:专业班级:媒体161 组别:无:学号:实验报告容验证性实验一、预习准备:实验目的:1、熟练掌握二叉树的结构特性,熟悉二叉树的各种存储结构的特点及适用围;2、熟练掌握二叉树的遍历方法及遍历算法;3、掌握建立哈夫曼树和哈夫曼编码的方法及带权路径长度的计算。

实验环境:Widows操作系统、VC6.0实验原理:1.定义:树:树(tree)是n(n>0)个结点的有限集T,其中,有且仅有一个特定的结点,称为树的根(root)。

当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,……Tm,其中每一个集合本身又是一棵树,称为根的子树(subtree)二叉树:二叉树是n(n>=0)个结点的有限集,它或为空树(n=0),或由一个根结点和两棵分别称为左子树和右子树的互不相交的二叉树构成。

哈夫曼树: 最优二叉树——赫夫曼树设有n个权值{w1,w2,……wn},构造一棵有n个叶子结点的二叉树,每个叶子的权值为wi,则wpl最小的二叉树叫Huffman树。

2. 特点:树:树中至少有一个结点——根树中各子树是互不相交的集合二叉树:每个结点至多有二棵子树(即不存在度大于2的结点)二叉树的子树有左、右之分,且其次序不能任意颠倒哈夫曼树:一棵有n个叶子结点的Huffman树有2n-1个结点采用顺序存储结构——动态分配数组存储3. 表示:遍历二叉树:先序遍历:先访问根结点,然后分别先序遍历左子树、右子树中序遍历:先中序遍历左子树,然后访问根结点,最后中序遍历右子树后序遍历:先后序遍历左、右子树,然后访问根结点 按层次遍历:从上到下、从左到右访问各结点 构造Huffman 树的方法——Huffman 算法(1) 根据给定的n 个权值{w1,w2,……wn},构造n 棵只有根 结点的二叉树,令起权值为wj ;(2) 在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和;(3) 在森林中删除这两棵树,同时将新得到的二叉树加入森林中重复上述两步,直到只含一棵树为止,这棵树即哈夫曼树。

[精品]【数据结构】二叉树实验报告

[精品]【数据结构】二叉树实验报告

[精品]【数据结构】二叉树实验报告二叉树实验报告一、实验目的:1.掌握二叉树的基本操作;2.理解二叉树的性质;3.熟悉二叉树的广度优先遍历和深度优先遍历算法。

二、实验原理:1.二叉树是一种树形结构,由n(n>=0)个节点组成;2.每个节点最多有两个子节点,称为左子节点和右子节点;3.二叉树的遍历分为四种方式:前序遍历、中序遍历、后序遍历和层次遍历。

三、实验环境:1.编程语言:C++;2.编译器:Dev-C++。

四、实验内容:1.定义二叉树节点结构体:struct BinaryTreeNode{int data; // 节点数据BinaryTreeNode *leftChild; // 左子节点指针BinaryTreeNode *rightChild; // 右子节点指针};2.初始化二叉树:queue<BinaryTreeNode *> q; // 使用队列存储节点q.push(root);int i = 1; // 创建子节点while (!q.empty() && i < length){BinaryTreeNode *node = q.front();q.pop();if (data[i] != -1) // 创建左子节点 {BinaryTreeNode *leftChild = new BinaryTreeNode;leftChild->data = data[i];leftChild->leftChild = nullptr;leftChild->rightChild = nullptr;node->leftChild = leftChild;q.push(leftChild);}i++;if (data[i] != -1) // 创建右子节点 {BinaryTreeNode *rightChild = new BinaryTreeNode;rightChild->data = data[i];rightChild->leftChild = nullptr;rightChild->rightChild = nullptr;node->rightChild = rightChild;q.push(rightChild);}i++;}return root;}3.前序遍历二叉树:五、实验结果:输入:int data[] = {1, 2, 3, 4, -1, -1, 5, 6, -1, -1, 7, 8};输出:前序遍历结果:1 2 4 5 3 6 7 8中序遍历结果:4 2 5 1 6 3 7 8后序遍历结果:4 5 2 6 8 7 3 1层次遍历结果:1 2 3 4 5 6 7 8通过本次实验,我深入理解了二叉树的性质和遍历方式,并掌握了二叉树的基本操作。

(完整版)C++二叉树基本操作实验报告

(完整版)C++二叉树基本操作实验报告

、实验目的选择二叉链式存储结构作为二叉树的存储结构,设计一个程序实现二叉树的基本操作(包括建立、输出、前序遍历、中序遍历、后序遍历、求树高、统计叶子总数等)二、实验开发环境Windows 8.1 中文版Microsoft Visual Studio 6.0三、实验内容程序的菜单功能项如下:1 -- 建立一棵二叉树2 -- 前序遍历递归算法3 -- 前序遍历非递归算法4 -- 中序遍历递归算法5 -- 中序遍历非递归算法6 ---- 后序遍历递归算法7 ---- 后序遍历非递归算法8 ---- 求树高9 -- 求叶子总数10 - 输出二叉树11 - 退出四、实验分析1、建立一棵二叉树2、输入二叉树各节点数据coutvv"请按正确顺序输入二叉树的数据:";cin.getline(t,1000); //先把输入的数据输入到一个t 数组3、递归前序遍历void BL1(ECS_data *t) {if(NULL!=t){cout<<t->data<<",";BL1(t->l);BL1(t->r);}}4、非递归前序遍历void preOrder2(ECS_data *t){ stack<ECS_data*> s; ECS_data *p=t; while(p!=NULL||!s.empty()) { while(p!=NULL){cout<<p->data<<" ";s.push(p); p=p->l;} if(!s.empty()){p=s.top(); s.pop(); p=p->r;}}}5、递归中序遍历void BL2(ECS_data *t) {if(NULL!=t){BL2(t->l);cout<<t->data<<",";BL2(t->r);}}6、非递归中序遍历void inOrder2(ECS_data *t) //非递归中序遍历{stack<ECS_data*> s;ECS_data *p=t; while(p!=NULL||!s.empty()){while(p!=NULL){s.push(p);p=p->l;}if(!s.empty()){p=s.top(); cout<<p->data<<" "; s.pop();p=p->r;}7、递归后序遍历void BL3(ECS_data *t) {if(NULL!=t){BL3(t->l);BL3(t->r); cout<<t->data<<",";8、非递归后序遍历void postOrder3(ECS_data *t){stack<ECS_data*> s;ECS_data *cur; //当前结点ECS_data *pre=NULL; // 前一次访问的结点s.push(t);while(!s.empty()){cur=s.top();if((cur->l==NULL&&cur->r==NULL)||(pre!=NULL&&(pre==cur->l||pre==cur->r))){cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过s.pop();pre=cur;}else{if(cur->r!=NULL)s.push(cur->r);if(cur->l!=NULL)s.push(cur->l);}}}9、求树高int Height (ECS_data *t) {if(t==NULL) return 0; else{int m = Height ( t->l );int n = Height(t->r);return (m > n) ? (m+1) : (n+1); }10、求叶子总数int CountLeaf(ECS_data *t){static int LeafNum=O;//叶子初始数目为0,使用静态变量if(t)// 树非空{if(t->l==NULL&&t->r==NULL)// 为叶子结点LeafNum++;// 叶子数目加 1 else//不为叶子结点{Cou ntLeaf(t->l);//递归统计左子树叶子数目 Cou ntLeaf(t->r);//递归统计右子树叶子数目 }}return LeafNum; }五、运行结果附:完整程序源代码: 〃二叉树链式存储的实现#in cludeviostream> #in clude<cstri ng>#in elude <stack> using n ames pace std; struct ECS_data //先定义好一个数据的结构 {char data;ECS_data *l; ECS_data *r; };" //树高//表示有多少个节点数〃表示的是数组的总长度值,(包括#),因为后面要class ECS {P rivate://in t level; int n; int n1;} }ECS_data *temp[1000];public: ECS_data *root; ECS() // 初始化 {ECS_data *p; char t[1000];int i; int front=0,rear=1;入的点的父母 //front 表示有多少个节点, rear 表示当前插 coutvv"请按正确顺序输入二叉树的数据:"; cin.getline(t,1000); //cout<<t<<" "<<endl;int n1=strlen(t); n=0; for(i=0;i<n1;i++) {if(t[i]!='#') {//先把输入的数据输入到一个 t 数组 //测量数据的长度p=NULL;if(t[i]!=',') {n++;p=new ECS_data; p->data=t[i]; p->l=NULL; p->r=NULL; } front++;temp[front]=p; if(1 ==front){root=p;} else{//满足条件并开辟内存if((p!=NULL)&&(0==front%2)) {temp[rear]->l=p;// 刚开始把这里写成了 == }if((p!=NULL)&&(1==front%2)) {temp[rear]->r=p; }if(1==front%2)rear++;//就当前的数据找这个数据的父母}} }}~ECS(){int i;for(i=1;i<=n;i++) if(temp[i]!=NULL) delete temp[i]; } void JS() {int s; s=n;coutvv"该二叉树的节点数为:"vvsvvendl; }void BL1(ECS_data *t)// 递归前序遍历 {if(NULL!=t){cout<<t->data<<","; BL1(t->l); BL1(t->r);}void preOrder2(ECS_data *t) //非递归前序遍历{stack<ECS_data*> s; ECS_data *p=t;while(p!=NULL||!s.empty()){while(p!=NULL){cout<<p->data<<" "; s.push(p); p=p->l;}if(!s.empty()){p=s.top(); s.pop(); p=p->r;//释放内存//记录节点的个数if(NUL匚丛)宀BL2(e_)-coufAvdafaAfr BL2(g-voidino ‘de ‘2(Ecslda応J )二卅融丘甘甸壷逗宀sfackAECSIdafa*vs 八 ECSIdafa *P H Cwhi-e(p一 hnul匚-一 s.empfyo) 宀wh=e(p一"NULL)宀s.push(p)八PHP —vrif (一s.empfyo)宀PHSlopucoufAAP —vdafaAAs.popwPHP*voidBL3(Ecsldafa *U 1融&训引筍已宀if(NUL匚丛)宀BL3(e_)- BL3(g- coufAAf —vdafaAdrvoidposfo ‘de ‘3(Ecsldafa *0&可甸壷逗 宀sfackAECSIdafa*vs 八ECSIdafa*cucm 遡璋、的ECSIdafa*p‘eHNUF二遡—舟曲亘兼叫、的s.push(t);while(!s.empty()){cur=s.top();if((cur->l==NULL&&cur->r==NULL)||(pre!=NULL&&(pre==cur->l||pre==cur->r))){ cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过s.pop(); pre=cur;}else{if(cur->r!=NULL)s.push(cur->r);if(cur->l!=NULL)s.push(cur->l);}}}int Height (ECS_data *t) //求树高{if(t==NULL) return 0; else{int m = Height ( t->l );int n = Height(t->r);return (m > n) ? (m+1) : (n+1);}}int CountLeaf(ECS_data *t) //求叶子总数{static int LeafNum=0;//叶子初始数目为0,使用静态变量if(t)//树非空{if(t->l==NULL&&t->r==NULL)// 为叶子结点LeafNum++;//叶子数目加1else//不为叶子结点{CountLeaf(t->l);// 递归统计左子树叶子数目Cou ntLeaf(t->r);//递归统计右子树叶子数目}}return LeafNum; }};int main(){ECS a;a.JS();coutvv"递归前序遍历:";a.BL1(a.root);cout<<endl;coutvv"非递归前序遍历:";a.preOrder2(a.root);coutvvendl;coutvv"递归中序遍历:";a.BL2(a.root);coutvvendl;coutvv"非递归中序遍历:";a.inOrder2(a.root);coutvvendl;coutvv"递归后序遍历:";a.BL3(a.root);coutvvendl;coutvv"非递归后序遍历:";a.postOrder3(a.root);coutvvendl;coutvv"树高为:"vva.Height(a.root)vvendl;coutvv"叶子总数为:"vva.CountLeaf(a.root)vvendl; return 0; }。

二叉树操作设计和实现实验报告

二叉树操作设计和实现实验报告

二叉树操作设计和实现实验报告一、目的:掌握二叉树的定义、性质及存储方式,各种遍历算法。

二、要求:采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序以及按层次遍历的操作,求所有叶子及结点总数的操作。

三、实验内容:1、分析、理解程序程序的功能是采用二叉树链表存储结构,完成二叉树的建立,先序、中序和后序以及按层次遍历的操作。

如输入二叉树ABD###CE##F##,链表示意图如下:2、添加中序和后序遍历算法//========LNR 中序遍历===============void Inorder(BinTree T){if(T){Inorder(T->lchild);printf("%c",T->data);Inorder(T->rchild);}}//==========LRN 后序遍历============void Postorder(BinTree T){if(T){Postorder(T->lchild);Postorder(T->rchild);printf("%c",T->data);}}3、调试程序,设计一棵二叉树,输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树,求出先序、中序和后序以及按层次遍历序列,求所有叶子及结点总数。

(1)输入完全二叉树的先序序列ABD###CE##F##,程序运行结果如下:(2)先序序列:(3)中序序列:(4)后序序列:(5)所有叶子及结点总数:(6)按层次遍历序列:四、源程序代码#include"stdio.h"#include"string.h"#include"stdlib.h"#define Max 20 //结点的最大个数typedef struct node{char data;struct node *lchild,*rchild;}BinTNode; //自定义二叉树的结点类型typedef BinTNode *BinTree; //定义二叉树的指针int NodeNum,leaf; //NodeNum为结点数,leaf为叶子数//==========基于先序遍历算法创建二叉树==============//=====要求输入先序序列,其中加入虚结点"#"以示空指针的位置========== BinTree CreatBinTree(void){BinTree T;char ch;if((ch=getchar())=='#')return(NULL); //读入#,返回空指针else{T=(BinTNode *)malloc(sizeof(BinTNode)); //生成结点T->data=ch;T->lchild=CreatBinTree(); //构造左子树T->rchild=CreatBinTree(); //构造右子树return(T);}}//========NLR 先序遍历=============void Preorder(BinTree T){if(T) {printf("%c",T->data); //访问结点Preorder(T->lchild); //先序遍历左子树Preorder(T->rchild); //先序遍历右子树}}//========LNR 中序遍历===============void Inorder(BinTree T){if(T){Inorder(T->lchild);printf("%c",T->data);Inorder(T->rchild);}}//==========LRN 后序遍历============void Postorder(BinTree T){if(T){Postorder(T->lchild);Postorder(T->rchild);printf("%c",T->data);}}//=====采用后序遍历求二叉树的深度、结点数及叶子数的递归算法======== int TreeDepth(BinTree T){int hl,hr,max;if(T){hl=TreeDepth(T->lchild); //求左深度hr=TreeDepth(T->rchild); //求右深度max=hl>hr? hl:hr; //取左右深度的最大值NodeNum=NodeNum+1; //求结点数if(hl==0&&hr==0) leaf=leaf+1; //若左右深度为0,即为叶子。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(7)将当前对头出栈,len++,打印出队元素
(8)如果出队元素的左子树的根节点不为空则入队,len--.
(9)如果出队元素的右子树的根节点不为空则入队,len--.
4、
(1)利用指针temp指向根节点,并初始化一个队列。
(2)将temp指向的当点节点入队。并声明当前层最大节点数为0
(3)重复指向以下所有步骤,直到遇到break语句。若遇到break语句则结束整个程序并返回最大节点数。
}
if(top <= 0)return;
top--;
p = Stack[top];
printf("%c",p->data);
p = p->rchild;
}
}
intmain()
{
BitNode *root;
root = CreateTree();
printf("前序遍历结果");
PreOrder(root);
2、在前序遍历的过程中利用中间变量交换左右子树。
3、利用队列。当上一层中的数据全部出队(遍历)完毕再遍历本层节点。
4、高度:获取所有节点到根节点的最长路径。宽度:在层次遍历的基础上,返回最多节点的层的节点数。
算法描述:可以用自然语言、伪代码或流程图等方式
1、创建树:
(1)声明节点
(2)输入当前节点,若输入为#则当前节点为空,否则为当前节点申请空间。
InOrder(T->lchild);
printf("%c",T->data);
InOrder(T->rchild);
}
BitTree *Exchange(BitTree *T)
{
BitTree *temp;
if(T == NULL)returnNULL;
temp = T->lchild;
T->lchild = T->rchild;
(4)用变量len记录队列中二叉树当前层的节点数。
(5)若len为0则结束整个程序,否则执行第六步。
(6)当len>0(即队列中还有前层的节点时)重复七~九步。否则执行第十步。
(7)将当前对头出栈,len++,打印出队元素
(8)如果出队元素的左子树的根节点不为空则入队,len--.
(9)如果出队元素的右子树的根节点不为空则入队,len--.
(2)后序遍历当前节点的左子树。
(3)后序遍历当前节点的右子树。
(3)打印当前节点的data。
2、
(1)若当前节点为空则返回NULL,结束。否则执行下一步。
(2)利用中间变量temp交换当前节点的左右子树。
(3)交换当前的点左子树根节点的左右子树。
(4)交换当前节点右子树根节点的左右子树。
(4)返回根节点。
二、实验题目与要求
1.每位同学按下述要求实现相应算法:以二叉链表为存储结构,实现二叉树的创建、遍历算法
1)问题描述:在主程序中提供下列菜单:
1…建立树
2…前序遍历树
3…中序(非递归)遍历树
4…后序遍历树0…结束
2)实验要求:
①定义下列过程:
CreateTree():按从键盘输入的前序序列,创建树
PreOrderTree():前序遍历树(递归)
InOrderTree():中序(非递归)遍历树
LaOrderTree():后序遍历树(递归)
②每位同学在实验过程中要单步运行程序,跟踪二叉树的创建过程与前序遍历的递归过程。
3)注意问题:
①注意理解递归算法的执行步骤。
②注意字符类型数据在输入时的处理。
③重点理解如何利用栈结构实现非递归算
2.编写算法交换二叉树中所有结点的左、右子树
T->lchild = CreateTree();
T->rchild = CreateTree();
}
returnT;
}
voidPreOrder(BitNode *T)
{
if(T == NULL)return;
printf("%c",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
3、
(1)利用指针temp指向根节点,并初始化一个队列。
(2)将temp指向的当点节点入队。
(3)重复指向以下所有步骤,直到遇到break语句。
(4)用变量len记录队列中二叉树当前层的节点数。
(5)若len为0则结束整个程序,否则执行第六步。
(6)当len>0(即队列中还有前层的节点时)重复指向以下所有步骤。否则执行第三步。
printf("\n");
printf("中序遍历结果");
InOrder(root);
printf("\n");
printf("后序遍历结果");
PostOrder(root);
printf("\n");
return0;
}
2、
#include<stdio.h>
#include<stdlib.h>
typedefcharElemtype;
1)问题描述:编写一算法,交换二叉树中所有结点的左、右子树
2)实验要求:以二叉链表作为存储结构
3.试编写按层次顺序遍历二叉树的算法
1)问题描述:编写按层次顺序遍历二叉树的算法
2)实验要求:以二叉链表作为存储结构
4.编写算法求二叉树高度及宽度。
1)问题描述:二叉树高度是指树中所有节点的最大层数,二叉树宽度是指在二叉树的各层上,具有节点数最多的那一层上的节点总数。
输出:
4、
输入:ABH##FD###E#CK##G##
输出:
算法时间复杂度分析
1、O(n).
2、O(n).
3、O(n).
4、O(n).
四、收获与体会
学了二叉树之后顿时感觉之前的内容有多简单了。二叉树中用到很多递归算法,看起来很难懂。需要一步一步的跟下去才能理解,但是理解还远远不够,关键是是自己能写出来属于自己的递归算法。经过长时间的练习,我已经能写出来一些简单的递归算法了,但是稍微难一点的就写不出来了。后面的图还更难。革命尚未成功,诸君还需努力呐。我相信经过自己不屑的练习,我会提高的!
printf("\n中序遍历交换后的二叉树:");
InOrder(root);
printf("\n");
return0;
}
3、
#include<stdio.h>
#include<stdlib.h>
#defineMaxSize 100
typedefcharElemtype;
typedefstructBitTree
}
voidPostOrder(BitNode *T)
{
if(T == NULL)return;
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%c",T->data);
}
voidInOrder(BitNode *T)
{
BitNode *p,*q;
BitNode *Stack[MaxSize];
(3)将输入的值赋给当前节点的data域,并前序建立当前节点的左子树和右子树。
(4)返回当前节点。
前序遍历树:
(1)若当前节点为空则返回上一级函数,否则打印当前节点。
(2)前序遍历当前节点的左子树。
(3)前序遍历当前节点的右子树。
中序遍历树:
(1)声明一个顺序栈,并用p指针指向当前节点。
(2)若当前节点和栈不同时为空则重复进行下一步。否则程序结束
{
Elemtype data;
structBitTree *lchild;
structBitTree *rchild;
}BitTree;
typedefBitTree Elementtype;
typedefstructQueueNode
{
Elementtype *base;
intfront;
intrear;
实验报告
学院(系)名称:计算机与通信工程学院
姓名
* *
学号
********
专业
计算机科学与技术
班级
2015级*班
实验项目
实验三:二叉树操作
课程名称
数据结构与算法
课程代码
0661013
实验时间
年月日第节
实验地点
7-***
考核标准
实验过程
25分
程序运行
20分
回答问题
15分
实验报告
30分
特色
功能
5分
考勤违纪情况
inttop = 0;
p = T;
while(!(p == NULL && top == 0))
{
while(p != NULL)
{
if(top < MaxSize-1)
{
Stack[top] = p;
top++;
}else{
printf("栈溢出");
exit(0);
}
p = p->lchild;
(10)当前层最大节点数等于上一层最大节点数和当前队列中的节点数中较大的一个。
执行第三步。
算法的实现和测试结果:包括算法运行时的输入、输出,实验中出现的问题及解决办法等
相关文档
最新文档