二分木のさまざまな操作を実装するプログラムを作成し、これに基づいて次の機能を完了するプログラムを設計します。
(1)二分木を作成します(キーボードを使用してシーケンスをトラバースし、文字列を入力して二分木を生成します) ;
(2)出力プレオーダー、ミドルオーダー、およびポストオーダートラバーサルのトラバーサルシーケンス;
(3)バイナリツリーのノード数をカウントして出力します;
(4)バイナリツリーの深さを計算し
ます文字列を入力し、完全な二分木の特性に従って二分木を生成するキーボード。
例:次のバイナリツリーの入力文字列は次のとおりです。ABD### C#E ##
1.二分木の作成と基本操作
#include<Windows.h>
#include<iostream>
#include<stdio.h>
using namespace std;
//二叉链表的结点类型
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//先序遍历创建二叉树
BiTree CreateBiTree()
{
BiTree T;
char ch;
if ((ch = getchar()) == '#')T = NULL;
else
{
T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = ch;
T->lchild = CreateBiTree();
T->rchild = CreateBiTree();
}
return T;
}
//输出前序遍历二叉树的遍历序列
void PreOrderTraverse(BiTree T)
{
if (T != NULL)
{
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//输出中序遍历二叉树的遍历序列
void InOrderTraverse(BiTree T)
{
if (T != NULL)
{
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
//输出后序遍历二叉树的遍历序列
void PostOrderTraverse(BiTree T)
{
if (T != NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data;
}
}
//计算二叉树结点个数
int NodeCount(BiTree T)
{
if (T == NULL)return 0;
else return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}
//计算叶子结点个数
int Leaf_NodeCount(BiTree T)
{
int a = 0;
if (T == NULL)return 0;
else
{
if (!T->lchild&&!T->rchild)a++;
return a + Leaf_NodeCount(T->lchild) + Leaf_NodeCount(T->rchild);
}
}
//计算树的深度
int Tree_depth(BiTree T)
{
if (T != NULL) {
return MAX(Tree_depth(T->lchild),Tree_depth(T->rchild)) + 1;
}
return 0;
}
int main()
{
BiTree T;
T = CreateBiTree();
while (1)
{
Sleep(1000);
cout << "**************操作介绍***************" << endl;
cout << " 0:退出操作系统 " << endl;
cout << " 1:输出前序遍历二叉树的遍历序列 " << endl;
cout << " 2:输出中序遍历二叉树的遍历序列 " << endl;
cout << " 3:输出后序遍历二叉树的遍历序列 " << endl;
cout << " 4:输出计算二叉树结点个数 " << endl;
cout << " 5:输出计算二叉树叶子结点个数 " << endl;
cout<< " 6:输出计算二叉树的深度 "<<endl;
cout << "*************************************" << endl;
cout << "请输入操作代号:";
int a;
cin >> a;
cout << "***************************************" << endl;
switch (a)
{
case 1:
cout << "该二叉树的前序序列为:";
PreOrderTraverse(T);
cout << endl;
break;
case 2:
cout << "该二叉树的中序序列为:";
InOrderTraverse(T);
cout << endl;
break;
case 3:
cout << "该二叉树的后序序列为:";
PostOrderTraverse(T);
cout << endl;
break;
case 4:
cout << "该二叉树结点个数为:";
int b;
b = NodeCount(T);
cout << b<<"个"<<endl;
break;
case 5:
cout << "该二叉树叶子结点个数为:";
int c;
c = Leaf_NodeCount(T);
cout << c << "个" << endl;
break;
case 6:
cout << "该二叉树的深度为:";
int d;
d = Tree_depth(T);
cout << d <<endl;
break;
}
if (a == 0)break;
}
return 0;
}
操作の結果は次のとおりです。
第二に、手がかりの二分木の作成とトラバース
前の実験に基づいて、次の機能が完了します。
(1)中間次のスレッド化されたバイナリツリー。
(2)スレッド化されたバイナリツリーの中間次のトラバーサルと出力トラバーサルシーケンス。
#include<stdio.h>
#include<iostream>
using namespace std;
//线索二叉树结点结构
typedef struct BiTree {
char data;
int LTag, RTag;
struct BiTree *lchild, *rchild;
}BiTree,*BiThrTree;
BiThrTree pre; //全局变量,(前驱结点)
//创建一个二叉树(先序遍历)
BiThrTree InitTree(BiThrTree T)
{
char ch;
if ((ch = getchar()) == '#')T = NULL;
else
{
T = (BiTree*)malloc(sizeof(BiTree));
T->data = ch;
T->LTag = 0;
T->RTag = 0;
T->lchild=InitTree(T->lchild);
T->rchild=InitTree(T->rchild);
}
return T;
}
//中序线索化二叉树
void Inthreading(BiThrTree T)
{
if (T)
{
Inthreading(T->lchild);
if (T->lchild == NULL) //当T的左儿子为空时
{
T->LTag = 1;
T->lchild = pre;
}
if (!pre->rchild) //当pre的右儿子为空时
{
pre->RTag = 1;
pre->rchild = T;
}
pre = T;
Inthreading(T->rchild);
}
}
//设置根结点
BiThrTree Inorderthreading(BiThrTree head, BiThrTree T)
{
head= (BiTree*)malloc(sizeof(BiTree));
head->LTag = 0;
head->RTag = 1;
head->rchild = NULL;
if(!T)
{
head->rchild = head;
}
else
{
head->lchild = T;
pre = head;
Inthreading(T);
pre->rchild = head;
pre->RTag = 1;
head->rchild = pre;
}
return head;
}
//访问一个结点
void visit(char c)
{
cout<<c<<" ";
}
//中序遍历线索二叉树
void InOrderTraverse(BiThrTree T)
{
BiThrTree p;
p = T->lchild;
while (p != T)
{
while (p->LTag == 0)p = p->lchild;
visit(p->data);
while (p->RTag == 1 && p->rchild != T)
{
p = p->rchild;
visit(p->data);
}
p = p->rchild;
}
}
int main()
{
BiThrTree T = NULL, head = NULL;
cout << "请输入二叉树先序遍历序列:";
T=InitTree(T);
head=Inorderthreading(head,T);
cout << "线索二叉树中序遍历为:";
InOrderTraverse(head);
cout << endl;
return 0;
}
操作の結果は次のとおりです。