实验三:二叉树操作

合集下载

实验三 二叉树基本操作

实验三 二叉树基本操作

实验三二叉树基本操作(2课时)一、实验目的1.掌握二叉树的结构特征,以及各种存储结构的特点及使用范围。

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

二、实验要求1.程序结构清晰、语句完整,包含有头文件和main函数;2.格式正确,语句采用缩进格式;3.运行结果正确,输入输出有提示,格式美观。

三、实验设备、材料和工具1.奔腾2计算机或以上机型2.turboc2,vc++,TC++四、实验内容和步骤实验内容:1.统计一棵二叉树中每种类型结点数(度为0、1、2的结点数)。

2.分别输入一棵有6个结点和8个结点的二叉树,编程序输出先序、中序和后序的遍历结果。

3.哈夫曼树及哈夫曼编码。

五、实验报告要求1.根据实验内容初步设计好程序,并从理论上排除错误;2.针对程序的健壮性准备好测试数据;3.结果分析中如实填写运行后的结果,并记录调试过程中产生的重要问题和解决方法。

六、根据实验过程填写下面内容1:程序:#include"test.h"int LeafCount1=0,LeafCount2=0,LeafCount3=0;void leaf_a(BiTree root){if(root!=NULL){leaf_a(root->LChild);leaf_a(root->RChild);if(root->LChild==NULL&&root->RChild==NULL)LeafCount1++;else if(root->LChild==NULL||root->RChild==NULL)LeafCount2++;else if(root->LChild!=NULL||root->RChild!=NULL)LeafCount3++;elseprintf("不符合题意!");}}void main(){BiTree root;printf("按先序遍历序列建立二叉树,请输入需要插入的序列:\n");CreateBiTree(&root);// PreOrder(root);leaf_a(root);printf("度为0的节点数:%d\n",LeafCount1);printf("度为1的节点数:%d\n",LeafCount2);printf("度为2的节点数:%d\n",LeafCount3);}#include <stdio.h>#include <malloc.h>#include <conio.h>typedef char DataType;void Visit(char ch){printf("%c ",ch);}typedef struct Node{DataType data;struct Node *LChild;struct Node *RChild;}BiTNode, *BiTree;void CreateBiTree(BiTree *bt){char ch;ch = getchar();if(ch=='#')*bt=NULL;else{*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点(*bt)->data=ch;CreateBiTree(&((*bt)->LChild)); //生成左子树CreateBiTree(&((*bt)->RChild)); //生成右子树}}void PreOrder(BiTree root)/*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ {if (root!=NULL){Visit(root->data); /*访问根结点*/PreOrder(root->LChild); /*先序遍历左子树*/PreOrder(root->RChild); /*先序遍历右子树*/ }}void InOrder(BiTree root)/*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ {if (root!=NULL){InOrder(root ->LChild); /*中序遍历左子树*/Visit(root ->data); /*访问根结点*/InOrder(root ->RChild); /*中序遍历右子树*/}}void PostOrder(BiTree root)/* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/ {if(root!=NULL){PostOrder(root ->LChild); /*后序遍历左子树*/PostOrder(root ->RChild); /*后序遍历右子树*/Visit(root ->data); /*访问根结点*/}}结果分析:(要求完全理解程序,需每人答辩)ab cd ef2:程序:#include"bitree.h"void main(){BiTree T;char ch;printf("按照先序遍历建立二叉树,请输入序列:\n");CreateBiTree(&T);printf("\n先序遍历为:"); //先序遍历PreOrder(T);printf("\n中序遍历为:"); //中序遍历InOrder(T);printf("\n后序遍历为:"); //后序遍历PostOrder(T);}#include <stdio.h>#include <malloc.h>#include <conio.h>#define false 0#define true 1typedef char DataType;typedef struct Node{DataType data;struct Node *LChild;struct Node *RChild;}BiTNode, *BiTree;void CreateBiTree(BiTree *bt){char ch;ch=getchar();if(ch=='#')*bt=NULL;else{*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点(*bt)->data=ch;CreateBiTree(&((*bt)->LChild)); //生成左子树CreateBiTree(&((*bt)->RChild)); //生成右子树}}void PreOrder(BiTree root)/*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ {if (root!=NULL){printf("%c ",root ->data); /*访问根结点*/PreOrder(root ->LChild); /*先序遍历左子树*/PreOrder(root ->RChild); /*先序遍历右子树*/}}void InOrder(BiTree root)/*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ {if (root!=NULL){InOrder(root ->LChild); /*中序遍历左子树*/printf("%c ",root ->data); /*访问根结点*/InOrder(root ->RChild); /*中序遍历右子树*/}}void PostOrder(BiTree root)/* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/ {if(root!=NULL){PostOrder(root ->LChild); /*后序遍历左子树*/PostOrder(root ->RChild); /*后序遍历右子树*/printf("%c ",root ->data); /*访问根结点*/}}结果分析:(要求完全理解程序,需每人答辩)第一个8个结点的二叉树图形为:b cef g h第二个为6个节点的二叉树图形:ab cd e f对结点的输出实现递归调用,输出各种遍历的情况3:程序:#include <stdio.h>#include <stdlib.h>#include <string.h>#include "huffman.h"//typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*//*typedef struct{unsigned int weight ; /* 用来存放各个结点的权值unsigned int parent, LChild,RChild ; //指向双亲、孩子结点的指针}HTNode, * HuffmanTree; //动态分配数组,存储哈夫曼树*///输出哈夫曼树void outputHuffman(HuffmanTree HT, int m){if(m!=0){printf("%d ", HT[m].weight);outputHuffman(HT,HT[m].LChild);outputHuffman(HT,HT[m].RChild);}}HuffmanTree HT; //ht哈夫曼树HuffmanCode HC; //hc哈弗曼编码int *w;int i,n; // 元素的个数;int wei; // 元素的权值;int m;printf("输入哈夫曼树的总结点树:" );scanf("%d",&n);w=(int *)malloc((n+1)*sizeof(int));for(i=1;i<=n;i++){printf("请输入第%d个元素的权值:",i);fflush(stdin);//清除缓存scanf("%d",&wei);w[i]=wei;}CrtHuffmanTree(&HT,w,n);m = 2*n-1;outputHuffman(HT,m);printf("\n");CrtHuffmanCode(&HT,&HC,n);}#include <stdio.h>#include <stdlib.h>#include <string.h>#define N 20#define M 2*N-1typedef char* HuffmanCode[N+1];/*存储N个哈夫曼编码串的头指针数组*/{unsigned int weight ; /* 用来存放各个结点的权值*/unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/ }HTNode, HuffmanTree[M+1]; /*动态分配数组,存储哈夫曼树*/void select(HuffmanTree *ht,int n, int *s1, int *s2){int i;int min;for(i=1; i<=n; i++){if((*ht)[i].parent == 0){ min = i;i = n+1;}}for(i=1; i<=n; i++){if((*ht)[i].parent == 0){if((*ht)[i].weight < (*ht)[min].weight)min = i;}}*s1 = min;for(i=1; i<=n; i++){if((*ht)[i].parent == 0 && i!=(*s1)){ min = i;i = n+1;}}for(i=1; i<=n; i++){if((*ht)[i].parent == 0 && i!=(*s1)){if((*ht)[i].weight < (*ht)[min].weight)min = i;}}*s2 = min;}void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)/*从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码*/{char *cd;int i;unsigned int c;int start;int p;hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); /*分配n个编码的头指针*/cd=(char * )malloc(n * sizeof(char )); /*分配求当前编码的工作空间*/cd[n-1]='\0'; /*从右向左逐位存放编码,首先存放编码结束符*/for(i=1;i<=n;i++) /*求n个叶子结点对应的哈夫曼编码*/{start=n-2; /*初始化编码起始指针*/for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) /*从叶子到根结点求编码*/ if( (*ht)[p].LChild == c){cd[start]='0'; /*左分支标0*/--start;}else{cd[start]='1'; /*右分支标1*/--start;}(*hc)[i]=(char *)malloc((n-start)*sizeof(char)); /*为第i个编码分配空间*/strcpy((*hc)[i],&cd[start+1]);}free(cd);for(i=1;i<=n;i++)printf("%d编码为%s\n",(*ht)[i].weight,(*hc)[i]);}void CrtHuffmanTree(HuffmanTree *ht , int *w, int n){ /* w存放已知的n个权值,构造哈夫曼树ht */int m,i;int s1,s2;m=2*n-1;// *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0号单元未使用*/ for(i=1;i<=n;i++){/*1-n号放叶子结点,初始化*/(*ht)[i].weight = w[i];(*ht)[i].LChild = 0;(*ht)[i].parent = 0;(*ht)[i].RChild = 0;}for(i=n+1;i<=m;i++){(*ht)[i].weight = 0;(*ht)[i].LChild = 0;(*ht)[i].parent = 0;(*ht)[i].RChild = 0;} /*非叶子结点初始化*//* ------------初始化完毕!对应算法步骤1---------*/for(i=n+1;i<=m;i++) /*创建非叶子结点,建哈夫曼树*/{ /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回*/select(ht,i-1,&s1,&s2);(*ht)[s1].parent=i;(*ht)[s2].parent=i;(*ht)[i].LChild=s1;(*ht)[i].RChild=s2;(*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;}}/*哈夫曼树建立完毕*/结果分析:(要求完全理解程序,需每人答辩)通过调用select函数找出最小的两个权值,用CrtHuffman函数存放权值构成哈夫曼树再调用CrtHuffmanCode函数实现从叶子结点到根,逆向求每个叶子结点对应的哈弗曼编码。

