数据结构作业:二叉树的基本操作二:(包含树的直径问题)

编写一个程序,实现二叉树的基本运算,具体要求如下:(指定示范实例1:P243图7.34。指定示范实例2:P201图7.13 )

1,先序遍历输出该树(带“^"标志)。

2,中序遍历输出该树(带“^"标志)。

3,后序遍历输出该树(带“^"标志)。

4,层次遍历输出该树(带“^"标志)。

5,输出该树的先序凹入表表示法(参考附件)。

6,输出该树的中序凹入表表示法。

7,输出该树的后序凹入表表示法。

8,设计一个算法把二叉树b所有的左、右子树进行交换,并用括号表示法输出该树。(要求不破坏原二叉树)

9,(选做题)输出该树相隔最远的一对结点。(例:对P243图7.34,N与I相隔最远。提示:相隔最远不一定分别在左右两棵子树上,相隔最远是两个叶子,还有一种就是叶子与根。)

 

头文件代码:BTree_2.h

#include<bits/stdc++.h>
#include<ctime>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<iostream>
#include<cstdio>
#include<time.h>

using namespace std;
const int N = 50;
typedef char ElemType;


//二叉树结构体
typedef struct node {
	ElemType data;         //数据域
	struct node* lchild;   //左孩子
	struct node* rchild;   //右孩子
}BTNode;


/*----------------------------------------------二叉树基本操作-------------------------------------------------------------------------*/

//1.创建二叉树
void CreateBTree(BTNode*& b, char* str)
{
	BTNode* St[N], * p;     //St数组充当栈
	int top = -1, k, j = 0; //top为栈顶指针,j为遍历的数据下标,k用来标记是左儿子还是右儿子
	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];
	}
}

// 2.输出二叉树
void DispBTree(BTNode* b)
{
	if (b != NULL)
	{
		cout << b->data;
		if (b->lchild != NULL || b->rchild != NULL)
		{
			cout << '(';
			DispBTree(b->lchild);
			if (b->rchild != NULL)cout << ',';
			DispBTree(b->rchild);
			cout << ')';
		}
	}
}

//3.销毁二叉树
void DestroyBTree(BTNode*& b)
{
	if (b != NULL)
	{
		DestroyBTree(b->lchild);  //递归左子树
		DestroyBTree(b->rchild);  //递归右子树
		free(b);
	}
}

/*----------------------------------------------二叉树基本操作---------------------------------------------------------------------------------------*/

/*-------------------------------------------二叉树的基本操作二---------------------------------------------------------------------------------------*/
//1.先序遍历
void PreOrder(BTNode* b)
{
	if (b != NULL){
		cout << b->data;
		PreOrder(b->lchild);
		PreOrder(b->rchild);
	}
	else {
		cout << "^";
	}
}

//2.中序遍历
void InOrder(BTNode* b)
{
	if (b != NULL){
		InOrder(b->lchild);
		cout << b->data;
		InOrder(b->rchild);
	}
	else {
		cout << "^";
	}
}

//3.后序遍历
void PostOrder(BTNode* b)
{
	if (b != NULL) {
		PostOrder(b->lchild);
		PostOrder(b->rchild);
		cout << b->data;
	}
	else {
		cout << "^";
	}
}

//4.树的先序凹入表表示法
void PreOrder2(BTNode* b, int indentLevel, int k) {
	if (b == NULL) return;

	// 输出当前结点
	for (int i = 0; i < indentLevel; i++) cout << "  ";
	cout << b->data;
	for (int i = 0; i < 30 - 2 * indentLevel; i++)
		cout << "=";
	if (k == 0)cout << 'B';
	else if (k == 1)cout << "L";
	else cout << "R";
	cout << endl;
	PreOrder2(b->lchild, indentLevel + 1, 1);
	PreOrder2(b->rchild, indentLevel + 1, 2);

}

//5.树的中序凹入表表示法
void InOrder2(BTNode* b, int indentLevel, int k) {
	if (b == NULL) return;

	InOrder2(b->lchild, indentLevel + 1, 1);
	// 输出当前结点
	for (int i = 0; i < indentLevel; i++) cout << "  ";
	cout << b->data;
	for (int i = 0; i < 30 - 2 * indentLevel; i++)
		cout << "=";
	if (k == 0)cout << 'B';
	else if (k == 1)cout << "L";
	else cout << "R";
	cout << endl;
	
	InOrder2(b->rchild, indentLevel + 1, 2);

}
//6.树的后序凹入表表示法
void PostOrder2(BTNode* b, int indentLevel, int k) {
	if (b == NULL) return;

	PostOrder2(b->lchild, indentLevel + 1, 1);
	PostOrder2(b->rchild, indentLevel + 1, 2);
	// 输出当前结点
	for (int i = 0; i < indentLevel; i++) cout << "  ";
	cout << b->data;
	for (int i = 0; i < 30 - 2 * indentLevel; i++)
		cout << "=";
	if (k == 0)cout << 'B';
	else if (k == 1)cout << "L";
	else cout << "R";
	cout << endl;
}

//7.交换左右孩子
BTNode* swapTree(BTNode* b) 
{
	if (b == NULL) {
		return NULL;
	}

	swapTree(b->lchild);
	swapTree(b->rchild);

	BTNode* temp = b->lchild;
	b->lchild = b->rchild;
	b->rchild = temp;
	return b;
}

//8.(选做题)输出该树相隔最远的一对结点(树的直径问题)
int res=0; //一定记得开成公共的,因为要二次DFS,用于更新 
int dfs(BTNode* node)
{
	if(node==NULL)return 0;
	int left = dfs(node->lchild)+1;
	int right = dfs(node->rchild)+1;
	res=max(res,(left+right)/2);  //更新树的直径长度 
	return max(left,right)+1;  //返回以当前结点为根的子树的最大深度 
}
int DBTree(BTNode *root)
{
	res=0;
	dfs(root);
	return res;
}


 主函数代码:BTree_2.cpp

#include"BTree_2.h"

int main()
{
	BTNode* b;
	char s[100];
	cout<<"一:输入样例7.13,建立二叉树:"<<endl<<endl;
	cin >> s;
	CreateBTree(b, s);
	
	
	cout<<"二、分别输出该样例下二叉树的先序遍历、中序遍历、后序遍历的结果:"<<endl<<endl;
	cout<<"1.先序遍历: ";PreOrder(b);cout<<endl;
	cout<<"2.中序遍历: ";InOrder(b);cout<<endl;
	cout<<"3.后序遍历: "; PostOrder(b);cout<<endl;
	cout<<endl;
	
	
	cout<<"三、分别输出该样例下二叉树的先序遍历、中序遍历、后序遍历凹入表达式:"<<endl;
	
	cout<<"1.先序凹入表达式:"<<endl; PreOrder2(b, 0, 0);cout<<endl<<endl;
	cout<<"2.中序凹入表达式:"<<endl;InOrder2(b, 0, 0);cout<<endl<<endl;
	cout<<"3.后序凹入表达式:"<<endl; PostOrder2(b, 0, 0);cout<<endl<<endl;
	
	
	cout<<"四、交换左右孩子:"<<endl;
	BTNode*p = swapTree(b);
	cout<<"1.用括号表达式输出交换后的二叉树:  ";
	DispBTree(p); 
	cout<<endl<<endl;
	
	cout<<"五、(选做题:好像树的直径(大臣的旅费)!!):输出该树相隔最远的一对结点:"<<endl;
	cout<<"距离最远的一对结点,其实好像就是数的直径吧!那求树的直径的算法就是利用两次DFS"<<endl;
	cout<<"第一次从任意一点出发,去深搜最远的一点(end),然后再以该点(end)出发,再次深搜最远距离,该距离就是树的直径!"<<endl<<endl; 
	cout<<"树的直径为:"<<DBTree(b)<<endl;
	system("pause"); 



}

运行测试:

都是递归代码,好好理解 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值