199 lines
4.9 KiB
C++
199 lines
4.9 KiB
C++
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#define OK 1
|
||
typedef int Status;
|
||
typedef struct BiTNode
|
||
{
|
||
char data; //结点数据域
|
||
struct BiTNode *lchild, *rchild; //左右孩子指针
|
||
}BiTNode,*BiTree;
|
||
|
||
//1、创建二叉链表:按先序次序输入二叉树中结点的值,创建二叉链表表示的二叉树T
|
||
// 例:建立课本P115图5.10(b)的二叉树--读入字符的顺序为:ABC##DE#G##F###(#表示空树)
|
||
BiTree Create(BiTree &T)
|
||
{
|
||
char ch;
|
||
printf("请输入一个字符:");
|
||
scanf("%c",&ch);
|
||
getchar(); //清空缓冲区,把遗留的\n清除
|
||
//todo list //if: 如果输入的是'#',则建立一棵空树
|
||
//else:否则,递归建立一个二叉树(注意:是按按先序次序创建的二叉树)
|
||
if(ch == '#') {
|
||
T = NULL; //建立空树
|
||
} else {
|
||
T = (BiTree)malloc(sizeof(BiTNode)); //创建新结点
|
||
T->data = ch;
|
||
T->lchild = NULL;
|
||
T->rchild = NULL;
|
||
T->lchild = Create(T->lchild); //递归创建左子树
|
||
T->rchild = Create(T->rchild); //递归创建右子树
|
||
}
|
||
return T;
|
||
}
|
||
|
||
//先序遍历二叉树
|
||
Status PreOrder(BiTree &T)
|
||
{
|
||
//todo list //if: 如果是空树,则返回
|
||
//else:否则,先访问根结点 (D)
|
||
//前序遍历左子树 (L)
|
||
//前序遍历右子树 (R)
|
||
if(T == NULL) {
|
||
return OK;
|
||
} else {
|
||
printf("%c ", T->data); //访问根结点
|
||
PreOrder(T->lchild); //前序遍历左子树
|
||
PreOrder(T->rchild); //前序遍历右子树
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
//中序遍历二叉树
|
||
Status InOrder(BiTree &T)
|
||
{
|
||
//todo list //if: 如果是空树,则返回
|
||
//else:否则,先中序遍历左子树 (L)
|
||
//访问根结点 (D)
|
||
//中序遍历右子树 (R)
|
||
if(T == NULL) {
|
||
return OK;
|
||
} else {
|
||
InOrder(T->lchild); //中序遍历左子树
|
||
printf("%c ", T->data); //访问根结点
|
||
InOrder(T->rchild); //中序遍历右子树
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
//后序遍历
|
||
Status PostOrder(BiTree &T)
|
||
{
|
||
//todo list //if: 如果是空树,则返回
|
||
//else:否则,先后序遍历左子树 (L)
|
||
//后序遍历右子树 (R)
|
||
//访问根结点 (D)
|
||
if(T == NULL) {
|
||
return OK;
|
||
} else {
|
||
PostOrder(T->lchild); //后序遍历左子树
|
||
PostOrder(T->rchild); //后序遍历右子树
|
||
printf("%c ", T->data); //访问根结点
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
//层次遍历1
|
||
void LeverOrder(BiTree &T)
|
||
{
|
||
if (T == NULL) { // 处理空树,避免空指针访问
|
||
printf("二叉树为空!\n");
|
||
return;
|
||
}
|
||
//BT *Queue[100]; //队列
|
||
BiTree Queue[100]; //队列
|
||
char ch;
|
||
int front = 0;
|
||
int rear = 0;
|
||
// 队列边界检查(新增:防止数组越界)
|
||
if (rear >= 100) {
|
||
printf("队列已满,无法入队!\n");
|
||
return;
|
||
}
|
||
Queue[rear++] = T; //根节点入队
|
||
while (front < rear) //当队不空
|
||
{
|
||
ch = Queue[front]->data; //出队队头元素
|
||
printf("%c ",ch);
|
||
if (Queue[front]->lchild){
|
||
if (rear >= 100) {
|
||
printf("队列已满,左孩子无法入队!\n");
|
||
break;
|
||
}
|
||
Queue[rear++] = Queue[front]->lchild;
|
||
}
|
||
if (Queue[front]->rchild){
|
||
if (rear >= 100) {
|
||
printf("队列已满,右孩子无法入队!\n");
|
||
break;
|
||
}
|
||
Queue[rear++] = Queue[front]->rchild;
|
||
}
|
||
front++; // 队头后移,完成出队
|
||
}
|
||
|
||
}
|
||
|
||
//节点总数
|
||
int Count(BiTree &T)
|
||
{
|
||
//todo list //if:如果是空树,则结点个数为0;
|
||
//else:否则,结点个数为左子树的结点个数+右子树的结点个数再+1。
|
||
if(T == NULL) {
|
||
return 0;
|
||
} else {
|
||
return Count(T->lchild) + Count(T->rchild) + 1;
|
||
}
|
||
}
|
||
//叶子节点
|
||
int CountLeaf(BiTree &T)
|
||
{
|
||
//todo list //if:如果是空树,则叶子结点个数为0;
|
||
//else if:如果是叶子结点,则返回1;
|
||
//else否则,为左子树的叶子结点个数+右子树的叶子结点个数。
|
||
if(T == NULL) {
|
||
return 0;
|
||
} else if(T->lchild == NULL && T->rchild == NULL) {
|
||
return 1;
|
||
} else {
|
||
return CountLeaf(T->lchild) + CountLeaf(T->rchild);
|
||
}
|
||
}
|
||
int main()
|
||
{
|
||
BiTree T = NULL; //创建一颗空树
|
||
int choose = -1;
|
||
printf("*********************************************\n");
|
||
printf("********** 实验六 *******\n");
|
||
printf("*********************************************\n");
|
||
printf("********** 1.创建一棵二叉树 *******\n");
|
||
printf("********** 2.先序遍历二叉树 *******\n");
|
||
printf("********** 3.中序遍历二叉树 *******\n");
|
||
printf("********** 4.后序遍历二叉树 *******\n");
|
||
printf("********** 5.层序遍历二叉树 *******\n");
|
||
printf("********** 6.求二叉树节点个数 *******\n");
|
||
printf("********** 7.求二叉数叶子节点个数 *******\n");
|
||
printf("********** 0.退出 *******\n");
|
||
printf("*********************************************\n");
|
||
while (choose)
|
||
{
|
||
printf("\n");
|
||
printf("请输入你的选择项:");
|
||
scanf("%d", &choose);
|
||
getchar(); //清空缓冲区,把遗留的\n清除
|
||
switch (choose)
|
||
{
|
||
case 1:T = Create(T); break; //创建
|
||
printf("\n");
|
||
case 2:
|
||
printf("先序序列为:") ;
|
||
PreOrder(T); break; //先序遍历二叉树
|
||
printf("\n");
|
||
case 3:
|
||
printf("中序序列为:") ;
|
||
InOrder(T); break; //中序遍历二叉树
|
||
printf("\n");
|
||
case 4:
|
||
printf("后序序列为:") ;
|
||
PostOrder(T); break; //后序遍历二叉树
|
||
printf("\n");
|
||
case 5:
|
||
printf("层次序列为:") ;
|
||
LeverOrder(T); break; //层序遍历二叉树
|
||
printf("\n");
|
||
case 6:printf("节点总数为:%d\n", Count(T)); break;//结点总数
|
||
case 7:printf("叶子节点总数为:%d\n", CountLeaf(T)); break; //叶子结点总数
|
||
case 0:exit(0); break;
|
||
}
|
||
}
|
||
}
|