实验三--二叉树的基本运算

实验三--二叉树的基本运算

实验三二叉树的基本运算一、实验目的1、使学生熟练掌握二叉树的逻辑结构和存储结构。

2、熟练掌握二叉树的各种遍历算法。

二、实验内容1、问题描述建立一棵二叉树,试编程实现二叉树的如下基本操作:(1). 按先序序列构造一棵二叉链表表示的二叉树T;(2). 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;(3). 求二叉树的深度/结点数目/叶结点数目;(选做)(4). 将二叉树每个结点的左右子树交换位置。

(选做)2、基本要求从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立)。

3、测试数据如输入:abc00de0g00f000(其中ф表示空格字符)则输出结果为:先序:a->b->c->d->e->g->f中序:a->b->c->d->e->g->f后序:a->b->c->d->e->g->f三、程序代码#include<malloc.h>#include<iostream.h>#define OK 1#define ERROR -1typedef char TElemType;int i;typedef struct BiTNode{TElemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;int CreateBiTree(BiTree&T) //创建二叉树{char a;cin>>a;if(a=='0') T=NULL;else{if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) {return ERROR;}T->data=a;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}return OK;}int PreOrderTraverse(BiTree&T) //先序遍历二叉树{if(T){//cout<<"此为先序遍历"<<endl;cout<<T->data<<"->";if(PreOrderTraverse(T->lchild))if(PreOrderTraverse(T->rchild))return OK;return ERROR;}else return OK;}int InOrderTraverse(BiTree&T) //中序遍历二叉树{if(T){//cout<<"此为中序遍历"<<endl;if(InOrderTraverse(T->lchild)){cout<<T->data<<"->";if(InOrderTraverse(T->rchild))return OK;}return ERROR;}else return OK;}int PostOrderTraverse(BiTree&T) //后序遍历二叉树{if(T){//cout<<"此为后序遍历"<<endl;if (PostOrderTraverse(T->lchild))if(PostOrderTraverse(T->rchild)){cout<<T->data<<"->";i++;return (OK);}return (ERROR);}elsereturn (OK);}int CountDepth(BiTree&T) //计算二叉树的深度{if(T==NULL){return 0;}else{int depl=CountDepth(T->lchild);int depr=CountDepth(T->lchild);if(depl>depr){return depl+1;}else{return depr+1;}}}void main() //主函数{BiTree T;cout<<"请输入二叉树节点的值以创建树"<<endl;CreateBiTree(T);cout<<"此为先序遍历";PreOrderTraverse(T);cout<<"end"<<endl;cout<<"此为中序遍历";InOrderTraverse(T);cout<<"end"<<endl;cout<<"此为后序遍历";PostOrderTraverse(T);cout<<"end"<<endl<<"此树节点数是"<<i<<endl<<"此树深度是"<<CountDepth(T)<<endl;}四、调试结果及运行界面:五、实验心得通过这次程序上机实验让我认识到了以前还不太了解的二叉树的性质和作用,这次实验的的确确的加深了我对它的理解。

数据结构实验报告二叉树

数据结构实验报告二叉树

数据结构实验报告二叉树《数据结构与算法》实验报告专业班级姓名学号实验项目实验三二叉树。

实验目的1、掌握用递归方法实现二叉树的遍历。

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

题目:(1)编写二叉树的遍历操作函数。

①先序遍历,递归方法re_preOrder(TREE *tree)②中序遍历,递归方法re_midOrder(TREE *tree)③后序遍历,递归方法re_postOrder(TREE *tree)(2)调用上述函数实现先序、中序和后序遍历二叉树操作。

算法设计分析(一)数据结构的定义要求用c语言编写一个演示程序,首先建立一个二叉树,让用户输入一个二叉树,实现该二叉树的便利操作。

