#include #include #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; } } }