数据结构-实验五讲义(1)-二叉树的基本操作

合集下载

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

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

数据结构实验报告实验五二叉树的操作班级:12卓越6班学号:***********名:***任课教师:***计算机与信息工程学院2014年5月13 日实验五二叉树的操作一、实验目的1.进一步掌握指针变量、动态变量的含义;2.掌握二叉树的结构特征,以及各种存储结构的特点及适用范围;3.掌握用指针类型描述、访问和处理二叉树的运算。

二、实验要求1.按实验内容编写实验的程序,主程序以菜单形式运行。

2.上机调试运行本程序。

3.保存和打印出程序的运行结果,并结合程序进行分析。

4.提交源程序和运行结果。

三、实验内容1.创建以二叉链表作存储结构的二叉树;2.按中序遍历二叉树;3.按层次遍历二叉树;4.计算二叉树的单枝结点数;5.交换二叉树的左右子树。

解://声明类BiTree及定义结构BiNode,文件名为bitree.h#ifndef BITREE_H#define BITREE_H//int num;template <class T>struct BiNode //二叉树的结点结构{T data;BiNode<T> *lchild, *rchild;};template <class T>class BiTree{public:BiTree( ); //构造函数,初始化一棵二叉树,其前序序列由键盘输入~BiTree(void); //析构函数,释放二叉链表中各结点的存储空间BiNode<T>* Getroot(); //获得指向根结点的指针void PreOrder(BiNode<T> *root); //前序遍历二叉树void InOrder(BiNode<T> *root); //中序遍历二叉树void PostOrder(BiNode<T> *root); //后序遍历二叉树void LeverOrder(BiNode<T> *root); //层序遍历二叉树int depth(BiNode<T> *root); //求二叉树的深度void nodenum(BiNode<T> *root); //求二叉树的结点个数void leafnum(BiNode<T> *root); //求二叉树的叶子结点个数void empty( ); //判断二叉树是否为空int printnum( ); // 输出(全部、叶子或单分支)结点数void sbnodenum(BiNode<T> *root); //求二叉树的单分支结点个数void exchangetree(BiNode<T> *root); //交换二叉树的左右子树private:BiNode<T> *root; //指向根结点的头指针BiNode<T> *p;BiNode<T> *Creat( ); //有参构造函数调用void Release(BiNode<T> *root); //析构函数调用int num;};#endif//定义类中的成员函数,文件名为bitree.cpp#include<iostream>#include<string>#include"bietree.h"using namespace std;/**前置条件:二叉树不存在*输入:无*功能:构造一棵二叉树*输出:无*后置条件:产生一棵二叉树*/template<class T>BiTree<T>::BiTree( ){this->num=0;this->root = Creat( );}/**前置条件:二叉树已存在*输入:无*功能:释放二叉链表中各结点的存储空间*输出:无*后置条件:二叉树不存在*/template<class T>BiTree<T>::~BiTree(void){Release(root);}*前置条件:二叉树已存在*输入:无*功能:获取指向二叉树根结点的指针*输出:指向二叉树根结点的指针*后置条件:二叉树不变*/template<class T>BiNode<T>* BiTree<T>::Getroot( ){return root;}/**前置条件:二叉树已存在*输入:无*功能:前序遍历二叉树*输出:二叉树中结点的一个线性排列*后置条件:二叉树不变*/template<class T>void BiTree<T>::PreOrder(BiNode<T> *root) {if(root==NULL) return;else{cout<<root->data<<" ";PreOrder(root->lchild);PreOrder(root->rchild);}}*前置条件:二叉树已存在*输入:无*功能:中序遍历二叉树*输出:二叉树中结点的一个线性排列*后置条件:二叉树不变*/template <class T>void BiTree<T>::InOrder (BiNode<T> *root){if (root==NULL) return; //递归调用的结束条件else{InOrder(root->lchild); //中序递归遍历root的左子树cout<<root->data<<" "; //访问根结点的数据域InOrder(root->rchild); //中序递归遍历root的右子树}}/**前置条件:二叉树已存在*输入:无*功能:后序遍历二叉树*输出:二叉树中结点的一个线性排列*后置条件:二叉树不变*/template <class T>void BiTree<T>::PostOrder(BiNode<T> *root){if (root==NULL) return; //递归调用的结束条件else{PostOrder(root->lchild); //后序递归遍历root的左子树PostOrder(root->rchild); //后序递归遍历root的右子树cout<<root->data<<" "; //访问根结点的数据域}}/**前置条件:二叉树已存在*输入:无*功能:层序遍历二叉树*输出:二叉树中结点的一个线性排列*后置条件:二叉树不变*/template <class T>void BiTree<T>::LeverOrder(BiNode<T> *root){const int MaxSize = 100;int front = 0;int rear = 0; //采用顺序队列,并假定不会发生上溢BiNode<T>* Q[MaxSize];BiNode<T>* q;if (root==NULL) return;else{Q[rear++] = root;while (front != rear){q = Q[front++];cout<<q->data<<" ";if (q->lchild != NULL) Q[rear++] = q->lchild;if (q->rchild != NULL) Q[rear++] = q->rchild;}}}/**前置条件:空二叉树*输入:数据ch;*功能:初始化一棵二叉树,构造函数调用*输出:无*后置条件:产生一棵二叉树*/template <class T>BiNode<T>* BiTree<T>::Creat( ){BiNode<T>* root;T ch;cout<<"请输入创建一棵二叉树的结点数据"<<endl;cin>>ch;if (ch=="#") root = NULL;else{root = new BiNode<T>; //生成一个结点root->data=ch;root->lchild = Creat( ); //递归建立左子树root->rchild = Creat( ); //递归建立右子树}return root;}/**前置条件:二叉树已经存在*输入:无*功能:释放二叉树的存储空间,析构函数调用*输出:无*后置条件:二叉树不存在*/template<class T>void BiTree<T>::Release(BiNode<T>* root){if (root != NULL){Release(root->lchild); //释放左子树Release(root->rchild); //释放右子树delete root;}}/**前置条件:二叉树已经存在*输入:无*功能:求二叉树的深度*输出:二叉树的深度*后置条件:二叉树不变*/template<class T>int BiTree<T>::depth(BiNode<T> *root){int n,m;if(root==NULL) return 0;else{n=depth(root->lchild); //左子树的深度m=depth(root->rchild); //右子树的深度if (n>m)return n+1;elsereturn m+1;}}/**前置条件:二叉树已经存在*输入:无*功能:求二叉树的结点个数*输出:二叉树的结点个数*后置条件:二叉树不变*/template<class T>void BiTree<T>::nodenum(BiNode<T> *root){if(root==NULL) return;else{num++;nodenum(root->lchild); //左子树的结点个数nodenum(root->rchild); //右子树的结点个数}}*前置条件:二叉树已经存在*输入:无*功能:求二叉树2 的叶子结点个数*输出:二叉树的叶子结点个数*后置条件:二叉树不变*/template<class T>void BiTree<T>::leafnum(BiNode<T> *root){if(root==NULL) return;else{if(!(root->lchild) && !(root->rchild)) //判断是否为叶子结点num++;leafnum(root->lchild); //左子树中的叶子结点个数leafnum(root->rchild); //右子树中的叶子结点个数}}/*将全局变量num初始化为0*/template<class T>void BiTree<T>::empty( ){num=0;}输出全局变量num的值*/template<class T>int BiTree<T>::printnum( ){return num;}/**前置条件:二叉树已经存在*输入:无*功能:求二叉树的单分支结点个数*输出:二叉树的单分支结点个数*后置条件:二叉树不变*/template<class T>void BiTree<T>::sbnodenum(BiNode<T> *root){if(root==NULL) return;else{if((!(root->lchild) && (root->rchild))||((root->lchild) && !(root->rchild))) //判断是否为叶子结点num++;sbnodenum(root->lchild); //左子树中的叶子结点个数sbnodenum(root->rchild); //右子树中的叶子结点个数}}/**前置条件:二叉树已经存在*输入:无*功能:交换二叉树的左右子树*输出:无*后置条件:二叉树左右子树交换*/template<class T>void BiTree<T>::exchangetree(BiNode<T> *root){if(root==NULL) return;else{if((root->rchild)&&(root->lchild)) //判断左右叶子结点都存在{ p=root->lchild;root->lchild=root->rchild;root->rchild=p;}exchangetree(root->lchild); //左子树中的叶子结点个数exchangetree(root->rchild); //右子树中的叶子结点个数}}/* BiNode<T> * Q[20];BiNode<T> *q;int front=-1;int rear=-1;int n=0;int m=0;Q[++rear]=root;if(root==NULL)cout<<0;else{while(front!=rear){q=Q[++front];if(q->lchild==NULL && q->rchild!=NULL)m++;if(q->lchild!=NULL && q->rchild==NULL)n++;if(q->lchild!=NULL) Q[++rear]=q->lchild;if(q->rchild!=NULL) Q[++rear]=q->rchild;}}cout<<"单分支节点的个数为:"<<m+n<<endl;*///二叉树的主函数,文件名为bitreemain.cpp#include<iostream>#include<string>#include"bietree.cpp"using namespace std;void main(){BiTree<string> bt; //创建一棵树BiNode<string>* root = bt.Getroot( ); //获取指向根结点的指针int s=-1;while(s!=0){cout<<"1.前序遍历"<<endl;cout<<"2.中序遍历"<<endl;cout<<"3.后序遍历"<<endl;cout<<"4.层序遍历"<<endl;cout<<"5.树的深度"<<endl;cout<<"6.叶子节点个数"<<endl;cout<<"7.单分支结点个数"<<endl;cout<<"8.左右子树交换后的结果"<<endl;cout<<"0.退出"<<endl;cin>>s;switch(s){ case 1:bt.PreOrder(root);cout<<endl;break;case 2:bt.InOrder(root);cout<<endl;break;case 3:bt.PostOrder(root);cout<<endl;break;case 4:bt.LeverOrder(root);cout<<endl;break;case 5:cout<<"树的深度为:"<<bt.depth(root)<<endl;break;case 6:bt.empty();bt.leafnum(root);cout<<"叶子结点个数为:"<<bt.printnum()<<endl;break;case 7:bt.empty();bt.sbnodenum(root);cout<<"单分支结点个数为:"<<bt.printnum()<<endl;break;case 8:bt.empty();bt.exchangetree(root);cout<<"左右子树交换后的结果:";bt.PreOrder(root);cout<<endl;break;case 0:exit(0);}}}。