二叉树型存储结构定义为:typedef struct TNode{ char data;//字符型数据struct TNode *lchild,*rchild;//左右孩子指针}TNode,* Tree;(二)总体设计程序由主函数、二叉树建立函数、先序遍历函数、中序遍历函数、后序遍历函数五个函数组成。

其功能描述如下:(1)主函数:统筹调用各个函数以实现相应功能。

int main()(2)二叉树建立函数:根据用户意愿运用先序遍历建立一个二叉树。

int CreateBiTree(Tree &T)(3)先序遍历函数:将所建立的二叉树先序遍历输出。

void PreOrder(Tree T)(4)中序遍历函数:将所建立的二叉树中序遍历输出。

void InOrder(Tree T)(5)后序遍历函数:将所建立的二叉树后序遍历输出。

void PostOrder(Tree T)(三)各函数的详细设计:(1)建立一个二叉树,按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树。

对T动态分配存储空间,生成根节点,构造左、右子树(2)编写先序遍历函数,依次访问根节点、左子结点、右子节点(3)编写中序遍历函数,依次访问左子结点、根节点、右子节点(4)编写后序遍历函数,依次访问左子结点、右子节点、根节点(5)编写主函数,调用各个函数,以实现二叉树遍历的基本操作。

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

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

实验三二叉树的操作一、实验目的1、掌握二叉树的逻辑结构;2、掌握二叉树的二叉链表存储结构;3、掌握基于二叉链表存储的二叉树的遍历操作的实现。

二、实验内容1、采用二叉链表存储建立一棵含有n个结点的二叉树;2、前序打印该二叉树的所有叶子结点;3、统计该二叉树的结点个数;4、计算该二叉树的深度;5、交换该二叉树的所有左右子树。

三、程序实现1、二叉链表结点类型BiNode.htemplate<class T>struct BiNode{T data;BiNode<T> *lchild,*rchild;};2、二叉树的建立及操作BiTree.htemplate<class T>struct BiNode{T data;BiNode<T> *lchild,*rchild;};template <class T>class BiTree{public:BiTree( ); //构造函数,初始化一棵二叉树,其前序序列由键盘输入~BiTree(); //析构函数,释放二叉链表中各结点的存储空间BiNode<T>* Getroot(); //获得指向根结点的指针void PreOrder(BiNode<T> *root); //前序遍历二叉树void InOrder(BiNode<T> *root); //中序遍历二叉树void PostOrder(BiNode<T> *root); //后序遍历二叉树void LevelOrder(BiNode<T> *root); //层序遍历二叉树private:BiNode<T> *root; //指向根结点的头指针BiNode<T>* Creat(); //有参构造函数调用void Release(BiNode<T> *root); //析构函数调用};template<class T>BiTree<T>::BiTree(){cout<<"请按前根序输入该二叉树的各个结点(#号表示为空):\n";this->root=Creat();}template <class T>BiNode<T>* BiTree<T>::Creat(){BiNode<T> *root;T ch;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>BiTree<T>::~BiTree(){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>::LevelOrder(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;}}}template<class T>void BiTree<T>::Release(BiNode<T>* root){if (root != NULL){Release(root->lchild); //释放左子树Release(root->rchild); //释放右子树delete root;}}3、主程序实现#include<iostream.h>#include "BiTree.h"int SumNode(BiNode<char> *root)//统计二叉树结点个数{int sum;if(root==NULL)return 0;else{sum=SumNode(root->lchild)+1;sum+=SumNode(root->rchild);return sum;}}void PrePrint(BiNode<char> *root)//前序打印二叉树叶子结点{if(root==NULL) return;else{if(root->lchild==NULL&&root->rchild==NULL)cout<<root->data<<' ';PrePrint(root->lchild);PrePrint(root->rchild);}}int TreeDeepth(BiNode<char> *root)//计算二叉树的深度{int deepth;if(root==NULL) return 0;else{deepth=(TreeDeepth(root->lchild)+1)>(TreeDeepth(root->rchild)+1)?(TreeDeepth(root->lchi ld)+1):(TreeDeepth(root->rchild)+1);return deepth;}}void Changechild(BiNode<char> *root)//交换二叉树的所有左右子树{BiNode<char> *temp;if(root==NULL||(root->lchild==NULL&&root->rchild==NULL)) return;else{Changechild(root->lchild);Changechild(root->rchild);if(root->lchild==NULL){root->lchild=root->rchild;root->rchild=NULL;}if(root->rchild==NULL){root->rchild=root->lchild;root->lchild=NULL;}else{temp=root->lchild;root->lchild=root->rchild;root->rchild=temp;}}}void main(){BiTree<char> Q;int deepth,sum;cout<<"Q的前序遍历为:\n";Q.PreOrder(Q.Getroot());cout<<"\nQ的中序遍历为:\n";Q.InOrder(Q.Getroot());cout<<"\nQ的后序遍历为:\n";Q.PostOrder(Q.Getroot());cout<<"\nQ的层序遍历为:\n";Q.LevelOrder(Q.Getroot());sum=SumNode(Q.Getroot());cout<<"\n结点个数为:"<<sum<<endl;deepth=TreeDeepth(Q.Getroot());cout<<"该二叉树的深度为:"<<deepth<<endl;cout<<"该二叉树叶子结点的前序打印顺序为:"<<'\n';PrePrint(Q.Getroot());cout<<"\n交换前二叉树的层序遍历为:\n";Q.LevelOrder(Q.Getroot());Changechild(Q.Getroot());cout<<"\n交换后二叉树的层序遍历为:\n";Q.LevelOrder(Q.Getroot());cout<<endl;}四、运行结果输入的二叉树结点的前根序序列为:ABDG##H##E#I##CF#J###二叉树形式为 AB CD E FG H I运行结果:五、实验心得体会通过本次实验过程,自己熟悉了二叉树的一些基本操作,掌握二叉树的逻辑结构;二叉树的二叉链表存储结构;熟悉了基于二叉链表存储的二叉树的遍历操作。

数据结构 实验三 -二叉树的操作及应用

数据结构 实验三 -二叉树的操作及应用

实验三二叉树的操作及应用实验课程名:数据结构与算法专业班级:计算机科学与技术(1)班学号:姓名:实验时间:12.11 实验地点:指导教师:一、实验目的1、进一步掌握指针变量、动态变量的含义。

2、掌握二叉树的结构特性,以及各种存储结构的特点和适用范围。

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

二、实验任务1、分别以顺序存储结构和二叉链表作存储结构,试编程实现前序、中序、后序及层次顺序遍历二叉树的算法。

程序源代码:#include <stdio.h>#include <malloc.h>#define NULL 0typedef struct node{int data;struct node *lchild,*rchild;}BiT ree;int front=0,rear=0;BiT ree *q[10];//创建二叉树BiT ree *CreatBiT ree(){int x;BiT ree *T;scanf("%d",&x);if(x==0)T=NULL;else{T=(BiT ree *)malloc(sizeof(BiT ree));T->data=x;T->lchild=CreatBiT ree();T->rchild=CreatBiT ree();}return (T);}//先序遍历void Pre(BiT ree *T){if(T!=NULL){printf("%4d",T->data);Pre(T->lchild);Pre(T->rchild);}}//中序遍历void In(BiT ree *T){if(T!=NULL){In(T->lchild);printf("%4d",T->data);In(T->rchild);}}//后序遍历void Back(BiT ree *T){if(T!=NULL){Back(T->lchild);Back(T->rchild);printf("%4d",T->data);}}void enqueue(BiT ree *t){if(front!=rear+1){rear=rear+1;q[rear]=t;}}BiT ree *delqueue(){if(front==rear)return NULL;{front=front+1;return (q[front]);}}void lev(BiT ree *t){BiT ree *p;if(t!=NULL){enqueue(t);while(front!=rear){p=delqueue();printf("%4d",p->data);if(p->lchild!=NULL)enqueue(p->lchild);if(p->rchild!=NULL)enqueue(p->rchild);}}}void main(){int i;BiT ree *t;printf("Please enter value:\t");t=CreatBiT ree();printf("0:退出\t1:先序\t2:中序\t3:后序\t4:层次\n");do{printf("Please choose the num:\t");scanf("%d",&i);switch(i){case 0:break;case 1:{Pre(t);printf("\n");break;}case 2:{In(t);printf("\n");break;}case 3:{Back(t);printf("\n");break;}case 4:{lev(t);printf("\n");break;}default:printf("Input Error!\n");}}while(i);printf("\n");}程序运行结果:2、以二叉链表作存储结构,试编写计算二叉树深度、所有结点总数、叶子结点数、双孩子结点个数、单孩子结点个数的算法。

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

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

TextFile中。

(4) P:打印代码文件(Print)。

将文件CodeFile以紧凑格式显示在终端上,每行50个代码。

同时将此字符形式的编码文件写入文件CodePrin中。

(5) T:打印哈夫曼树(Tree printing)。

将已在内存中的哈夫曼树以直观的方式显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。

3) 实现提示:(1) 文件CodeFile的基类型可以设为字节型。

(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。

请用户键入一个选择功能符。

此功能执行完毕后再显示此菜单,直至某次用户选择了“E”为止。

(3) 在程序的一次执行过程中,第一次执行I、D或C命令之后,哈夫曼树已经在内存了,不必再读入。

每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

三、实验过程与实验结果实验3-01:以二叉链表为存储结构,实现二叉树的创建、遍历数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。

2.利用非递归实现中序遍历,需要利用栈操作,按照中序遍历规则将节点依次入栈后出栈实现。

算法描述:图1 中序遍历(非递归)实现算法的实现和测试结果(参考OJ)实验3-02:编写算法交换二叉树中所有结点的左、右子树数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。

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

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

实验3 二叉树的操作及应用PB13000818 焦孟娇实验目的:1. 熟练掌握递归程序设计的方法。

2. 掌握二叉树的特性和基本算法。

问题描述:二叉树是一种基本且常用的数据结构。

二叉树的很多基本算法都可以用递归的形式来表述。

本实验要求实现二叉树的如下操作:创建、销毁、复制、打印显示、先中后序遍历、查找元素、层序遍历、求二叉树的深度、宽度、结点数和叶子个数等。

实验内容:一、队列的抽象数据类型定义为:Queue operation{数据对象:数据关系:基本操作:InitQueue(&S)操作结果:构造一个空队列SQueueLength(S)初始条件:队列S已存在操作结果:返回S的元素个数,即队列的长度QueueEmpty(S)初始条件:队列S已存在操作结果:若S为空队列,则返回TRUE,否则FALSEEnQueue(&S, e)初始条件:队列S已存在操作结果:插入元素e为队列新元素DeQueue(&S, &e)初始条件:队列S已存在且非空操作结果:删除S的队头元素,并用e返回其值GetHead(S, &e)初始条件:队列S已存在且非空操作结果:用e返回S的队头元素ClearQueue(&S)初始条件:队列S已存在操作结果:将S清为空队列DeleteQueue(&S)初始条件:队列S已存在操作结果:队列S被销毁Print(S)初始条件:队列S已存在操作结果:输出队列S} Queue operationBiTree operation{InitBiTree( &T )// 操作结果:构造空二叉树T。

DestroyBiTree( &T )// 初始条件:二叉树T已存在。

// 操作结果:销毁二叉树T。

CreateBiTree( &T, definition )// 初始条件:definition给出二叉树T的定义。

// 操作结果:按definiton构造二叉树T。

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

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

《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为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,失败。

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

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

二叉树的基本操作实现及其应用一、实验目的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<<"二叉树初始化成功!"<<endl;}2、/* 按先序次序建立一个二叉树*/int BinTreeCreat(BitTree &BT){char ch;cin>>ch;if(ch=='#') BT=NULL;else{if(!(BT=(BitTree)malloc(sizeof(BitNode))))exit(0);BT->data=ch;BinTreeCreat(BT->lchild);BinTreeCreat(BT->rchild);}return 0;}3、/* 检查二叉树是否为空 */void BinTreeEmpty(BitTree &BT){if(BT->data==NULL)cout<<"是空二叉树!"<<endl;elsecout<<"不是空二叉树!"<<endl;}4、/*按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */void BinTraverse(BitTree &BT)//按先序序列建立二叉树{if(BT!=NULL){cout<<BT->data;BinTraverse(BT->lchild);BinTraverse(BT->rchild);}}5、/* 求二叉树的深度 */int BinTreeDepth(BitTree BT){int depthval;if(BT){int depthLeft=BinTreeDepth(BT->lchild);int depthRight=BinTreeDepth(BT->rchild);depthval=1+(depthLeft>depthRight?depthLeft:depthRight);}else depthval=0;return depthval;}6、/* 求二叉树中所有结点数 */int BinTreeCount(BitTree BT){int node;if(BT){int lchild=BinTreeCount(BT->lchild);int rchild=BinTreeCount(BT->rchild);node=lchild+rchild+1;}elsenode=0;return node;}㈡、函数调用及主函数设计㈢程序调试及运行结果分析测试数据: 1、初始化二叉树; 2、按先序序列建立二叉树;3、判断二叉树是否为空;4、先序序列遍历二叉树;5、求二叉树的深度;6、求二叉树节点的个数。

二叉树基本操作--实验报告

二叉树基本操作--实验报告

⼆叉树基本操作--实验报告实验三⼆叉树的基本操作学院:物理与电⼦学院班级:电信1105班姓名:刘岩学号:29⼀、实验⽬的1、熟悉⼆叉树的基本操作,掌握⼆叉树的实现以及实际应⽤。

3、加深对于⼆叉树的理解,逐步培养解决实际问题的编程能⼒。

⼆、实验环境1台WINDOWS环境的PC机,装有Visual C++ 。

三、实验内容1、问题描述现需要编写⼀套⼆叉树的操作函数,以便⽤户能够⽅便的利⽤这些函数来实现⾃⼰的应⽤。

其中操作函数包括:1>创建⼆叉树CreateBTNode(*b,*str):根据⼆叉树括号表⽰法的字符串*str⽣成对应的链式存储结构。

2>输出⼆叉树DispBTNode(*b):以括号表⽰法输出⼀棵⼆叉树。

3>查找结点FindNode(*b,x):在⼆叉树b中寻找data域值为x的结点,并返回指向该结点的指针。

4>求⾼度BTNodeDepth(*b):求⼆叉树b的⾼度。

若⼆叉树为空,则其⾼度为0;否则,其⾼度等于左⼦树与右⼦树中的最⼤⾼度加l。

5>求⼆叉树的结点个数NodesCount(BTNode *b)6>先序遍历的递归算法:void PreOrder(BTNode *b)7>中序遍历的递归算法:void InOrder(BTNode *b)8>后序遍历递归算法:void PostOrder(BTNode *b)9>层次遍历算法void LevelOrder(BTNode *b)2、基本要求实现以上9个函数。

主函数中实现以下功能:创建下图中的树b输出⼆叉树b找到’H’节点,输出其左右孩⼦值输出b的⾼度输出b的节点个数输出b的四种遍历顺序3、程序编写上图转化为⼆叉树括号表⽰法为A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))程序:#include <>#include <>#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);//查找节点int BTNodeHeight(BTNode *b);//求⾼度void DispBTNode(BTNode *b);//输出int NodesCount(BTNode *b);//⼆叉树的结点个数void PreOrder(BTNode *b);//先序遍历递归void InOrder(BTNode *b);//中序遍历递归void PostOrder(BTNode *b);//后序遍历递归void LevelOrder(BTNode *b);//层次遍历//创建void CreateBTNode(BTNode *&b,char *str){BTNode *St[MaxSize],*p=NULL;int top=-1,k,j=0;char ch;b=NULL;ch=str[j];while(ch!='\0'){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)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){ BTNode *p;if(b==NULL)return b;else if(b->data==x)return b;else{p=FindNode(b->lchild,x);if(p!=NULL)return p;elsereturn FindNode(b->rchild,x);}}//求⾼度int BTNodeHeight(BTNode *b){int lchildh,rchildh;if(b==NULL)return (0);else{lchildh=BTNodeHeight(b->lchild);rchildh=BTNodeHeight(b->rchild);return(lchildh>rchildh)(lchildh+1):(rchildh+1);}}//⼆叉树的结点个数int NodesCount(BTNode *b){if(b==NULL)return 0;elsereturn NodesCount(b->lchild)+NodesCount(b->rchild)+1; }//先序遍历递归void PreOrder(BTNode *b){ if(b!=NULL){printf("%c",b->data); PreOrder(b->lchild); PreOrder(b->rchild);}}//中序遍历递归void InOrder(BTNode *b){if(b!=NULL){InOrder(b->lchild);printf("%c",b->data); InOrder(b->rchild);}}//后序遍历递归void PostOrder(BTNode *b){ if(b!=NULL){PostOrder(b->lchild); PostOrder(b->rchild);printf("%c",b->data);}}//层次遍历void LevelOrder(BTNode *b){ BTNode *p;BTNode *qu[MaxSize];int front,rear;front=rear=-1;rear++;qu[rear]=b;while(front!=rear){front=(front+1)%MaxSize;p=qu[front];printf("%c",p->data);if(p->lchild!=NULL){rear=(rear+1)%MaxSize;qu[rear]=p->lchild;}if(p->rchild!=NULL){rear=(rear+1)%MaxSize;qu[rear]=p->rchild;}}}void main(){BTNode *b,*p,*lp,*rp;char str[]="A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";//根据树形图改写成的//⼆叉树括号表⽰法的字符串*str //char str[100];scanf("%s",&str);//⾃⾏输⼊括号表⽰的⼆叉树CreateBTNode(b,str); //创建树bprintf("\n");printf("输出⼆叉树:");//输出⼆叉树bDispBTNode(b);printf("\n");printf("'H'结点:");//找到'H'节点,输出其左右孩⼦值p=FindNode(b,'H');printf("\n");if (p!=NULL){printf("左孩⼦节点的值");printf("%c",p->lchild->data);printf("\n");printf("右孩⼦节点的值");printf("%c",p->rchild->data);printf("\n");//此处输出p的左右孩⼦节点的值}printf("\n");printf("⼆叉树b的深度:%d\n",BTNodeHeight(b));//输出b的⾼度printf("⼆叉树b的结点个数:%d\n",NodesCount(b));//输出b的节点个数printf("\n");printf(" 先序遍历序列:\n");//输出b的四种遍历顺序printf(" 算法:");PreOrder(b);printf("\n");printf(" 中序遍历序列:\n");printf(" 算法:");InOrder(b);printf("\n");printf(" 后序遍历序列:\n");printf(" 算法:");PostOrder(b);printf("\n");printf(" 层次遍历序列:\n");printf(" 算法:");LevelOrder(b); printf("\n");}四、实验⼼得与⼩结通过本次实验,我熟悉⼆叉树的基本知识内容,对课本的知识有了更加深刻的理解与掌握掌握。

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

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

