《数据结构与算法设计》实验报告书之二叉树的基本操作实现及其应用

《数据结构与算法设计》实验报告书之二叉树的基本操作实现及其应用

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

实验目的
1.熟悉二叉树结点的结构和对二叉树的基本操作。
2.掌握对二叉树每一种操作的具体实现。
3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
4.会用二叉树解决简单的实际问题。

实验内容
设计程序实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。
1、采用二叉树链表作为存储结构,
2、递归建立一个二叉树
4、按(A:先序 B:中序 C:后序 )遍历输出二叉树的所有结点
5、输出二叉树(凹入式)
以上必做,以下选做
6、求二叉树中所有结点数
7、求二叉树的深度
8、求二叉树叶子结点数
9、创建二叉树其他方法
10、图形打印二叉树

算法设计分析

(一)数据结构的定义
在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2(k-1)个叶子节点,至多有2^k-1个节点。
二叉树存储结构定义为:

/*定义二叉树存储结构*/
typedef struct node
{
	datatype data;
	struct node *lchild,*rchild;
}treenode,*treelist;

(二)总体设计
实验总共包括八个函数:主函数,树初始化函数,根据先序序列和中序序列创建二叉树函数,先序创建二叉树函数,先序遍历算法函数,中序遍历算法函数,后序遍历算法函数,打印二叉树函数。

主函数:统筹调用各个函数以实现相应功能
Int main()
void execute()

树初始化函数:建立树的初始化
void treeinit(treelist &bt)

根据先序序列和中序序列创建二叉树函数:根据先序序列和中序序列创建二叉树
treelist treecreate4(char *p,char *m,int len)

先序创建二叉树函数函数:根据先序序列创建二叉树
treelist treecreate()

先序遍历二叉树函数:利用先序遍历的方法遍历整棵树
void DLR( node *root )

中序遍历二叉树函数:利用中序遍历的方法遍历整棵树
void LDR(node *root)

后序遍历二叉树函数:利用后序遍历的方法遍历整棵树
void LRD (node *root)

打印二叉树函数:利用递归的方法打印整棵树
void printInorder(node *root,int height,string to,int len)
void printTree(node *root)

(三)各函数的详细设计:
主函数main()
主要就是进行功能的实现。

树初始化函数void treeinit(treelist &bt):
建立树的初始化

根据先序序列和中序序列创建二叉树函数treelist treecreate4(char *p,char *m,int len):
根据先序序列和中序序列创建二叉树,判断根节点的位置以及叶子节点,通过一层一层的递归实现创建。

先序创建二叉树函数函数treelist treecreate():
根据先序序列创建二叉树,通过输入一个一个的字符创建二叉树,也是通过递归实现,一‘-’表示该节点为空。

先序遍历二叉树函数void DLR( node *root ):
利用先序遍历的方法遍历整棵树,先从跟节点开始,后左右遍历。

中序遍历二叉树函数void LDR(node *root):
利用中序遍历的方法遍历整棵树,先从左孩子开始,再根节点,最后遍历右孩子。

后序遍历二叉树函数void LRD (node *root):
利用后序遍历的方法遍历整棵树,先从左孩子开始,之后从右孩子遍历,最后再根节点。

打印二叉树函数void printInorder(node *root,int height,string to,int len) void printTree(node *root):
利用递归的方法打印整棵树

实验测试结果
先序和中序结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先序创建结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实验总结:(100字到200字)
此部分附上主要程序代码和相关的注释说明、调试数据及过程、问题及解决办法。 (最重要)

(1)调试过程中主要遇到哪些问题?是如何解决的?
答:在建立二叉树的时候还是遇见过一些问题的,就拿先序和中序创建来说,找位置有一些难度,看了老师的代码才发现并没有自己想的那么复杂。还有打印二叉树,说实话,还是不怎么会,这个代码是网上参考的,后面要多加思考,争取能够自己写出打印二叉树的函数。

(2)经验和体会
答:还是那句老话,多敲代码自己练习,有时间把多复习多上网查查资料,增加自己对二叉树数据结构的理解。

附录 实验程序代码(该部分请加注释)
/tree.h函数代码/

typedef struct node
{
	datatype data;
	struct node *lchild,*rchild;
}treenode,*treelist;

//树初始化
void treeinit(treelist &bt)
{
	bt=NULL;
}

treelist treecreate4(char *p,char *m,int len)        //根据先序序列和中序序列创建二叉树;
{
	//*P存放先序序列,*m存放中序序列,len为m中字符个数;
	treelist s;
	char *q;
	int k;
	if(len<=0)
		return NULL;
	s=new treenode();   //创建二叉树结点s;
	s->data=*p;
	figure++;
	for(q=m;q<m+len;q++)       //在中序序列中找等于*p的位置k;
	{
		if(*q==*p)
			break;
	}
	k=q-m;
	s->lchild=treecreate4(p+1,m,k);              //递归构造左子树;
	s->rchild=treecreate4(p+k+1,q+1,len-k-1);     //递归构造右子树;
	return s;
}

treelist treecreate() //先序创建二叉树
{
    treelist s;
    char c;
    std::cin>>c;
    if(c == '-'){
        s = NULL;
    }else{
        s = new treenode();
        s->data = c;
        figure++;                       //构造根结点
        s->lchild = treecreate();  //构造左子树
        s->rchild = treecreate();  //构造右子树
    }
    return s;
}