二叉树的基本操作

二叉树的基本操作

二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

二叉树在计算机领域中得到广泛应用,它的基本操作包括插入、删除、查找、遍历等。

1.插入操作:二叉树的插入操作是将一个新的节点添加到已有的二叉树中的过程。

插入操作会按照一定规则将新节点放置在正确的位置上。

插入操作的具体步骤如下:-首先,从根节点开始,比较新节点的值与当前节点的值的大小关系。

-如果新节点的值小于当前节点的值,则将新节点插入到当前节点的左子树中。

-如果新节点的值大于当前节点的值,则将新节点插入到当前节点的右子树中。

-如果当前节点的左子树或右子树为空,则直接将新节点插入到该位置上。

-如果当前节点的左子树和右子树都不为空,则递归地对左子树或右子树进行插入操作。

2.删除操作:二叉树的删除操作是将指定节点从二叉树中删除的过程。

删除操作有以下几种情况需要考虑:-如果待删除节点是叶子节点,则直接将其从二叉树中删除即可。

-如果待删除节点只有一个子节点,则将其子节点替换为待删除节点的位置即可。

-如果待删除节点有两个子节点,则需要找到其左子树或右子树中的最大节点或最小节点,将其值替换为待删除节点的值,然后再删除最大节点或最小节点。

3.查找操作:二叉树的查找操作是在二叉树中查找指定值的节点的过程。

查找操作的具体步骤如下:-从根节点开始,将待查找值与当前节点的值进行比较。

-如果待查找值等于当前节点的值,则返回该节点。

-如果待查找值小于当前节点的值,则在当前节点的左子树中继续查找。

-如果待查找值大于当前节点的值,则在当前节点的右子树中继续查找。

-如果左子树或右子树为空,则说明在二叉树中找不到该值。

4.遍历操作:二叉树的遍历操作是按照一定规则依次访问二叉树中的每个节点。

有三种常用的遍历方式:- 前序遍历(Preorder Traversal):先访问根节点,然后递归地前序遍历左子树和右子树。

- 中序遍历(Inorder Traversal):先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

二叉树的建立与基本操作

二叉树的建立与基本操作

二叉树的建立与基本操作二叉树是一种特殊的树形结构,它由节点(node)组成,每个节点最多有两个子节点。

二叉树的基本操作包括建立二叉树、遍历二叉树、查找二叉树节点、插入和删除节点等。

本文将详细介绍二叉树的建立和基本操作,并给出相应的代码示例。

一、建立二叉树建立二叉树有多种方法,包括使用数组、链表和前序、中序、后序遍历等。

下面以使用链表的方式来建立二叉树为例。

1.定义二叉树节点类首先,定义一个二叉树节点的类,包含节点值、左子节点和右子节点三个属性。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```2.建立二叉树使用递归的方法来建立二叉树,先构造根节点,然后递归地构造左子树和右子树。

```pythondef build_binary_tree(lst):if not lst: # 如果 lst 为空,则返回 Nonereturn Nonemid = len(lst) // 2 # 取 lst 的中间元素作为根节点的值root = Node(lst[mid])root.left = build_binary_tree(lst[:mid]) # 递归构造左子树root.right = build_binary_tree(lst[mid+1:]) # 递归构造右子树return root```下面是建立二叉树的示例代码:```pythonlst = [1, 2, 3, 4, 5, 6, 7]root = build_binary_tree(lst)```二、遍历二叉树遍历二叉树是指按照其中一规则访问二叉树的所有节点,常见的遍历方式有前序遍历、中序遍历和后序遍历。

1.前序遍历前序遍历是指先访问根节点,然后访问左子节点,最后访问右子节点。

```pythondef pre_order_traversal(root):if root:print(root.value) # 先访问根节点pre_order_traversal(root.left) # 递归访问左子树pre_order_traversal(root.right) # 递归访问右子树```2.中序遍历中序遍历是指先访问左子节点,然后访问根节点,最后访问右子节点。

二叉树的存储结构及基本操作

二叉树的存储结构及基本操作

二叉树的存储结构及基本操作二叉树是一种常见的数据结构,广泛应用于计算机科学领域。

二叉树具有其独特的存储结构和基本操作,下面将详细介绍。

一、二叉树的存储结构二叉树的存储结构通常有两种形式:顺序存储和链式存储。

1. 顺序存储顺序存储是将二叉树中的所有元素按照一定的顺序存储在一段连续的内存单元中,通常采用数组来表示。

对于任意一个节点i,其左孩子节点的位置为2*i+1,右孩子节点的位置为2*i+2。

这种存储方式的优点是访问速度快,但需要预先确定节点总数,且不易于插入和删除操作。

2. 链式存储链式存储是采用指针的方式将二叉树的节点链接起来。

每个节点包含数据元素以及指向左孩子节点和右孩子节点的指针。

链式存储方式的优点是易于插入和删除操作,但访问速度较慢。

二、二叉树的基本操作1. 创建二叉树创建二叉树的过程就是将数据元素按照一定的顺序插入到二叉树中。

对于顺序存储的二叉树,需要预先分配内存空间;对于链式存储的二叉树,可以直接创建节点对象并链接起来。

2. 遍历二叉树遍历二叉树是指按照某种规律访问二叉树中的所有节点,通常有前序遍历、中序遍历和后序遍历三种方式。

前序遍历的顺序是根节点-左孩子节点-右孩子节点;中序遍历的顺序是左孩子节点-根节点-右孩子节点;后序遍历的顺序是左孩子节点-右孩子节点-根节点。

对于顺序存储的二叉树,可以采用循环结构实现遍历;对于链式存储的二叉树,需要使用指针逐个访问节点。

3. 查找元素在二叉树中查找元素,需要根据一定的规则搜索所有节点,直到找到目标元素或搜索范围为空。

对于顺序存储的二叉树,可以采用线性查找算法;对于链式存储的二叉树,可以采用深度优先搜索或广度优先搜索算法。

4. 插入元素在二叉树中插入元素需要遵循一定的规则,保证二叉树的性质。