二叉树的基本操作与实现实验报告二叉树是一种重要的数据结构,在计算机科学领域中被广泛应用。

本实验将介绍二叉树的基本操作与实现,并给出相应的实验报告。

一、引言二叉树是一种特殊的树状结构,每个节点至多有两个子节点。

二叉树有许多重要的特性,如平衡二叉树、二叉树等,应用广泛。

在本实验中,我们将介绍二叉树的基本操作和实现。

二、实验目的1.掌握二叉树的基本概念和特性;2.熟悉二叉树的基本操作,包括创建、插入、删除、遍历等;3.学会使用编程语言实现二叉树的基本操作。

三、实验内容本实验主要包括以下内容:1.二叉树的定义和基本概念;2.二叉树的基本操作,包括创建、插入、删除、遍历等;3.使用编程语言实现二叉树的基本操作;4.测试和验证二叉树的基本操作的正确性。

四、实验步骤1.二叉树的定义和基本概念二叉树是一种树状结构,每个节点至多有两个子节点。

二叉树的每个节点包含一个数据项和指向左子树和右子树的指针。

二叉树的特性有很多,如完全二叉树、平衡二叉树、二叉树等。

2.二叉树的基本操作(1)创建二叉树:可以通过手动输入节点数据来创建二叉树,也可以通过读取文件中的数据来创建二叉树。

