编写一个程序,实现二叉树的基本运算,具体要求如下:(指定示范实例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");
}
运行测试:
都是递归代码,好好理解