对于顺序存储的二叉树,插入操作需要移动大量元素;对于链式存储的二叉树,插入操作相对简单,只需修改指针即可。

5. 删除元素在二叉树中删除元素同样需要遵循一定的规则,保证二叉树的性质。

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

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

实验二二叉树操作
(一)实验内容
二叉树的建立和遍历。

(二)实验目的
1.进一步掌握指针变量的使用。

2.掌握二叉树的结构特征以及各种存储结构的特点及使用范围。

3.掌握用指针类型描述、访问和处理二叉树的运算。

4.掌握栈或队列的使用。

(三)实验题目
本实验要求实现以下功能:
1.按前序次序建立一棵二叉树,以‘#’表示空。

2.中序、后序遍历该二叉树,输出遍历序列。

3.求出该二叉树的深度并输出,或求出该二叉树的叶子数目并输出。

4.试以栈为辅助存储结构实现二叉树的前序非递归算法或以队列为辅
助存储结构实现二叉树的层次遍历算法。

(四)实验仪器设备
1.学生每个一台PC机
2.已安装环境。

c语言二叉树的基本操作

c语言二叉树的基本操作

c语言二叉树的基本操作一、概念二叉树是一种数据结构,它由节点组成,每个节点都有0个或2个子节点,左子节点的关键字小于或等于该节点的关键字,右子节点的关键字大于该节点的关键字。

二、基本操作1、创建二叉树(1)结构体定义typedef struct node{int data; // 数据struct node *left; // 左子节点struct node *right; // 右子节点}Node, *pNode;(2)创建节点return p;}// 创建根节点*pTree = create_node(arr[0]);// 寻找合适的位置插入节点while (p != NULL){q = p;if (arr[i] < p->data)p = p->left;elsep = p->right;}2、遍历二叉树遍历二叉树有三种方法,分别是前序遍历、中序遍历和后序遍历。

(1)前序遍历void pre_order(pNode pTree){if (pTree != NULL){printf("%d ", pTree->data);pre_order(pTree->left);pre_order(pTree->right);}}3、查找节点找到关键字为data的节点,返回指向该节点的指针。

pNode search_node(pNode pTree, int data){if (pTree == NULL)return NULL;4、计算深度计算二叉树的深度,即为根节点到叶子节点的最长路径所包含的节点个数。

return left_depth > right_depth ? left_depth + 1 : right_depth + 1; }5、计算叶子节点数return leaf_count(pTree->left) + leaf_count(pTree->right);}6、删除节点删除节点分为两种情况:(1)被删除节点为叶子节点直接将其父节点指向该节点的指针设置为NULL即可。

数据结构与算法实验——二叉树基本操作

数据结构与算法实验——二叉树基本操作

二叉树基本操作实验报告实验名称二叉树基本操作实验目的1.熟悉二叉树结点的结构和二叉树的基本操作;2.掌握二叉树每种操作的具体实现;3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法;4.在二叉树基本操作的基础上掌握对二叉树的一些其它操作的具体实现方法;5.掌握构造哈夫曼树以及哈夫曼编码的方法。

实验内容编制一个演示二叉树创建、遍历、计算等操作的程序。

问题描述用数据结构相关知识,实现二叉树的定义和操作。

该程序包括二叉树结构类型以及对二叉树操作的具体的函数定义(包括:初始化二叉树、清空二叉树、检查二叉树是否为空、遍历二叉树(先序、后序、中序、层次)、求二叉树的深度、求二叉树所有节点数)。

问题分析该实验是基于C语言和数据结构知识基础的对二叉树的基本操作的检验,无需设计复杂的算法,程序语句也相对简单。

因此,我直接按要求定义了对二叉树操作的具体函数,并于主函数中实现对应的功能调用,其中,功能选择靠switch语句实现。

实验步骤1.需求分析本演示程序用VC++编写,完成二叉树的生成、遍历、计算等基本操作。

①输入的形式和输入值的范围:以字符(其中‘#’表示虚节点)的形式输入,以创建二叉树;在输入二叉树节点前,必须先确定该序列能正确创建二叉树。

②输出的形式:在所有三种操作中都显示操作是否正确以及操作后二叉树的内容。

③程序所能达到的功能:完成二叉树的生成、遍历(包括先序、后序、中序、层次四种方式)、计算等基本操作。

④测试数据:创建操作中依次输入a,b,d,#,g,#,#,#,c,e,#,#,f,#,#生成一个二叉树。

2.概要设计1)为了实现上述程序功能,需要定义二叉树的抽象数据类型:ADT BitTree {数据对象:由一个根节点和两个互不相交的左右子树构成数据关系:结点具有相同的数据类型及层次结构基本操作:Void BinTreeInit(BitTree *T)初始条件:无操作结果:初始化一棵二叉树Void BinTreeCreat(BitTree *T)初始条件:二叉树T已存在操作结果:按先序次序创建一棵二叉树2)本程序包含7个函数:①主函数main() ②初始化二叉树函数BinTreeInit() ③建立一棵二叉树函数BinTreeCreat() ④先序遍历函数PreOrderTraverse() ⑤中序遍历函数InOrderTraverse()⑥后序遍历函数PostOrderTraverse()⑦层次遍历函数LevelOrderTraverse()⑧求二叉树深度函数Countlevel()⑨检验空树函数BinTreeEmpty()⑩求节点数函数 Countnode()函数说明#include<stdio.h>#include<stdlib.h>typedef char Datatype;typedef struct NodeType{Datatype data;struct NodeType *lchild;struct NodeType *rchild;}BiTNode;typedef BiTNode * BinTree;//初始化二叉树。

实验五:二叉树的定义及基本操作

实验五:二叉树的定义及基本操作

实验五:二叉树的定义及基本操作(必做:基本2学时,扩展4学时)一、实验目的:.熟练掌握二叉树的二叉链表存储结构.掌握二叉树的非线性和递归性特点.熟练掌握二叉树的递归遍历操作的实现方法,掌握二叉树的非递归遍历操作的实现.掌握线索二叉树的定义和基本操作.加深对二叉树结构和性质的理解,逐步培养解决实际问题的编程能力二、实验内容:(一)基本实验内容:.定义二叉树的链式存储结构;.实现二叉树的基本操作:建空树、销毁二叉树、生成二叉树(先序,中序或后序)、判二叉树是否为空、求二叉树的深度、求二叉树的根等基本算法;.实现二叉树的递归(先序、中序或后序)遍历算法;1.问题描述:利用二叉树的链式存储结构,设计一组输入数据(假定为一组整数或一组字符),能够对二叉树进行如下操作:.创建一棵空二叉树;.对一棵存在的二叉树进行销毁;.根据输入某种遍历次序输入二叉树中结点的值,依序建立二叉树;.判断某棵二叉树是否为空;.求二叉树的深度;.求二叉树的根结点,若为空二叉树,则返回一特殊值;.二叉树的遍历,即按某种方式访问二叉树中的所有结点,并使每个结点恰好被访问一次;.编写主程序,实现对各不同的算法调用;其他算法的描述省略,参见实现要求说明。

2.实现要求:.“构造空二叉树算法”操作结果:构造一个空二叉树T;.“销毁二叉树算法”初始条件:二叉树T存在;操作结果:销毁二叉树T;.“创建二叉树算法”初始条件:可以根据先序、中序和后序输入二叉树中结点的值(可为字符型或整型);操作结果:以选择的某种次序建立二叉树T;.“判二叉树是否为空算法”初始条件:二叉树T存在;操作结果:若T为空二叉树,则返回TRUE,否则FALSE;.“求二叉树的深度算法”初始条件:二叉树T存在;操作结果:返回T的深度;.“求二叉树的根算法”初始条件:二叉树T存在;操作结果:返回T的根;.“先序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次;.“中序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次;.“后序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次;(二)扩展实验内容:利用二叉树的链式存储结构,设计一组输入数据(假定为一组整数或一组字符),能够对二叉树进行如下操作:.求某一个结点的双亲结点,求某一个结点的左孩子(或右孩子)结点;求某一个结点的左兄弟(或右兄弟)算法;.利用栈,实现二叉树的非递归(先序、中序或后序)遍历算法;.利用队列,实现层序递归遍历二叉树;.定义线索二叉树的链式存储结构,建立线索二叉树,实现线索二叉树的插入和删除操作;1.问题描述:.求二叉树中某个指定结点的父结点,当指定结点为根时,返回一特殊值;.求二叉树中某个指定结点的左孩子结点,当指定结点没有左孩子时,返回一特殊值;.求二叉树中某个指定结点的右孩子结点,当指定结点没有右孩子时,返回一特殊值;.实现中序非递归遍历二叉树算法一定采用二叉链表存储结构,并且仿照递归算法执行过程中递归工作栈的状态变化状况直接实现栈的操作,写出相应的非递归算法;中序和后序类似;.编写主程序,实现对各不同的算法调用。

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

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