(2)插入节点:在指定位置插入一个新节点。

(3)删除节点:删除指定位置的节点。

(4)遍历二叉树:有前序遍历、中序遍历和后序遍历三种遍历方式。

3.使用编程语言实现二叉树的基本操作实现二叉树的基本操作可以使用编程语言来完成。

我们可以定义一个二叉树的结构体,包含节点数据和指向左右子树的指针。

然后根据具体的需求,实现相应的操作函数。

4.测试和验证二叉树的基本操作的正确性在完成二叉树的基本操作后,我们可以编写测试代码来验证操作的正确性。

通过创建二叉树,并进行插入、删除和遍历操作,观察输出结果是否符合预期。

五、实验结果与分析在完成二叉树的基本操作后,我们可以进行测试和验证。

通过输出二叉树的遍历结果,比对预期结果来判断操作是否正确。

同时,我们还可以观察二叉树的结构和特性,如是否满足平衡二叉树或二叉树的条件。

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

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

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

二叉树的基本操作包括创建、遍历、插入和删除等。

本实验旨在通过实践来深入了解二叉树的基本操作,并通过实验结果验证其正确性和有效性。

一、创建二叉树创建二叉树是二叉树操作中的第一步。

在本实验中,我们使用了递归算法来创建二叉树。

递归算法是一种重要的算法思想,通过将问题划分为更小的子问题来解决复杂的问题。

在创建二叉树时,我们首先创建根节点,然后递归地创建左子树和右子树。

二、遍历二叉树遍历二叉树是对二叉树中的每个节点进行访问的过程。

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

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

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

插入节点的过程需要遵循二叉树的特性,即左子节点的值小于父节点的值,右子节点的值大于父节点的值。

在插入节点时,我们需要找到合适的位置,将新节点插入到正确的位置上。

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

删除节点的过程相对复杂,需要考虑多种情况。

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

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

如果要删除的节点有两个子节点,我们需要找到其后继节点或前驱节点来替代被删除的节点。

实验结果:通过实验,我们成功地实现了二叉树的基本操作。

创建二叉树的递归算法能够正确地创建出符合要求的二叉树。

遍历二叉树的算法能够按照指定的顺序遍历每个节点。

插入节点和删除节点的操作也能够正确地修改二叉树的结构。

