【數(shù)據(jù)結(jié)構(gòu)】——求二叉樹某結(jié)點在先序、中序喳整、后序遍歷中的訪問次序

題目要求

設(shè)二叉樹采用二叉鏈表存儲結(jié)構(gòu)谆构,結(jié)點數(shù)據(jù)域為字符類型。編寫程序框都,用先序遞歸遍歷法建立二叉樹的二叉鏈表存儲結(jié)構(gòu)搬素。然后輸入一個字符,輸出該字符在先魏保、中熬尺、后序遍歷中的訪問次序(訪問次序從1開始)以及先、中谓罗、后序遍歷結(jié)果粱哼。若輸入的字符不在二叉樹中,輸出相應(yīng)提示信息檩咱。要求程序可以反復輸入字符并輸出訪問次序及遍歷結(jié)果揭措,直到輸入某個特殊字符時結(jié)束程序胯舷。注意:輸入單個字符時需對其后的換行符進行處理。

數(shù)據(jù)結(jié)構(gòu)設(shè)計

用結(jié)構(gòu)體建立二叉樹的二叉鏈表結(jié)構(gòu)绊含。其中桑嘶,data表示數(shù)據(jù)域,lchild表示左指針躬充,rchild表示右指針逃顶,BiT表示二叉鏈表結(jié)構(gòu)體指針類型變量,BiTNode表示二叉鏈表結(jié)構(gòu)體類型變量充甚。

算法設(shè)計簡要描述

  1. 先序遍歷建立二叉樹:遞歸調(diào)用函數(shù)以政,不斷讀取字符,依次建立左子樹和右子樹伴找,當讀取到‘#’字符時盈蛮,返回NULL指針,最終返回根結(jié)點指針疆瑰。
  2. 查詢字符是否在二叉樹中:在while循環(huán)中,反復輸入字符昙啄,依次輸出先序穆役、中序、后序遍歷結(jié)果梳凛,并判斷該字符是否在二叉樹中耿币。

程序代碼

#include <iostream>
using namespace std;
typedef struct node                             //二叉鏈表
{
    ElemTp data;                                //數(shù)據(jù)域
    struct node *lchild,                        //左指針
        *rchild;                                //右指針
}*BiT, BiTNode;
void visit(BiT e)                               //訪問函數(shù)      
{
    if (e->data != NULL)                        //輸出二叉樹的數(shù)據(jù)域
        cout << e->data << "  ";
}
void preorder(BiT bt)                           //先序遍歷二叉樹
{
    if (bt)
    {
        visit(bt);                              //訪問根節(jié)點
        preorder(bt->lchild);                   //遞歸調(diào)用遍歷左子樹
        preorder(bt->rchild);                   //遞歸調(diào)用遍歷右子樹
    }
}
void midorder(BiT bt)                           //中序遍歷二叉樹
{
    if (bt)
    {
        midorder(bt->lchild);                   //遞歸調(diào)用遍歷左子樹
        visit(bt);                              //訪問根節(jié)點
        midorder(bt->rchild);                   //遞歸調(diào)用遍歷右子樹
    }
}
void lasorder(BiT bt)                           //后序遍歷二叉樹
{
    if (bt)
    {
        lasorder(bt->lchild);                   //遞歸調(diào)用遍歷左子樹
        lasorder(bt->rchild);                   //遞歸調(diào)用遍歷右子樹
        visit(bt);                              //訪問根節(jié)點
    }
}
BiT crtPreBT()                                  //先序遞歸遍歷建立二叉樹算法
{
    BiT bt;
    char ch;
    ch = getchar();
    if (ch == '#')                              //讀到‘#’返回NULL指針
        return NULL;    
    bt = new BiTNode();                         //建立新的二叉樹結(jié)點
    bt->data = ch;
    bt->lchild = crtPreBT();                    //遞歸建立左子樹
    bt->rchild = crtPreBT();                    //遞歸建立右子樹
    return bt;
}
void prefind(BiT bt, ElemTp c, int &k)          //先序查詢(bt為根節(jié)點,c為查詢元素,k記錄查詢元素的位置)
{
    if (!bt || k > 0)                           //bt為空,或者k>0,直接返回
        return;
    k--;                        
    if (bt->data == c)                          //查詢到了元素c,將k變?yōu)閗的相反數(shù)
        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為根節(jié)點,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變?yōu)閗的相反數(shù)
        k = -k;
    midfind(bt->rchild, c, k);                  //遞歸查詢右子樹
}
void lasfind(BiT bt, ElemTp c, int &k)          //后序查詢(bt為根節(jié)點,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變?yōu)閗的相反數(shù)
        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 << "先序遍歷結(jié)點訪問次序: " << endl;
    preorder(bt);
    cout << endl;
    cout << "中序遍歷結(jié)點訪問次序: " << endl;
    midorder(bt);
    cout << endl;
    cout << "后序遍歷結(jié)點訪問次序: " << endl;
    lasorder(bt);
    cout << endl;
    cout << "請輸入要查找的字符('#'結(jié)束): " << endl;
    cin >> c;
    while (c != '#')                                //輸入'#'結(jié)束
    {
        prefind(bt, c, pre_n);
        midfind(bt, c, mid_n);
        lasfind(bt, c, las_n);
        cout << "先序遍歷結(jié)點訪問次序: " << endl;
        preorder(bt);
        cout << endl;
        cout << "中序遍歷結(jié)點訪問次序: " << endl;
        midorder(bt);
        cout << endl;
        cout << "后序遍歷結(jié)點訪問次序: " << 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 << "請輸入下一個要查找的字符('#'結(jié)束): " << endl;
        cin >> c;
    }
    return 0;
}

示例

(1)程序輸入
先序序列:ABC##DE#G##F###
請輸入要查找的字符('#'結(jié)束):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##
請輸入要查找的字符('#'結(jié)束):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: 二叉樹中不存在該字符

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末塑悼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子楷掉,更是在濱河造成了極大的恐慌厢蒜,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烹植,死亡現(xiàn)場離奇詭異斑鸦,居然都是意外死亡,警方通過查閱死者的電腦和手機草雕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門巷屿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人墩虹,你說我怎么就攤上這事嘱巾『┝眨” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵浓冒,是天一觀的道長栽渴。 經(jīng)常有香客問我,道長稳懒,這世上最難降的妖魔是什么闲擦? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮场梆,結(jié)果婚禮上墅冷,老公的妹妹穿的比我還像新娘。我一直安慰自己或油,他們只是感情好寞忿,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著顶岸,像睡著了一般腔彰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辖佣,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天霹抛,我揣著相機與錄音,去河邊找鬼卷谈。 笑死杯拐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的世蔗。 我是一名探鬼主播端逼,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼涤久,長吁一口氣:“原來是場噩夢啊……” “哼缚够!你這毒婦竟也來了恋拍?” 一聲冷哼從身側(cè)響起陆馁,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤贫途,失蹤者是張志新(化名)和其女友劉穎苍凛,沒想到半個月后封断,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掀序,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡而昨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年救氯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歌憨。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡着憨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出务嫡,到底是詐尸還是另有隱情甲抖,我是刑警寧澤漆改,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站准谚,受9級特大地震影響挫剑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柱衔,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一樊破、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唆铐,春花似錦哲戚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至王浴,卻和暖如春脆炎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氓辣。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工秒裕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筛婉。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓簇爆,卻偏偏與公主長得像癞松,于是被迫代替她去往敵國和親爽撒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容