数据结构实验报告—二叉树数据结构实验报告—二叉树引言二叉树是一种常用的数据结构,它由节点和边构成,每个节点最多有两个子节点。

在本次实验中,我们将对二叉树的基本结构和基本操作进行实现和测试,并深入了解它的特性和应用。

实验目的1. 掌握二叉树的基本概念和特性2. 熟练掌握二叉树的基本操作,包括创建、遍历和查找等3. 了解二叉树在实际应用中的使用场景实验内容1. 二叉树的定义和存储结构:我们将首先学习二叉树的定义,并实现二叉树的存储结构,包括节点的定义和节点指针的表示方法。

2. 二叉树的创建和初始化:我们将实现二叉树的创建和初始化操作,以便后续操作和测试使用。

3. 二叉树的遍历:我们将实现二叉树的前序、中序和后序遍历算法,并测试其正确性和效率。

4. 二叉树的查找:我们将实现二叉树的查找操作,包括查找节点和查找最大值、最小值等。

5. 二叉树的应用:我们将探讨二叉树在实际应用中的使用场景,如哈夫曼编码、二叉搜索树等。

二叉树的定义和存储结构二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。

节点被表示为一个由数据和指向其左右子节点的指针组成的结构。

二叉树可以分为三类:满二叉树、完全二叉树和非完全二叉树。

二叉树可以用链式存储结构或顺序存储结构表示。

- 链式存储结构:采用节点定义和指针表示法,通过将节点起来形成一个树状结构来表示二叉树。

- 顺序存储结构:采用数组存储节点信息,通过计算节点在数组中的位置来进行访问和操作。

二叉树的创建和初始化二叉树的创建和初始化是二叉树操作中的基础部分。

我们可以通过手动输入或读取外部文件中的数据来创建二叉树。

对于链式存储结构,我们需要自定义节点和指针,并通过节点的方式来构建二叉树。

对于顺序存储结构,我们需要定义数组和索引,通过索引计算来定位节点的位置。

一般来说,初始化一个二叉树可以使用以下步骤:1. 创建树根节点,并赋初值。

2. 创建子节点,并到父节点。

3. 重复步骤2,直到创建完整个二叉树。

二叉树的基本操作实现(数据结构实验)

二叉树的基本操作实现(数据结构实验)

⼆叉树的基本操作实现(数据结构实验)实验题⽬:⼆叉树的基本操作实现实验⽬的:掌握⼆叉树的⼆叉链存储结构及表⽰。

掌握⼆叉树的三种遍历算法(递归和⾮递归两类)。

运⽤三种遍历的⽅法求解⼆叉树的有关问题。

实验内容:实现⼆叉树的⼆叉链表存储结构;实现先序、中序和后序遍历⼆叉树;遍历⼆叉树的应⽤:计算叶⼦结点、左右⼦树交换等。

要求:1、⼆叉树基本操作已实现,学习和进⼀步理解。

2 、在求总结点的程序中加⼊求叶⼦结点的功能。

3 、左右⼦树交换,按中序和后序是否也可以?4 、选作:按层遍历⼆叉树。

实验代码:#include<stdio.h>#include<malloc.h>#include<string.h>#include<stdlib.h>#include<iostream>#define MAXTSIZE 1000using namespace std;/*测试数据: abc##de#g##f###*/typedef struct BiTNode{char data; // 结点数据域struct BiTNode *lchild,*rchild; // 左右孩⼦指针}BiTNode,*BiTree;void CreateBiTree(BiTree &T) // 先序遍历建⽴⼆叉链表{char ch;cin>>ch;// scanf("%c",&ch);if(ch=='#')T=NULL;else{T=(BiTNode *)malloc(sizeof(BiTNode));T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}}void travel1(BiTree T) // 先序遍历{if(T){printf("%c",T->data);travel1(T->lchild);travel1(T->rchild);}}void travel2(BiTree T) // 中序遍历{if(T){travel2(T->lchild);printf("%c",T->data);travel2(T->rchild);}}void travel3(BiTree T) // 后序遍历{if(T){travel3(T->lchild);travel3(T->rchild);printf("%c",T->data);}}int count(BiTree T) // 计算叶⼦结点的个数{if(T==NULL) return0;int cnt=0;if((!T->lchild)&&(!T->rchild)){cnt++;}int leftcnt=count(T->lchild);int rightcnt=count(T->rchild);cnt+=leftcnt+rightcnt;return cnt;}int Depth(BiTree T) // 计算⼆叉树的深度{if(T==NULL) return0;else{int m=Depth(T->lchild);int n=Depth(T->rchild);return m>n?(m+1):(n+1);}}void exchange(BiTree T,BiTree &NewT) // 交换左右⼦树{if(T==NULL){NewT=NULL;return ;}else{NewT=(BiTNode *)malloc(sizeof(BiTNode));NewT->data=T->data;exchange(T->lchild,NewT->rchild); // 复制原树的左⼦树给新树的右⼦树 exchange(T->rchild,NewT->lchild); // 复制原树的右⼦树给新树的左⼦树 }}int main(){puts("**************************");puts("1. 建⽴⼆叉树");puts("2. 先序遍历⼆叉树");puts("3. 中序遍历⼆叉树");puts("4. 后序遍历⼆叉树");puts("5. 计算叶⼦结点个数");puts("6. 计算⼆叉树的深度");puts("7. 交换⼆叉树的左右⼦树");puts("0. 退出");puts("**************************");BiTree Tree,NewTree;int choose;while(~scanf("%d",&choose),choose){switch(choose){case1:puts("温馨提醒:输⼊请以 '#' 为左/右⼦树空的标志!");CreateBiTree(Tree);break;case2:printf("先序遍历结果为:");travel1(Tree);puts("");break;case3:printf("中序遍历结果为:");travel2(Tree);puts("");break;case4:printf("后序遍历结果为:");travel3(Tree);puts("");break;case5:printf("叶⼦结点个数为:%d\n",count(Tree));break;case6:printf("⼆叉树的深度为:%d\n",Depth(Tree));break;case7:exchange(Tree,NewTree);Tree=NewTree;puts("交换成功!\n");break;}}system("pause");return0;}。

实验五--二叉树的存储结构和基本操作

实验五--二叉树的存储结构和基本操作

实验五二叉树的存储表示和基本操作实验内容1. 二叉树的二叉链表的存储结构—————二叉树的二叉链表存储表示————————typedef struct node{ElemType data; /*数据元素*/struct node *lchild; /*指向左孩子*/struct node *rchild; /*指向右孩子*/} BTNode;2. 二叉树的基本操作(1)创建操作:创建一棵二叉树。

(2)查找操作:查找二叉树中值为x的结点。

(3)查找左孩子操作:查找二叉树中值为x的结点的左孩子。

(4)查找右孩子操作:查找二叉树中值为x的结点的右孩子。

(5)求深度操作:求二叉树的深度。

(6)求宽度操作:求二叉树的宽度。

(7)求结点个数操作:求二叉树的结点个数。

(8)求叶子结点个数操作:求二叉树的叶子结点个数。

(9)输出操作:以括号表示法输出二叉树。

3. 链式队列操作实现的步骤(1)实现将链式队列的存储结构和基本操作程序代码。

(2)实现main主函数。