讨论与总结:二叉树的基本操作是数据结构中的重要内容,对于理解和应用其他数据结构具有重要意义。

通过本次实验,我们深入了解了二叉树的创建、遍历、插入和删除等操作,并通过实验验证了其正确性和有效性。

实验报告 实验三 二叉排序树的建立和查找

实验报告 实验三 二叉排序树的建立和查找

实验三二叉排序树的建立和查找一、实验目的1.掌握二叉排序树的建立算法2.掌握二叉排序树查找算法。

二、实验环境操作系统和C语言系统三、预习要求复习二叉排序树的生成及查找算法,编写完整的程序。

四、实验内容实现二叉排序树上的查找算法。

具体实现要求:用二叉链表做存储结构,输入键值序列,建立一棵二叉排序树并在二叉排序树上实现查找算法。

五、参考算法#include <stdio.h>#include <stdlib.h>typedef int InfoType;typedef int KeyType; /*假定关键字类型为整数*/typedef struct node /*结点类型*/{KeyType key; /*关键字项*/InfoType otherinfo; /*其它数据域,InfoType视应用情况而定,下面不处理它*/struct node *lchild,*rchild; /*左右孩子指针*/}BSTNode;typedef BSTNode *BSTree; /*BSTree是二叉排序树的类型*/BSTNode *SearchBST(BSTree T,KeyType key){ /*在二叉排序树T上查找关键字为key的结点,成功时返回该结点位置,否则返回NULL*/if(T==NULL||key==T->key) /*递归的终结条件*/return T; /*若T为空,查找失败;否则成功,返回找到的结点位置*/if(key<T->key)return SearchBST(T->lchild,key);elsereturn SearchBST(T->rchild,key); /*继续在右子树中查找*/}void InsertBST(BSTree *T,int key){ /*插入一个值为key的节点到二叉排序树中*/BSTNode *p,*q;if((*T)==NULL){ /*树为空树*/(*T)=(BSTree)malloc(sizeof(BSTNode));(*T)->key=key;(*T)->lchild=(*T)->rchild=NULL;}else{p=(*T);while(p){q=p;if(p->key>key)p=q->lchild;else if(p->key<key)p=q->rchild;else{printf("\n 该二叉排序树中含有关键字为%d的节点!\n",key);return;}}p=(BSTree)malloc(sizeof(BSTNode));p->key=key;p->lchild=p->rchild=NULL;if(q->key>key)q->lchild=p;elseq->rchild=p;}}BSTree CreateBST(void){ /*输入一个结点序列,建立一棵二叉排序树,将根结点指针返回*/BSTree T=NULL; /*初始时T为空树*/KeyType key;scanf("%d",&key); /*读入一个关键字*/while(key){ /*假设key=0是输入结束标志*/ InsertBST(&T,key); /*将key插入二叉排序树T*/scanf("%d",&key); /*读入下一关键字*/}return T; /*返回建立的二叉排序树的根指针*/ }void ListBinTree(BSTree T) /*用广义表示二叉树*/{if(T!=NULL){printf("%d",T->key);if(T->lchild!=NULL||T->rchild!=NULL){printf("(");ListBinTree(T->lchild);if(T->rchild!=NULL)printf(",");ListBinTree(T->rchild);printf(")");}}}void main(){BSTNode *SearchBST(BSTree T,KeyType key);void InsertBST(BSTree *Tptr,KeyType key);BSTree CreateBST();void ListBinTree(BSTree T);BSTree T;BSTNode *p;int key;printf("请输入关键字(输入0为结束标志):\n");T=CreateBST();ListBinTree(T);printf("\n");printf("请输入欲查找关键字:");scanf("%d",&key);p=SearchBST(T,key);if(p==NULL)printf("没有找到%d!\n",key);elseprintf("找到%d!\n",key);ListBinTree(p);printf("\n");}实验中出现的问题及对问题的解决方案输入数据时,总是不能得到结果,原因是在建立二叉树函数定义中,是对指针的值进行了修改。

数据结构二叉树实验报告

数据结构二叉树实验报告

实验三二叉树的遍历一、实验目的1、熟悉二叉树的结点类型和二叉树的基本操作。

2、掌握二叉树的前序、中序和后序遍历的算法。

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

二、实验环境运行C或VC++的微机。

三、实验内容1、依次输入元素值,以链表方式建立二叉树,并输出结点的值。

2、分别以前序、中序和后序遍历二叉树的方式输出结点内容。

四、设计思路1. 对于这道题,我的设计思路是先做好各个分部函数,然后在主函数中进行顺序排列,以此完成实验要求2.二叉树采用动态数组3.二叉树运用9个函数,主要有主函数、构建空二叉树函数、建立二叉树函数、访问节点函数、销毁二叉树函数、先序函数、中序函数、后序函数、范例函数,关键在于访问节点五、程序代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define OK 1#define ERROR 0typedef 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);}-void PreOrderT(Tree *T,void(*visit)(int))//先序遍历T{if(*T) // 二叉树非空{visit((*T)->data); // 先访问根结点PreOrderT(&((*T)->lchild),visit); // 递归调用函数,先序遍历左子树PreOrderT(&((*T)->rchild),visit); // 递归调用函数,先序遍历右子树}}void InOrderT(Tree *T,void(*visit)(int)){if(*T){InOrderT(&((*T)->lchild),visit); // 递归调用函数,中序遍历左子树visit((*T)->data); // 访问根结点InOrderT(&((*T)->rchild),visit); // 递归调用函数,中序遍历右子树}}void PostOrderT(Tree *T,void(*visit)(int)){if(*T){PostOrderT(&((*T)->lchild),visit); // 递归调用函数,后序遍历左子树PostOrderT(&((*T)->rchild),visit); // 递归调用函数,序遍历右子树visit((*T)->data); // 访问根结点}}void example(){int i;printf("如果你想建立如图所示的二叉树\n");printf("\n");printf(" 1 \n");printf(" / \\ \n");printf(" 3 3 \n");printf(" / \\ \\ \n");printf(" 4 5 7 \n");printf("\n");printf("请输入:1 3 4 00 00 5 00 00 3 00 7 00 00\n");printf("\n按先序次序输入二叉树中结点的值(输入00表示节点为空)\n");for(i=0;i<71;i++)printf("*");printf("\n");}int main (){Tree T;printf("**************欢迎使用!**************潘俊达\n"); example();printf("\n请输入所要建立的二叉树:\n");CreateT(&T);InitT(&T);int i;printf("先序遍历二叉树:\n");PreOrderT(&T,visit);printf("\n");printf("\n中序遍历二叉树:\n");InOrderT(&T,visit);printf("\n");printf("\n后序遍历二叉树:\n");PostOrderT(&T,visit);printf("\n");system("PAUSE");return 0;}六、程序截图1.范例函数显示,并输入先序二叉树节点值2.先序遍历二叉树3.中序遍历二叉树3.后序遍历二叉树。

实验三二叉树

实验三二叉树

实验三二叉树实验三二叉树操作实验目的掌握二叉树的定义、性质及存储方式,各种遍历算法。

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