//先序遍历算法
void DLR( node *root )
{
	if (root !=NULL) //非空二叉树
	{
		cout<<root->data; //访问D
		DLR(root->lchild); //递归遍历左子树
		DLR(root->rchild); //递归遍历右子树
	}
}

//中序遍历算法
void LDR(node *root)
{
	if(root !=NULL)
	{
		LDR(root->lchild);
		cout<<root->data;
		LDR(root->rchild);
	}
}

//后序遍历算法
void LRD (node *root)
{
	if(root !=NULL)
	{
		LRD(root->lchild);
		LRD(root->rchild);
		cout<<root->data;
	}
}

void printInorder(node *root,int height,string to,int len)
{
	if(NULL == root)
		return ;
	printInorder(root->rchild,height+1,"_",len);//先打印右子树
	//打印跟节点
	stringstream ss;
	ss << root->data;
	string val = to + ss.str() + to;
	int lenM = val.length();
	int lenL = (len-lenM)/2;
	int lenR = len -lenM-lenL;
	val = string(lenL,' ') + val + string(lenR,' ');
	std::cout<<string(height*len,' ')<<val<<std::endl;
	printInorder(root->lchild,height+1,"_",len);
	return ;
}

void printTree(node *root)
{
	cout << "Binary Tree:" << endl;
	printInorder(root,0,"_",5);
	cout << endl;
}

/menu.h菜单函数代码/

#ifndef MENU_H_INCLUDED
#define MENU_H_INCLUDED

void menu(){
    std::cout<<"\n";
    std::cout<<" **********************二叉树的应用**********************\n";
    std::cout<<" *                                                      *\n";
    std::cout<<" *     a:(先中)创建二叉树       b:先序创建二叉树        *\n";
    std::cout<<" *     c:先序遍历               d:中序遍历              *\n";
    std::cout<<" *     e:后序遍历               f:二叉树的节点数        *\n";
	std::cout<<" *     g:打印二叉树(凹入型)   h:退出程序              *\n";
    std::cout<<" *                                                      *\n";
    std::cout<<" ********************************************************\n";
}

#endif // MENU_H_INCLUDED

/主函数代码/

#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
using namespace std;
#define maxsize 100
#define infinity 10000			/*定义一个无限大的值*/
typedef char datatype;
int figure=0;//所含结点个数

#include "menu.h"
#include "tree.h"

typedef treelist elem;
char str1[100],str2[100];
int i,j,length;//lever表示层次,h高度
treelist bt;

int main()
{
	treeinit(bt);
    void execute();
	execute();
	return 0;
}
void execute()
{
	char a;
	for(;;)
	{
		menu();
		cin>>a;
		switch (a)
		{
			case 'a':
				cout<<"请输入先序序列和中序序列:"<<endl;
				cin>>str1>>str2;
				length=strlen(str1);
				bt=treecreate4(str1,str2,length);
				break;
            case 'b':
				cout<<"请输入先序序列:"<<endl;
				bt=treecreate();
				break;
			case 'c':
			    cout<<"先序序列为:"<<endl;
				DLR(bt);
				break;
			case 'd':
			    cout<<"中序序列为:"<<endl;
				LDR(bt);
				break;
			case 'e':
			    cout<<"后序序列为:"<<endl;
				LRD(bt);
				break;
            case 'f':
				cout<<"二叉树的节点数为:"<<endl;
				cout<<figure<<endl;
				break;
			case 'g':
				cout<<"打印树(凹入式):"<<endl;
				printTree(bt);
				break;
			case 'h':
				cout<<" 再见!"<<endl;
				return ;
            default:
                cout<<"输入的字符有误,请重新输入!!"<<endl;
                break;
		}
	}
}
  • 43
    点赞
  • 323
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点:左子节点和右子节点。下面是二叉树的一些基本操作: 1. 插入操作:向二叉树中插入一个节点。如果树为空,则新节点将成为根节点。否则,我们需要找到合适的位置来插入新节点。通常,我们从根节点开始,按照一定规则(例如比较节点值)向左或向右遍历树,直到找到一个空位置来插入新节点。 2. 删除操作:从二叉树中删除一个节点。删除操作有三种情况:(1)被删除的节点没有子节点,这种情况下,只需将其父节点对应的子节点指针置为空即可。(2)被删除的节点有一个子节点,这种情况下,将其子节点替代被删除的节点即可。(3)被删除的节点有两个子节点,这种情况下,需要找到它的后继节点(通常是右子树中最小的节点),将后继节点的值复制给要删除的节点,并删除后继节点。 3. 查找操作:在二叉树中查找一个特定的值。从根节点开始,按照一定规则遍历树,直到找到目标值或者遍历完整个树。 4. 遍历操作:遍历二叉树可以按照不同的方式进行,常见的有三种遍历方式:前序遍历、中序遍历和后序遍历。前序遍历先访问根节点,在递归地遍历左子树和右子树;中序遍历先递归地遍历左子树,再访问根节点,最后递归地遍历右子树;后序遍历先递归地遍历左子树和右子树,最后访问根节点。 5. 翻转操作:将二叉树左右子节点交换。可以通过递归或迭代的方式实现。 这些是二叉树的一些基本操作,它们在实际应用中非常常见且有广泛的应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值