4.程序代码完整清单#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); /*创建一棵二叉树*/ BTNode *FindNode(BTNode *b,ElemType x); /*查找二叉树的结点*/ BTNode *LchildNode(BTNode *p); /*查找二叉树结点的左孩子*/ BTNode *RchildNode(BTNode *p); /*查找二叉树结点的右孩子*/ int BTNodeDepth(BTNode *b); /*求二叉树的深度*/void DispBTNode(BTNode *b); /*输出二叉树*/int BTWidth(BTNode *b); /*求二叉树的宽度*/int Nodes(BTNode *b); /*求二叉树结点个数*/int LeafNodes(BTNode *b); /*求二叉树叶子结点个数*/void 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",BTWidth(b));printf("(5)二叉树b的结点个数:%d\n",Nodes(b));printf("(6)二叉树b的叶子结点个数:%d\n",LeafNodes(b));printf("\n");}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];}}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); /*求左子树的高度为lchilddep*/rchilddep=BTNodeDepth(b->rchild); /*求右子树的高度为rchilddep*/return (lchilddep>rchilddep)? (lchilddep+1):(rchilddep+1);}}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(")");}}}int BTWidth(BTNode *b) /*求二叉树b的宽度*/{struct{int lno; /*结点的层次编号*/BTNode *p; /*结点指针*/} Qu[MaxSize]; /*定义顺序非循环队列*/int front,rear; /*定义队首和队尾指针*/ int lnum,max,i,n;front=rear=0; /*置队列为空队*/if (b!=NULL){rear++;Qu[rear].p=b; /*根结点指针入队*/Qu[rear].lno=1; /*根结点的层次编号为1*/while (rear!=front) /*队列不为空*/{front++;b=Qu[front].p; /*队头出队*/lnum=Qu[front].lno;if (b->lchild!=NULL) /*左孩子入队*/{rear++;Qu[rear].p=b->lchild;Qu[rear].lno=lnum+1;}if (b->rchild!=NULL) /*右孩子入队*/{rear++;Qu[rear].p=b->rchild;Qu[rear].lno=lnum+1;}}max=0;lnum=1;i=1;while (i<=rear){n=0;while (i<=rear && Qu[i].lno==lnum){n++;i++;}lnum=Qu[i].lno;if (n>max) max=n;}return max;}elsereturn 0;}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);}}5. 运行结果清单(1)输出二叉树:A ( B( D , E ( H ( J , K ( L , M ( , N ) ) ) ) ), C ( F , G ( , I ) ) )(2)’H’结点:左结点为J 右结点为K(3)二叉树b的深度:7(4)二叉树b的宽度:4(5)二叉树b的结点个数:14(6) 二叉树b的叶子结点个数:6。

蔡少云数据结构实验报告——二叉树的基本操作

蔡少云数据结构实验报告——二叉树的基本操作

数据结构实验报告学院:管理学院班级: 13电商1班姓名:蔡少云学号: 321300---- 2014年12 月1 日目录一、需求分析………………………………………问题描述…………………………………………基本要求…………………………………………实现说明…………………………………………二、设计目的………………………………………三、概要设计………………………………………基本框架图………………………………………设计想法…………………………………………四、详细设计………………………………………结点类……………………………………二叉树接口…………………………………………二叉树类………………………………………测试类………………………………………五、测试结果………………………………………基本数据…………………………………………操作截图…………………………………………六、用户使用说明…………………………………七、心得体会………………………………………题目:二叉树的基本操作一、需求分析【问题描述】在一棵二叉链表表示的二叉树中,实现以下操作,并说明采用哪种遍历算法,其他遍历算法是否可行。

1.二叉树的先根次序遍历2.输出以p结点为根的子树的所有叶子结点,先根次序遍历算法3.将每个结点的左子树与右子树交换4.由中根和后根次序遍历序列构造二叉树5.二叉树深拷贝,复制一棵二叉树【基本要求】建立结点类,二叉树接口。

实现二叉树的先根次序遍历,中根次序遍历和后根次序遍历。

【实现说明】可以利用利用二叉树的先根次序遍历完成相应功能。

二、设计目的1、达到熟悉掌握java和数据结构的基本知识和技能;2、能够利用所学的基本知识和技能,解决简单的面向对象的设计问题;3、把课本上的知识应用到实际生活中,达到学以致用的目的;4、复习学过的知识,思考新的问题;三、概要设计(1)基本框架图:实现(2)设计想法:结点类属性:data 、left 、right 构造函数 方法:输出方法、判断是否叶子结点方法 二叉树接口 将每个结点的左子树与右子树交换leaf1() 遍历输出叶子结点lrTran(); 先根、中根、后根次序遍历二叉树 判断二叉树是否为空isEmpty() 二叉树深拷贝,复制一棵二叉树抽象 方法二叉树类1、建立结点类BinaryNode;2、建立二叉树接口BinaryTTree<T>3、建立二叉树类,实现二叉树接口BinaryTree<T>4、建立主类,创建二叉树,进行测试。

数据结构实验报告-树(二叉树)

数据结构实验报告-树(二叉树)

实验5:树(二叉树)(采用二叉链表存储)一、实验项目名称二叉树及其应用二、实验目的熟悉二叉树的存储结构的特性以及二叉树的基本操作。

三、实验基本原理之前我们都是学习的线性结构,这次我们就开始学习非线性结构——树。

线性结构中结点间具有唯一前驱、唯一后继关系,而非线性结构中结点的前驱、后继的关系并不具有唯一性。

在树结构中,节点间关系是前驱唯一而后继不唯一,即结点之间是一对多的关系。

直观地看,树结构是具有分支关系的结构(其分叉、分层的特征类似于自然界中的树)。

四、主要仪器设备及耗材Window 11、Dev-C++5.11五、实验步骤1.导入库和预定义2.创建二叉树3.前序遍历4.中序遍历5.后序遍历6.总结点数7.叶子节点数8.树的深度9.树根到叶子的最长路径10.交换所有节点的左右子女11.顺序存储12.显示顺序存储13.测试函数和主函数对二叉树的每一个操作写测试函数,然后在主函数用while+switch-case的方式实现一个带菜单的简易测试程序,代码见“实验完整代码”。