示例程序:#include"stdio.h"#include"string.h"#include#include#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 中序遍历===============//==========LRN 后序遍历============//=====采用后序遍历求二叉树的深度、结点数及叶子数的递归算法======== int TreeDepth(BinTree T){int hl,hr,max;if(T){hl=TreeDepth(T->lchild); //求左深度hr=TreeDepth(T->rchild); //求右深度(1)//取左右深度的最大值(2)//求结点数if(hl==0&&hr==0)(3)//若左右深度为0,即为叶子。

二叉树的基本操作实验

二叉树的基本操作实验
六 运行结果
图(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. 二叉树的删除
实验结果:
1. 建立一颗二叉树,根节点为A,左子树B,右子树C,B的左子树D,右子树E,C的左子树F,右子树G。

结构如下:
A
/ \
B C
/ \ / \
D E F G
2. 对上述二叉树先进行中序遍历:DBEAFCG,再进行前序遍历:ABDECFG,最后进行后序遍历:DEBFGCA。

3. 在上述二叉树中查找元素G,并输出其父节点元素C。

4. 删除上述二叉树中的元素F,再对其进行中序遍历,结果为DBEACG。

结论:
通过这次实验,我们掌握了二叉树的基本操作方法,对于理解和分析算法、编写系统和软件工程都具有重要的意义。

同时,在实践中我们也深刻地认识到了二叉树操作的复杂性和局限性,这需要我们在实际应用中加以考虑和综合利用,才能发挥其最大的价值和作用。

实验三二叉树及其操作算法实现

实验三二叉树及其操作算法实现
二叉树是由一个根结点和两棵分别称为左子树
和右子树的互不相交的二叉树构成。
满二叉树
种类: 完全二叉树、非完全二叉树 平衡二叉树、非平衡二叉树
二叉树的性质
1、二叉树的第i层上至多有2i-1(i>=1)个结点。
2、深度为h的二叉树中至多含有2h-1个结点。
3、在任意二叉树中,若有n0个叶子结点,n2
printf("The tree is:\n"); for(k=1;k<=N;k++) {printf("%d,%d,%d\n",v[k],l[k],r[k]);}
}
了二叉树中的一个结点i。在输出二叉树时
,只要输出此三个数组就行了。
五、算法
构造算法: 1、读入一个数据元素,建立一个新 结点; 2、若二叉树为空,则新结点为根结 点; 3、若二叉树非空,则将新结点与根 结点值比较,如果小于根结点值,则插入 到左子树中,否则插入到右子树中。
具体算法如下:
TH←0 FOR K=1 TO n DO { READ X; V(k)←X; L(k)←R(k)←0; i=TH IF i=0 THEN TH←k ELSE {WHILE (L(i)!=k) AND (R(i)!=k) DO {IF X<V(i) THEN [插入到左子树] {IF L(i)!=0 TEHN i←L(i) ELSE L(i)←k} ELSE [插入到右子树] {IF R(i)!=0 THEN i←R(i) ELSE R(i)←k} } } }
六、程序清单
#include <stdio.h> #include <math.h> #define N 10 main() {int i,j,k,tree; int a[N],v[N],l[N],r[N]; for(j=1;j<=N;j++) {a[j]=rand()%100;} printf("The numbers are:\n"); for(j=1;j<=N;j++) {printf("%d,",a[j]);} printf("\n");

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

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

数据结构实验报告实验名称:实验三——二叉树学生姓名: XX班级:班内序号:学号:日期:1.实验要求1.1实验目的通过选择下面两个题目之一进行实现,掌握如下内容:掌握二叉树基本操作的实现方法了解赫夫曼树的思想和相关概念学习使用二叉树解决实际问题的能力1.2实验内容根据二叉树的抽象数据类型的定义,使用二叉链表实现一个二叉树。

二叉树的基本功能:1、二叉树的建立2、前序遍历二叉树3、中序遍历二叉树4、后序遍历二叉树5、按层序遍历二叉树6、求二叉树的深度7、求指定结点到根的路径8、二叉树的销毁9、其他:自定义操作编写测试main()函数测试线性表的正确性2. 程序分析2.1 存储结构二叉树的结点结构二叉树的二叉链表存储示意图2.2 关键算法分析(1)创建一个二叉树伪代码实现:1.定义根指针,输入节点储存的data,若输入“#”,则该节点为空;2.申请一个新节点,判断它的父结点是否不为空,如果不为空在判断其为左或者右孩子,并把地址付给父结点,把data写入。

