设二叉树采用二叉链表存储结构,结点数据域为字符类型。编写程序,用先序递归遍历法创建二叉树的二叉链表存储结构。而后输入一个字符,输出该字符在先、中、后序遍历中的访问次序(访问次序从1开始)以及先、中、后序遍历结果。若输入的字符不在二叉树中,输出相应提示信息。要求程序能够反复输入字符并输出访问次序及遍历结果,直到输入某个特殊字符时结束程序。注意:输入单个字符时需对其后的换行符进行处理。node
用结构体创建二叉树的二叉链表结构。其中,data表示数据域,lchild表示左指针,rchild表示右指针,BiT表示二叉链表结构体指针类型变量,BiTNode表示二叉链表结构体类型变量。ios
#include <iostream> using namespace std; typedef struct node //二叉链表 { ElemTp data; //数据域 struct node *lchild, //左指针 *rchild; //右指针 }*BiT, BiTNode; void visit(BiT e) //访问函数 { if (e->data != NULL) //输出二叉树的数据域 cout << e->data << " "; } void preorder(BiT bt) //先序遍历二叉树 { if (bt) { visit(bt); //访问根节点 preorder(bt->lchild); //递归调用遍历左子树 preorder(bt->rchild); //递归调用遍历右子树 } } void midorder(BiT bt) //中序遍历二叉树 { if (bt) { midorder(bt->lchild); //递归调用遍历左子树 visit(bt); //访问根节点 midorder(bt->rchild); //递归调用遍历右子树 } } void lasorder(BiT bt) //后序遍历二叉树 { if (bt) { lasorder(bt->lchild); //递归调用遍历左子树 lasorder(bt->rchild); //递归调用遍历右子树 visit(bt); //访问根节点 } } BiT crtPreBT() //先序递归遍历创建二叉树算法 { BiT bt; char ch; ch = getchar(); if (ch == '#') //读到‘#’返回NULL指针 return NULL; bt = new BiTNode(); //创建新的二叉树结点 bt->data = ch; bt->lchild = crtPreBT(); //递归创建左子树 bt->rchild = crtPreBT(); //递归创建右子树 return bt; } void prefind(BiT bt, ElemTp c, int &k) //先序查询(bt为根节点,c为查询元素,k记录查询元素的位置) { if (!bt || k > 0) //bt为空,或者k>0,直接返回 return; k--; if (bt->data == c) //查询到了元素c,将k变为k的相反数 k = -k; if (k > 0) return; prefind(bt->lchild, c, k); //递归查询左子树 prefind(bt->rchild, c, k); //递归查询右子树 } void midfind(BiT bt, ElemTp c, int &k) //中序查询(bt为根节点,c为查询元素,k记录查询元素的位置) { if (!bt || k > 0) //bt为空,或者k>0,直接返回 return; midfind(bt->lchild, c, k); //递归查询左子树 if (k > 0) return; k--; if (bt->data == c) //查询到了元素c,将k变为k的相反数 k = -k; midfind(bt->rchild, c, k); //递归查询右子树 } void lasfind(BiT bt, ElemTp c, int &k) //后序查询(bt为根节点,c为查询元素,k记录查询元素的位置) { if (!bt || k > 0) //bt为空,或者k>0,直接返回 return; lasfind(bt->lchild, c, k); //递归查询左子树 lasfind(bt->rchild, c, k); //递归查询右子树 if (k > 0) return; k--; if (bt->data == c) //查询到了元素c,将k变为k的相反数 k = -k; } int main() { int pre_n, mid_n, las_n; pre_n = mid_n = las_n = 0; //pre_n, mid_n, las_n分别记录先序、中序、后序中该元素的位置 ElemTp c; BiT bt; cout << "请输入先序遍历的字符序列: " << endl; bt = crtPreBT(); cout << "先序遍历结点访问次序: " << endl; preorder(bt); cout << endl; cout << "中序遍历结点访问次序: " << endl; midorder(bt); cout << endl; cout << "后序遍历结点访问次序: " << endl; lasorder(bt); cout << endl; cout << "请输入要查找的字符('#'结束): " << endl; cin >> c; while (c != '#') //输入'#'结束 { prefind(bt, c, pre_n); midfind(bt, c, mid_n); lasfind(bt, c, las_n); cout << "先序遍历结点访问次序: " << endl; preorder(bt); cout << endl; cout << "中序遍历结点访问次序: " << endl; midorder(bt); cout << endl; cout << "后序遍历结点访问次序: " << endl; lasorder(bt); cout << endl; if (pre_n > 0 && mid_n > 0 && las_n > 0) { cout << "先序遍历中该字符的访问次序为: " << pre_n << endl; cout << "中序遍历中该字符的访问次序为: " << mid_n << endl; cout << "后序遍历中该字符的访问次序为: " << las_n << endl; } else cout << "二叉树中不存在该字符" << endl; pre_n = mid_n = las_n = 0; cout << "请输入下一个要查找的字符('#'结束): " << endl; cin >> c; } return 0; }
(1)程序输入:
先序序列:ABC##DE#G##F###
请输入要查找的字符('#'结束):A G #
程序输出
先序遍历:A B C D E G F
中序遍历:C B E G D F A
后序遍历:C G E F D B A
A: 先序遍历中该字符的访问次序:1
中序遍历中该字符的访问次序:7
后序遍历中该字符的访问次序:7
G: 先序遍历中该字符的访问次序:6
中序遍历中该字符的访问次序:4
后序遍历中该字符的访问次序:2
(2)程序输入:
先序序列:ABDF####C#E#G#H##
请输入要查找的字符('#'结束):H R #
程序输出
先序遍历:A B D F C E G H
中序遍历:F D B A C E G H
后序遍历:F D B H G E C A
H: 先序遍历中该字符的访问次序:8
中序遍历中该字符的访问次序:8
后序遍历中该字符的访问次序:4
R: 二叉树中不存在该字符算法