实验完整代码:#include <bits/stdc++.h>using namespace std;#define MAX_TREE_SIZE 100typedef char ElemType;ElemType SqBiTree[MAX_TREE_SIZE];struct BiTNode{ElemType data;BiTNode *l,*r;}*T;void createBiTree(BiTNode *&T){ElemType e;e = getchar();if(e == '\n')return;else if(e == ' ')T = NULL;else{if(!(T = (BiTNode *)malloc(sizeof (BiTNode)))){cout << "内存分配错误!" << endl;exit(0);}T->data = e;createBiTree(T->l);createBiTree(T->r);}}void createBiTree2(BiTNode *T,int u) {if(T){SqBiTree[u] = T->data;createBiTree2(T->l,2 * u + 1);createBiTree2(T->r,2 * u + 2); }}void outputBiTree2(int n){int cnt = 0;for(int i = 0;cnt <= n;i++){cout << SqBiTree[i];if(SqBiTree[i] != ' ')cnt ++;}cout << endl;}void preOrderTraverse(BiTNode *T) {if(T){cout << T->data;preOrderTraverse(T->l);preOrderTraverse(T->r);}}void inOrderTraverse(BiTNode *T) {if(T){inOrderTraverse(T->l);cout << T->data;inOrderTraverse(T->r);}}void beOrderTraverse(BiTNode *T){if(T){beOrderTraverse(T->l);beOrderTraverse(T->r);cout << T->data;}}int sumOfVer(BiTNode *T){if(!T)return 0;return sumOfVer(T->l) + sumOfVer(T->r) + 1;}int sumOfLeaf(BiTNode *T){if(!T)return 0;if(T->l == NULL && T->r == NULL)return 1;return sumOfLeaf(T->l) + sumOfLeaf(T->r);}int depth(BiTNode *T){if(!T)return 0;return max(depth(T->l),depth(T->r)) + 1;}bool LongestPath(int dist,int dist2,vector<ElemType> &ne,BiTNode *T) {if(!T)return false;if(dist2 == dist)return true;if(LongestPath(dist,dist2 + 1,ne,T->l)){ne.push_back(T->l->data);return true;}else if(LongestPath(dist,dist2 + 1,ne,T->r)){ne.push_back(T->r->data);return true;}return false;}void swapVer(BiTNode *&T){if(T){swapVer(T->l);swapVer(T->r);BiTNode *tmp = T->l;T->l = T->r;T->r = tmp;}}//以下是测试程序void test1(){getchar();cout << "请以先序次序输入二叉树结点的值,空结点用空格表示:" << endl; createBiTree(T);cout << "二叉树创建成功!" << endl;}void test2(){cout << "二叉树的前序遍历为:" << endl;preOrderTraverse(T);cout << endl;}void test3(){cout << "二叉树的中序遍历为:" << endl;inOrderTraverse(T);cout << endl;}void test4(){cout << "二叉树的后序遍历为:" << endl;beOrderTraverse(T);cout << endl;}void test5(){cout << "二叉树的总结点数为:" << sumOfVer(T) << endl;}void test6(){cout << "二叉树的叶子结点数为:" << sumOfLeaf(T) << endl; }void test7(){cout << "二叉树的深度为:" << depth(T) << endl;}void test8(){int dist = depth(T);vector<ElemType> ne;cout << "树根到叶子的最长路径:" << endl;LongestPath(dist,1,ne,T);ne.push_back(T->data);reverse(ne.begin(),ne.end());cout << ne[0];for(int i = 1;i < ne.size();i++)cout << "->" << ne[i];cout << endl;}void test9(){swapVer(T);cout << "操作成功!" << endl;}void test10(){memset(SqBiTree,' ',sizeof SqBiTree);createBiTree2(T,0);cout << "操作成功!" << endl;}void test11(){int n = sumOfVer(T);outputBiTree2(n);}int main(){int op = 0;while(op != 12){cout << "-----------------menu--------------------" << endl;cout << "--------------1:创建二叉树--------------" << endl;cout << "--------------2:前序遍历----------------" << endl;cout << "--------------3:中序遍历----------------" << endl;cout << "--------------4:后序遍历----------------" << endl;cout << "--------------5:总结点数----------------" << endl;cout << "--------------6:叶子节点数--------------" << endl;cout << "--------------7:树的深度----------------" << endl;cout << "--------------8:树根到叶子的最长路径----" << endl;cout << "--------------9:交换所有节点左右子女----" << endl;cout << "--------------10:顺序存储---------------" << endl;cout << "--------------11:显示顺序存储-----------" << endl;cout << "--------------12:退出测试程序-----------" << endl;cout << "请输入指令编号:" << endl;if(!(cin >> op)){cin.clear();cin.ignore(INT_MAX,'\n');cout << "请输入整数!" << endl;continue;}switch(op){case 1:test1();break;case 2:test2();break;case 3:test3();break;case 4:test4();break;case 5:test5();break;case 6:test6();break;case 7:test7();break;case 8:test8();break;case 9:test9();break;case 10:test10();break;case 11:test11();break;case 12:cout << "测试结束!" << endl;break;default:cout << "请输入正确的指令编号!" << endl;}}return 0;}六、实验数据及处理结果测试用例:1.创建二叉树(二叉链表形式)2.前序遍历3.中序遍历4.后序遍历5.总结点数6.叶子结点数7.树的深度8.树根到叶子的最长路径9.交换所有左右子女10.顺序存储七、思考讨论题或体会或对改进实验的建议通过这次实验,我掌握了二叉树的顺序存储和链式存储,体会了二叉树的存储结构的特性,掌握了二叉树的树上相关操作。

数据结构实验报告(二叉树的基本操作)

数据结构实验报告(二叉树的基本操作)
else if((root->LChild==NULL)&&(root->RChild==NULL)) LeafNum=1;
else LeafNum=LeafCount(root->LChild)+LeafCount(root->RChild);
//叶子数为左右子树数目之和
return LeafNum;
printf("\n菜单选择\n\n");
printf(" 1.树状输出二叉树2.先序遍历二叉树\n");
printf(" 3.中序遍历二叉树4.后序遍历二叉树\n");
printf(" 5.输出叶子结点6.输出叶子结点的个数\n");
printf(" 7.输出二叉树的深度8.退出\n");
printf("\n----------------------------------------------------------------------\n");
{
printf("\n\n");
j=j+1; k=0;
while(k<nlocate)
{
printf(" ");
k++;
}
}
while(k<(nlocate-1))
{
printf(" ");
k++;
}
printf("%c",bt->data );
q.front=q.front+1;
if(bt->LChild !=NULL)//存在左子树,将左子树根节点入队列

二叉树的基本操作

二叉树的基本操作

实验五:二叉树的基本操作(1)输入字符序列,建立二叉链表。

(2)先序、中序、后序遍历二叉树:递归算法。

(3)中序遍历二叉树:非递归算法。

(最好也能实现先序、后序非递归算法)(4)求二叉树的高度。

(5)求二叉树的叶子个数。

(6)借助队列实现二叉树的层次遍历。

(7)在主函数中设计一个简单的菜单,分别调试上述算法。

综合训练:(1)为N个权值设计哈夫曼编码。

(2)试编写一个将百分制分数转换为五级分制的程序。

要求其时间性能尽可能好(即平均比较次数尽可能少)。

