設二叉樹採用二叉鏈表存儲結構,結點數據域爲字符類型。編寫程序,用先序遞歸遍歷法創建二叉樹的二叉鏈表存儲結構。而後輸入一個字符,輸出該字符在先、中、後序遍歷中的訪問次序(訪問次序從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: 二叉樹中不存在該字符
算法