代码实现void BiTree::create(BiNode* &R,int data[],int i,int n)//创建二叉树{if(i<=n){R=new BiNode;R->data=data[i-1];create(R->lch,data,2*i,n);create(R->rch,data,2*i+1,n);}else R=NULL;}(2)前序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.打印起始节点的值,并先后在左子数右子数上递归调用打印函数代码实现void BiTree::preorder(BiNode* R)//前序遍历{if(R!=NULL){cout<<R->data;preorder(R->lch);preorder(R->rch);}}时间复杂度:O(n)(3)中序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.递归遍历左子树3.打印根节点数据域内容4.递归遍历右子树代码实现void BiTree::inorder(BiNode* R)//中序遍历{if(R!=NULL){inorder(R->lch);cout<<R->data;inorder(R->rch);}}时间复杂度:O(n)(4)后序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.递归遍历左子树3.递归遍历右子树4.访问根结点数据域代码实现void BiTree::postorder(BiNode* R)//后序遍历{if(R!=NULL){postorder(R->lch);postorder(R->rch);cout<<R->data;}}时间复杂度:O(n)(5)层序遍历伪代码实现1.队列Q及所需指针的定义和初始化2.如果二叉树非空,将根指针入队3.循环直到队列Q为空3.1 q=队列Q的队头元素出队3.2 访问节点q的数据域 cout<<q->data<<" ";3.3 若节点q存在左孩子,则将左孩子指针入队3.4若节点q存在右孩子,则将右孩子指针入队代码实现void BiTree::levelordre(BiNode* R)//层序遍历{BiNode*queue[maxsize];int f=0,r=0;if(R!=NULL)queue[++r]=R;while(f!=r){BiNode*p=queue[++f];cout<<p->data;if(p->lch!=NULL)queue[++r]=p->lch;if(p->rch!=NULL)queue[++r]=p->rch;}}时间复杂度:O(n)(6)计算二叉树深度伪代码实现:1. 定义和初始化计数深度的参数2.如果根节点为空,return03.如果根节点为非空,递归调用自身的到叶子节点到根的路径长度,输出其中较大的作为树的深度代码实现int BiTree::depth(BiNode* root)//求二叉树深度{int ld,rd;if (root!=NULL){ld = 1+depth(root->lch);rd = 1+depth(root->rch);return ld>rd?ld:rd;}else return 0;}时间复杂度:O(n)(7)输出指定结点到根结点的路径伪代码实现:1.建立一个存储路径结点结构,定义和初始化结构体的数组2.当root不为空或top为0时,进入循环3.当此时root所指的节点的数据不为指定数据时,将root指向它的左孩子4.当此时root所指的节点的数据为指定数据时,访问其数据域并输出代码实现bool BiTree::printPath(BiNode* root, int data)//打印指定结点到根节点的路径{if (root == NULL)return false;if (root->data == data || printPath(root->lch,data) ||printPath(root->rch,data)){cout<<root->data;return true;}return false;}3. 程序运行结果3.1测试主函数流程图:3.2测试条件对如下二叉树: 补全后的二叉树:按层序遍历的输入方法为:ABC#EFGH###I###J###@ 3.3程序运行结果为:4. 总结出现的问题及改进:刚开始编译正确但是输出结果异常,纪念馆仔细检查发现二叉树创建有问题,经过仔细修改,发现形参表示错误,*&,指针的引用,作为输入时,既把指针的值传入函数内部,又可以将指针的关系传递到函数内部;作为输出,由于算法中修改了指针的值,可以将新值传入到函数内部。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(3)将输入的值赋给当前节点的data域,并前序建立当前节点的左子树和右子树。
(4)返回当前节点。
前序遍历树:
(1)若当前节点为空则返回上一级函数,否则打印当前节点。
(2)前序遍历当前节点的左子树。
(3)前序遍历当前节点的右子树。
中序遍历树:
(1)声明一个顺序栈,并用p指针指向当前节点。
(2)若当前节点和栈不同时为空则重复进行下一步。否则程序结束
5分
成绩
成绩栏
其它批改意见:
教师签字:
考核内容
评价在实验课堂中的表现,包括实验态度、编写程序过程等内容等。
□功能完善,
□功能不全
□有小错
□无法运行
○正确
○基本正确
○有提示
○无法回答
○完整
○较完整
○一般
○内容极少
○பைடு நூலகம்报告
○有
○无
○有
○无
一、实验目的
理解二叉树的逻辑特点和二叉树的性质;掌握二叉树的二叉链表存储结构,掌握二叉树的创建算法、遍历算法的递归与非递归实现,并能在遍历算法基础上实现较复杂算法设计。
(2)后序遍历当前节点的左子树。
(3)后序遍历当前节点的右子树。
(3)打印当前节点的data。
2、
(1)若当前节点为空则返回NULL,结束。否则执行下一步。
(2)利用中间变量temp交换当前节点的左右子树。
(3)交换当前的点左子树根节点的左右子树。
(4)交换当前节点右子树根节点的左右子树。
(4)返回根节点。
(4)用变量len记录队列中二叉树当前层的节点数。
(5)若len为0则结束整个程序,否则执行第六步。
(6)当len>0(即队列中还有前层的节点时)重复七~九步。否则执行第十步。
(7)将当前对头出栈,len++,打印出队元素
(8)如果出队元素的左子树的根节点不为空则入队,len--.
(9)如果出队元素的右子树的根节点不为空则入队,len--.
1)问题描述:编写一算法,交换二叉树中所有结点的左、右子树
2)实验要求:以二叉链表作为存储结构
3.试编写按层次顺序遍历二叉树的算法
1)问题描述:编写按层次顺序遍历二叉树的算法
2)实验要求:以二叉链表作为存储结构
4.编写算法求二叉树高度及宽度。
1)问题描述:二叉树高度是指树中所有节点的最大层数,二叉树宽度是指在二叉树的各层上,具有节点数最多的那一层上的节点总数。
2、在前序遍历的过程中利用中间变量交换左右子树。
3、利用队列。当上一层中的数据全部出队(遍历)完毕再遍历本层节点。
4、高度:获取所有节点到根节点的最长路径。宽度:在层次遍历的基础上,返回最多节点的层的节点数。
算法描述:可以用自然语言、伪代码或流程图等方式
1、创建树:
(1)声明节点
(2)输入当前节点,若输入为#则当前节点为空,否则为当前节点申请空间。
(10)当前层最大节点数等于上一层最大节点数和当前队列中的节点数中较大的一个。
执行第三步。
算法的实现和测试结果:包括算法运行时的输入、输出,实验中出现的问题及解决办法等
1、
输入:ABH##FD###E#CK##G##
输出:
2、
输入:ABH##FD###E#CK##G##
输出:
3、
输入:ABH##FD###E#CK##G##
(3)若当前节点不为空则重复进行第四步,否则执行第五步。
(4)在栈不满的情况下将当前节点入栈,并把p指针指向当前节点左子树的根节点。
(5)若栈为空则执行第三步,否则执行第六步。
(6)将栈顶元素出栈,并打印栈顶元素的data,将p指向栈顶元素的右子树的根节点。执行第二步。
前序遍历树:
(1)若当前节点为空则返回上一级函数否则执行下一步。
二、实验题目与要求
1.每位同学按下述要求实现相应算法:以二叉链表为存储结构,实现二叉树的创建、遍历算法
1)问题描述:在主程序中提供下列菜单:
1…建立树
2…前序遍历树
3…中序(非递归)遍历树
4…后序遍历树0…结束
2)实验要求:
①定义下列过程:
CreateTree():按从键盘输入的前序序列,创建树
PreOrderTree():前序遍历树(递归)
3、
(1)利用指针temp指向根节点,并初始化一个队列。
(2)将temp指向的当点节点入队。
(3)重复指向以下所有步骤,直到遇到break语句。
(4)用变量len记录队列中二叉树当前层的节点数。
(5)若len为0则结束整个程序,否则执行第六步。
(6)当len>0(即队列中还有前层的节点时)重复指向以下所有步骤。否则执行第三步。
2)实验要求:以二叉链表作为存储结构
三、实验过程与实验结果
应包括如下主要内容:
数据结构定义
二叉树是个节点的有限集合,该集合或者为空,或者由一个根节点及两个分别称为左子树和右子树的互不相交的二叉树组成。当集合为空时,称该二叉树为空二叉树。
算法设计思路简介
1、利用递归算法前序建立二叉树,并完成二叉树的前序、中序和后序遍历。其中前序遍历和后序遍历均用递归算法,中序遍历借助栈的机制,实现非递归遍历。
输出:
4、
输入:ABH##FD###E#CK##G##
输出:
算法时间复杂度分析
1、O(n).
2、O(n).
3、O(n).
4、O(n).
四、收获与体会
InOrderTree():中序(非递归)遍历树
LaOrderTree():后序遍历树(递归)
②每位同学在实验过程中要单步运行程序,跟踪二叉树的创建过程与前序遍历的递归过程。
3)注意问题:
①注意理解递归算法的执行步骤。
②注意字符类型数据在输入时的处理。
③重点理解如何利用栈结构实现非递归算
2.编写算法交换二叉树中所有结点的左、右子树
实验报告
学院(系)名称:计算机与通信工程学院
姓名
**
学号
********
专业
计算机科学与技术
班级
2015级*班
实验项目
实验三:二叉树操作
课程名称
数据结构与算法
课程代码
0661013
实验时间
年月日第节
实验地点
7-***
考核标准
实验过程
25分
程序运行
20分
回答问题
15分
实验报告
30分
特色
功能
5分
考勤违纪情况
(7)将当前对头出栈,len++,打印出队元素
(8)如果出队元素的左子树的根节点不为空则入队,len--.
(9)如果出队元素的右子树的根节点不为空则入队,len--.
4、
(1)利用指针temp指向根节点,并初始化一个队列。
(2)将temp指向的当点节点入队。并声明当前层最大节点数为0
(3)重复指向以下所有步骤,直到遇到break语句。若遇到break语句则结束整个程序并返回最大节点数。
相关文档
最新文档