假设学生成绩的分布情况如下:分数0-59 60-69 70-79 80-89 90-100比例0.05 0.15 0.40 0.30 0.10#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define OVERFLOW -1#define LIST_INT_SIZE 100#define LISTINCREMENT 10int dep, count= 0;typedef int Status;typedef char TElemType;typedef struct BiTNode{TElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree;//建立二叉树Status CreateBiTree(BiTree &T){char ch;getchar();scanf("%c", &ch);if(ch == ' '|| ch == '\n'){T = NULL;return ERROR;}else{T = (BiTree)malloc(sizeof(BiTNode));T->data = ch;printf("请输入%c的左孩子:", T->data);CreateBiTree(T->lchild);printf("请输入%c的右孩子:", T->data);CreateBiTree(T->rchild);return OK;}}//主菜单void print(){printf("\n菜单如下:\n");printf("1 . 输入字符序列,建立二叉链表\n");printf("2 . 先序、中序、后序遍历二叉树:递归算法\n");printf("3 . 先序、中序、后序遍历二叉树:非递归算法\n");printf("4 . 求二叉树的高度\n");printf("5 . 求二叉树的叶子个数\n");printf("6 . 借助队列实现二叉树的层次遍历\n");printf("0 . EXIT\n请选择操作序号:");}//先序、中序、后序遍历二叉树:递归算法void print2(){printf("\n递归算法遍历二叉树,菜单如下:\n");printf("1.先根遍历\n");printf("2.中序遍历\n");printf("3.后续遍历\n");printf("0.退出\n");printf("请输入二级菜单选择:");}Status Visit(BiTree T){if(T)printf("%c ", T->data);return OK;}}Status PrintElement(TElemType e){printf(" %c ", e);return OK;}//先序Status PreOrderTraverse(BiTree T, Status (*Visit)(TElemType e)) {if(T){if(Visit(T->data))if(PreOrderTraverse(T->lchild, Visit))if(PreOrderTraverse(T->rchild, Visit))return OK;return ERROR;}elsereturn OK;}//中序Status MidOrderTraverse(BiTree T, Status (*Visit)(TElemType e)) {if(T){if(MidOrderTraverse(T->lchild, Visit))if(Visit(T->data))if(MidOrderTraverse(T->rchild, Visit))return OK;return ERROR;}elsereturn OK;}//后序Status LastOrderTraverse(BiTree T, Status (*Visit)(TElemType e)) {{if(LastOrderTraverse(T->lchild, Visit))if(LastOrderTraverse(T->rchild, Visit))if(Visit(T->data))return OK;return ERROR;}elsereturn OK;}//求树的叶子的个数,和打印出叶子Status LeafNumTree(BiTree T){int lnum,rnum;if(T!=NULL){if(T->lchild==NULL && T->rchild==NULL)return 1;else{lnum=LeafNumTree(T->lchild);rnum=LeafNumTree(T->rchild);return lnum+rnum;}}return 0;}//求二叉树的高度Status BiTreeDepth(BiTree T){int l,r;if(T){l=BiTreeDepth(T->lchild);r=BiTreeDepth(T->rchild);if(l>=r)dep += l;else dep += r;}elsereturn 1;}//先序、中序、后序遍历二叉树:非递归算法void print3(){printf("\n非递归算法遍历二叉树,菜单如下:\n");printf("1.先根遍历\n");printf("0.退出\n");printf("请输入二级菜单选择:");}typedef struct QueueNode{BiTree e;struct QueueNode *next;}QueueNode,*QueuePtr; //定义队列结点结构typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;//栈的顺序存储表示typedef struct{ BiTNode *base; //栈底指针BiTNode *top; //栈顶指针int stacksize; //当前已分配的存储空间}SqStack;//初始化一个带头结点的队列void InitQueue(LinkQueue &q){q.front=q.rear=(QueuePtr)malloc(sizeof(QueueNode));q.front->next=NULL;}//入队列void enqueue(LinkQueue &q,BiTree p){QueuePtr s;int first=1;s=(QueuePtr)malloc(sizeof(QueueNode));s->e =p;s->next=NULL;q.rear->next=s;q.rear=s;}//出队列void dequeue(LinkQueue &q,BiTree &p) {char data;QueuePtr s;s=q.front->next;p=s->e ;data=p->data;q.front->next=s->next;if(q.rear==s)q.rear=q.front;free(s);printf("%c\t",data);}//判断队列是否为空Status queueempty(LinkQueue q){if(q.front->next==NULL)return 1;return 0;}//按层次遍历树中结点void Traverse(BiTree T){LinkQueue q;BiTree p;InitQueue(q);p=T;enqueue(q,p);while(queueempty(q)!=1){dequeue(q,p);if(p->lchild!=NULL)enqueue(q,p->lchild);if(p->rchild!=NULL)enqueue(q,p->rchild);}printf("\n");}//建立一个空栈void InitStack(SqStack &S){ S.base=(BiTree)malloc(LIST_INT_SIZE * sizeof(BiTNode));if(!S.base)exit(OVERFLOW );//存储分配失败S.top=S.base;S.stacksize=LIST_INT_SIZE;}//压入栈void Push(SqStack & S,BiTree p){ if(S.top-S.base>=S.stacksize)//满栈,追加存储结构{ S.base= (BiTree)realloc(S.base,(S.stacksize+LISTINCREMENT) * sizeof(BiTNode));if(!S.base) exit(OVERFLOW );//存储分配失败S.top=S.base+S.stacksize;S.stacksize+=LISTINCREMENT;}*(++S.top)=*p;}//退出栈bool Pop(SqStack &S,BiTree &p){ if( S.top==S.base){ printf("空栈\n");return false;}p=(BiTree)malloc( sizeof(BiTNode));*p=*S.top;--S.top;return true;}//判断是否是空栈bool StackEmpty(SqStack &S){ if( S.top==S.base)return true;elsereturn false ;}Status InOrderTraverAndCountLeaf(BiTree &T,Status(* Vist)(TElemType e)){ int j=0,count=0;BiTree p;p=(BiTNode *)malloc( sizeof(BiTNode));//关键一步p=T;SqStack s;InitStack(s);while(p||!StackEmpty(s)){ if(p){ Push(s,p);//如果p为非空,将p压入栈if(!(p->lchild)&&!(p->rchild))++count;//记录叶子节点数p=p->lchild;}//ifelse{Pop(s,p);//如果p为空,则p退栈Vist(p->data);p=p->rchild;}//else}//whilereturn count;}int main(){int n, ncase;int count;bool f, f1, f2, f3;BiTree T;TElemType e;print();while(scanf("%d", &n)!=EOF){f = true;switch(n){case 1:printf("输入空格或回车表示此结点为空结束\n请输入头结点:");if(CreateBiTree(T))printf("二叉树建立成功!\n");elseprintf("二叉树建立失败!\n");break;case 2:print2();while(scanf("%d", &ncase)!= EOF){f1 = true;switch(ncase){case 1:printf("先序遍历顺序为:");if(PreOrderTraverse(T, PrintElement))printf("先序遍历成功!\n");elseprintf("先序遍历失败!\n");break;case 2:printf("中序遍历顺序为:");if(MidOrderTraverse(T, PrintElement))printf("中序遍历成功!\n");elseprintf("中序遍历失败!\n");break;case 3:printf("后序遍历顺序为:");if(LastOrderTraverse(T, PrintElement))printf("后序遍历成功!\n");elseprintf("后序遍历失败!\n");break;case 0:f1 = false;break;default :printf("输入错误,请重新输入!\n");}if(!f1)break;print2();}break;case 3:print3();while(scanf("%d", &ncase)!= EOF){f2 = true;switch(ncase){case 1:InOrderTraverAndCountLeaf(T,PrintElement);break;case 0:f2 = false;break;default :printf("输入错误,请重新输入!\n");}if(!f2)break;print3();}break;case 4:dep = 0;BiTreeDepth(T);printf("二叉树的高度为:%d\n", dep-1);break;case 5:count = LeafNumTree(T);printf("二叉树的叶子个数为:%d\n", count);break;case 6:printf("按层次遍历的顺序为:\n");Traverse(T);printf("\n");break;case 0:f = false;break;default:printf("输入错误,请重新输入!\n");break;}if(!f){printf("退出程序...\n");break;}print();}return 0;}。

二叉树的基本操作

二叉树的基本操作

二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多连接两个子节点,分别称为左子节点和右子节点。

二叉树的基本操作包括创建、插入、删除、查找和遍历,下面将对这些操作进行详细介绍。

一、创建二叉树创建二叉树的方法有多种,其中最常用的是使用递归的方式。

递归创建二叉树时,可以先创建根节点,然后递归创建左子树和右子树。

如果子树为空,则使用特殊字符表示。

二、插入节点插入节点是向二叉树中添加新节点的操作。

插入节点的位置通常由二叉树的特性决定,左子节点小于父节点,右子节点大于父节点。

插入节点时,需要先找到插入位置,然后创建新节点,并将其连接到对应的位置。

三、删除节点删除节点是从二叉树中移除指定节点的操作。

删除节点的方式取决于节点的位置和子节点的情况。

如果要删除的节点是叶子节点,则直接将其删除即可。

如果要删除的节点有一个子节点,则将其子节点连接到父节点。

如果要删除的节点有两个子节点,则需要找到替代节点,将替代节点的值复制到当前位置,并将替代节点删除。

四、查找节点查找节点是在二叉树中寻找特定节点的操作。

常用的方式有深度优先(DFS)和广度优先(BFS)。

深度优先通常使用递归实现,分为前序遍历、中序遍历和后序遍历三种方式。

广度优先通常使用队列实现,先访问根节点,然后访问其所有子节点,再逐层访问下去,直到找到目标节点或遍历完整棵树。

五、遍历二叉树遍历二叉树是指按照一定顺序访问二叉树中的所有节点,常用的方式有前序遍历、中序遍历和后序遍历。

前序遍历先访问根节点,然后递归遍历左子树和右子树;中序遍历先递归遍历左子树,然后访问根节点,再遍历右子树;后序遍历先递归遍历左子树和右子树,然后访问根节点。

以上是二叉树的基本操作,通过这些操作可以有效地管理和处理二叉树数据结构。

在实际应用中,二叉树常用于、排序和表达等方面,因为它具有较高的查询效率和灵活性。

对于使用二叉树的相关算法和数据结构,理解和掌握其基本操作是非常重要的。

二叉树的基本操作实验

二叉树的基本操作实验
六 运行结果
图(1)
图表1
else if(a==4)
{
printf("层序遍历:");
howmuch(T,2);
}
else if(a==5)
{
printf("总节点数:");
howmuch(T,0);
}
else if(a==6)
{
printf("总叶子数:");
howmuch(T,1);
}
else if(a==7)
{
printf("树的深度:");
二 概要设计
功能实现
1.int CreatBiTree(BiTree &T)用递归的方法先序建立二叉树, 并用链表储存该二叉树
2.int PreTravel(BiTree &T)前序遍历
3.intMidTravel(BiTree &T)中序遍历
4.intPostTravel(BiTree &T)后序遍历
实验三 二叉树的基本运算
一、实验目的
1、使学生熟练掌握二叉树的逻辑结构和存储结构。
2、熟练掌握二叉树的各种遍历算法。
二、实验内容
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
1. 按先序序列构造一棵二叉链表表示的二叉树T;
2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
5.int Depth(BiTree &T) //计算树的深度
6.inthowmuch(BiTree T,int h)采用树节点指针数组,用于存放遍历到的元素地址,如果有左孩子,存入地址,j加一 ,否则没操作,通过访问数组输出层次遍历的结果。k计算叶子数,j为总节点。

二叉树基本操作

二叉树基本操作

二叉树基本操作二叉树基本操作一、实验目的1.熟悉二叉树结点的结构和对二叉树的基本操作。

2.掌握对二叉树每一种操作的具体实现。

3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。

4.在二叉树基本操作的基础上掌握对二叉树的一些其它操作的具体实现方法。

5.掌握构造哈夫曼树以及哈夫曼编码的方法。

二、实验内容(必做1)程序 1该程序的功能是实现二叉树结点的类型定义和对二叉树的基本操作。

该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。

/* 定义 DataType 为char类型 */typedef char DataType;/* 二叉树的结点类型 */typedef struct BitNode{DataType data;struct BitNode *lchild,*rchild;}BitNode,*BitTree;/* 初始化二叉树,即把树根指针置空 */void BinTreeInit(BitTree *BT)/* 按先序次序建立一个二叉树*/void BinTreeCreat(BitTree *BT)/* 检查二叉树是否为空 */int BinTreeEmpty(BitTree *BT)/* 按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */void BinTraverse(BitTree *BT)/* 求二叉树的深度 */int BinTreeDepth(BitTree BT)/* 求二叉树中所有结点数 */int BinTreeCount(BitTree BT)/* 清除二叉树,使之变为空树 */void BinTreeClear(BitTree *BT)程序2 二叉树采用二叉链表存储,设计按层次遍历二叉树的算法。

设计要求:在程序中构造两个子程序分别为void BinTreeCreat(BitTree *BT) /* 按前序次序建立一个二叉树*/ void layorder(BitTree T) /*按层次遍历二叉树 */程序 3哈夫曼树和哈夫曼编码:从终端输入若干个字符,统计字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各字符进行哈夫曼编码。

二叉树的基本操作

二叉树的基本操作

《数据结构》课程实验报告学院:应用科技学院班级:09电子信息工程姓名:苏伟华学号:120352009006实验设备:计算机1台,Microsoft Visual C++ 6.0 软件实验日期:2011年5月21日实验项目名称二叉树的基本操作实验目的1) 掌握二叉树链表的结构的建立过程。

2)掌握用递归方法实现二叉树的遍历。

3)加深对二叉树的理解,逐步培养解决实际问题的编程能力。

实验要求:(1)编写二叉树的基本操作函数。

Typedef struct BiTNode{ TelemType data;struct BiTNode *lchild,*rchild;} BiTNode,*BiTree;①创建一棵二叉树 void CreateBiTree(BiTree &T);②先序遍历,递归方法 void PreOrderTraverse(BiTree T,void(*Visit)(int));③中序遍历,递归方法 void InOrderTraverse(BiTree T,void(*Visit)(int));④后序遍历,递归方法 void PostOrderTraverse(BiTree T,void(*Visit)(int));(2)调用上述函数实现下列操作。

用递归方法分别先序、中序和后序遍历二叉树;实验内容(包括步骤):(1) 二叉树的存储结构typedef struct BiTNode{int data;BiTNode *lchild,*rchild; // 左右孩子指针}BiTNode,*BiTree;(2)程序中的主要函数及功能说明void InitBiTree(BiTree &T);//初始化void CreateBiTree(BiTree &T);//创建一棵二叉树void DestroyBiTree(BiTree &T);//销毁二叉树void PreOrderTraverse(BiTree T,void(*Visit)(int));//先序遍历void InOrderTraverse(BiTree T,void(*Visit)(int));//中序遍历void PostOrderTraverse(BiTree T,void(*Visit)(int));//后序遍历void visit(int e);//遍历输出(3)主程序模块switch(m) {case '1':printf("\n");system("CLS");printf("按先序次序输入二叉树中结点的值,输入0表示节点为空,如:(1 2 3 0 0 4 5 0 6 0 0 7 0 0 0)\n");printf("\n请按先序次序输入二叉树中结点的值:");CreateBiTree(T); // 建立二叉树Tbreak;case '2':printf("\n");system("CLS");printf("先序递归遍历二叉树: ");PreOrderTraverse(T,visit); // 先序递归遍历二叉树Tbreak;case '3':printf("\n");system("CLS");printf("\n中序递归遍历二叉树: ");InOrderTraverse(T,visit); // 中序递归遍历二叉树T break;case '4':printf("\n");system("CLS");printf(" \n后序递归遍历二叉树:");PostOrderTraverse(T,visit); // 后序递归遍历二叉树T break;case '5':break;default: printf("\n");system("CLS");printf("输入的字符不对,请重新输入!");break;}调试与结果测试:##################二叉树的基本操作########################### ×××××××××1.二叉树的创建×××××××××××××××××××××××2.先序递归遍历二叉树××××××××××××××××××××3.中序递归遍历二叉树××××××××××××××××××××4.后序递归遍历二叉树××××××××××××××××××××5.退出程序××××××××××××××××############################################################# ①请输入你的选择:1请按先序次序输入二叉树中结点的值:1 2 3 0 0 4 5 0 6 0 0 7 0 0 0 ②请输入你的选择:2先序递归遍历二叉树:1->2->3->4->5->6->7③请输入你的选择:3中序递归遍历二叉树:3-> 2-> 5-> 6-> 4 ->7 ->1④请输入你的选择:4后序递归遍历二叉树::3-> 6 ->5 ->7 ->4 ->2 ->1⑤请输入你的选择:5press any key to continue退出程序代码注释:#include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<math.h>typedef struct BiTNode{int data;BiTNode *lchild,*rchild; // 左右孩子指针}BiTNode,*BiTree;//************************************************************************* **************************************************//*******************************************函数的声明部分************************************************************************//************************************************************************* *******************************************************void InitBiTree(BiTree &T);//初始化void CreateBiTree(BiTree &T);//创建一棵二叉树void DestroyBiTree(BiTree &T);//销毁二叉树void PreOrderTraverse(BiTree T,void(*Visit)(int));//先序遍历void InOrderTraverse(BiTree T,void(*Visit)(int));//中序遍历void PostOrderTraverse(BiTree T,void(*Visit)(int));//后序遍历void visit(int e);//遍历输出//************************************************************************* ******************************************************//*******************************************函数的实现部分***********************************************************************//************************************************************************* *******************************************************void InitBiTree(BiTree &T)// 操作结果:构造空二叉树T{T=NULL;}void CreateBiTree(BiTree &T)//按先序次序输入二叉树中结点的值,构造二叉链表表示的二叉树T。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验5:二叉树的基本操作(6学时)
一、实验目的
1.理解二叉树的基本概念和特点
2.掌握二叉树的链式存储结构
3.掌握二叉树的基本操作
4.掌握二叉树遍历操作
5.掌握哈夫曼树的构造算法和基本操作
二、实验内容
1. 实现二叉树的如下操作,二叉树如下图所示。

(采用二叉链存储结构实现)
(1)输出二叉树b;
(2)输出C节点的左、右孩子节点值;
(3)输出二叉树的深度;
(4)输出二叉树b的节点个数;
(5)输出二叉树b的叶子节点个数。

A
B C
D
G
E F
b
具体效果如下:
三、实验要求
1.独立完成实验程序的编写与调试;
2.实验完成后填写实验报告,学习委员按学号从小到大的顺序提交。

四、思考题
1.思考二叉树先序遍历、中序遍历、后序遍历的递归和非递归算法的实现方法。

方法说明:
(1)CreateBTNode(*b,*str):根据二叉树括号表示法字符串str生成对应的二叉链存储结
构,后者的根节点为*b。

(2)FindNode(BTNode *b,ElemType x):在二叉树b中寻找data域值为x的节点,并返回指
向该节点的指针。

(3)LchildNode(BTNode *p):求二叉树中节点*p的左孩子节点。

(4)RchildNode(BTNode *p):求二叉树中节点*p的右孩子节点。

(5)BTNodeDepth(BTNode *b):求二叉树b的高度,若二叉树为空,则其高度为0;否则,
其高度等于左子树与右子树的高度中的最大高度加1。

(6)DispBTNode(BTNode *b):以括号表示法输出一棵二叉树。

(7)Nodes(BTNode *b):求二叉树b的节点个数
(8)LeafNodes(BTNode *b):求二叉树b的叶子节点个数
(9)DestroyBTNode(BTNode *&b):销毁二叉树b。

相关文档
最新文档