日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现

發布時間:2025/6/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、基本概念

每個結點最多有兩棵子樹,左子樹和右子樹,次序不可以顛倒。

性質:

1、非空二叉樹的第n層上至多有2^(n-1)個元素。

2、深度為h的二叉樹至多有2^h-1個結點。

滿二叉樹:所有終端都在同一層次,且非終端結點的度數為2。

在滿二叉樹中若其深度為h,則其所包含的結點數必為2^h-1。

完全二叉樹:除了最大的層次即成為一顆滿二叉樹且層次最大那層所有的結點均向左靠齊,即集中在左面的位置上,不能有空位置。

對于完全二叉樹,設一個結點為i則其父節點為i/2,2i為左子節點,2i+1為右子節點。

二、存儲結構

順序存儲:

將數據結構存在一塊固定的數組中。

[cpp]?view plaincopyprint?
  • #define?LENGTH?100??
  • typedef?char?datatype;??
  • typedef?struct?node{??
  • ????datatype?data;??
  • ????int?lchild,rchild;??
  • ????int?parent;??
  • }Node;??
  • ??
  • Node?tree[LENGTH];??
  • int?length;??
  • int?root;??
  • ?? 雖然在遍歷速度上有一定的優勢,但因所占空間比較大,是非主流二叉樹。二叉樹通常以鏈式存儲。

    鏈式存儲:

    [cpp]?view plaincopyprint?
  • typedef?char?datatype;??
  • ??
  • typedef?struct?BinNode{??
  • ????datatype?data;??
  • ????struct?BinNode*?lchild;??
  • ????struct?BinNode*?rchild;??
  • }BinNode;??
  • ??
  • typedef?BinNode*?bintree;??????????//bintree本身是個指向結點的指針??

  • ?三、二叉樹的遍歷

    遍歷即將樹的所有結點訪問且僅訪問一次。按照根節點位置的不同分為前序遍歷,中序遍歷,后序遍歷。

    前序遍歷:根節點->左子樹->右子樹

    中序遍歷:左子樹->根節點->右子樹

    后序遍歷:左子樹->右子樹->根節點

    例如:求下面樹的三種遍歷

    ?

    前序遍歷:abdefgc

    中序遍歷:debgfac

    后序遍歷:edgfbca

    四、遍歷的實現

    遞歸實現(以前序遍歷為例,其他的只是輸出的位置稍有不同)

    [cpp]?view plaincopyprint?
  • void?preorder(bintree?t){??
  • ????if(t){??
  • ????????printf("%c?",t->data);??
  • ????????preorder(t->lchild);??
  • ????????preorder(t->rchild);??
  • ????}??
  • }??

  • 非遞歸的實現

    因為當遍歷過根節點之后還要回來,所以必須將其存起來??紤]到后進先出的特點,選用棧存儲。數量確定,以順序棧存儲。

    [cpp]?view plaincopyprint?
  • #define?SIZE?100??
  • typedef?struct?seqstack{??
  • ????bintree?data[SIZE];??
  • ????int?tag[SIZE];???//為后續遍歷準備的??
  • ????int?top;?????//top為數組的下標??
  • }seqstack;??
  • ??
  • void?push(seqstack?*s,bintree?t){??
  • ??
  • ????if(s->top?==?SIZE){??
  • ????????printf("the?stack?is?full\n");??
  • ????}else{??
  • ????????s->top++;??
  • ????????s->data[s->top]=t;??
  • ????}??
  • }??
  • ??
  • bintree?pop(seqstack?*s){??
  • ????if(s->top?==?-1){??
  • ????????return?NULL;??
  • ????}else{??
  • ????????s->top--;??
  • ????????return?s->data[s->top+1];??
  • ????}??
  • }??
  • 1、前序遍歷?

    [cpp]?view plaincopyprint?
  • void?preorder_dev(bintree?t){??
  • ????seqstack?s;??
  • ????s.top?=?-1;?????//因為top在這里表示了數組中的位置,所以空為-1??
  • ????if(!t){??
  • ????????printf("the?tree?is?empty\n");??
  • ????}else{??
  • ????????while(t?||?s.stop?!=?-1){??
  • ????????????while(t){????//只要結點不為空就應該入棧保存,與其左右結點無關??????
  • ??????????????????printf("%c?",t->data);??
  • ????????????????push(&s,t);??
  • ????????????????t=?t->lchild;??
  • ????????????}??
  • ????????????t=pop(&s);??
  • ????????????t=t->rchild;??
  • ????????}??
  • ????}??
  • }??

  • ?2、中序遍歷

    ?

    [cpp]?view plaincopyprint?
  • void?midorder(bintree?t){??
  • ????seqstack?s;??
  • ????s.top?=?-1;??
  • ????if(!t){??
  • ????????printf("the?tree?is?empty!\n");??
  • ????}else{??
  • ????????while(t?||s.top?!=?-1){??
  • ????????????while(t){??
  • ????????????????push(&s,t);??
  • ????????????????t=?t->lchild;??
  • ????????????}??
  • ????????????t=pop(&s);??
  • ????????????printf("%c?",t->data);??
  • ????????????t=t->rchild;??
  • ????????}??
  • ????}??
  • }??
  • ?

    3、后序遍歷

    因為后序遍歷最后還要要訪問根結點一次,所以要訪問根結點兩次。采取夾標志位的方法解決這個問題。

    這段代碼非常糾結,對自己有信心的朋友可以嘗試獨立寫一下。反正我是寫了很長時間。邏輯不難,我畫了一張邏輯圖:

    ?代碼:

    ?

    [cpp]?view plaincopyprint?
  • void?postorder_dev(bintree?t){??
  • ????seqstack?s;??
  • ????s.top?=?-1;??
  • ????if(!t){??
  • ????????printf("the?tree?is?empty!\n");??
  • ????}else{??
  • ????????while(t?||?s.top?!=?-1){????//??樟说耐瑫rt也為空。??
  • ????????????while(t){??
  • ????????????????push(&s,t);??
  • ????????????????s.tag[s.top]?=?0;???//設置訪問標記,0為第一次訪問,1為第二次訪問??
  • ????????????????t=?t->lchild;??
  • ????????????}??
  • ????????????if(s.tag[s.top]?==?0){??//第一次訪問時,轉向同層右結點??
  • ????????????????t=?s.data[s.top];???//左走到底時t是為空的,必須有這步!??
  • ????????????????s.tag[s.top]=1;???????
  • ????????????????t=t->rchild;??
  • ????????????}else?{??
  • ????????????????while?(s.tag[s.top]?==?1){?//找到棧中下一個第一次訪問的結點,退出循環時并沒有pop所以為其左子結點??
  • ????????????????????t?=?pop(&s);??
  • ????????????????????printf("%c?",t->data);??
  • ????????????????}??
  • ????????????????t?=?NULL;?//必須將t置空。跳過向左走,直接向右走??
  • ????????????}??
  • ????????}??
  • ????}??
  • }??

  • ?4、層次遍歷:即每一層從左向右輸出

    元素需要儲存有先進先出的特性,所以選用隊列存儲。

    隊列的定義:

    [cpp]?view plaincopyprint?
  • #define?MAX?1000??
  • ??
  • typedef?struct?seqqueue{??
  • ????bintree?data[MAX];??
  • ????int?front;??
  • ????int?rear;??
  • }seqqueue;??
  • ??
  • ??
  • void?enter(seqqueue?*q,bintree?t){??
  • ????if(q->rear?==?MAX){??
  • ????????printf("the?queue?is?full!\n");??
  • ????}else{??
  • ????????q->data[q->rear]?=?t;??
  • ????????q->rear++;??
  • ????}??
  • }??
  • ??
  • bintree?del(seqqueue?*q){??
  • ????if(q->front?==?q->rear){??
  • ????????return?NULL;??
  • ????}else{??
  • ????????q->front++;??
  • ????????return?q->data[q->front-1];??
  • ????}??
  • }??

  • 遍歷實現?

    [cpp]?view plaincopyprint?
  • void?level_tree(bintree?t){??
  • ????seqqueue?q;??
  • ????bintree?temp;??
  • ????q.front?=?q.rear?=?0;??
  • ????if(!t){??
  • ????????printf("the?tree?is?empty\n");??
  • ????????return?;??
  • ????}??
  • ????enter(&q,t);??
  • ????while(q.front?!=?q.rear){??
  • ????????t=del(&q);??
  • ????????printf("%c?",t->data);??
  • ????????if(t->lchild){??
  • ????????????enter(&q,t->lchild);??
  • ????????}??
  • ????????if(t->rchild){??
  • ????????????enter(&q,t->rchild);??
  • ????????}??
  • ????}??
  • }??

  • ?

    5、利用前序遍歷的結果生成二叉樹

    [cpp]?view plaincopyprint?
  • //遞歸調用,不存點,想的時候只關注于一個點,因為還會回來的,不要跟蹤程序運行,否則容易多加循環??
  • ??
  • void?createtree(bintree?*t){????????
  • ????datatype?c;??
  • ????if((c=getchar())?==?'#')??
  • ????????*t?=?NULL;??
  • ????else{??
  • ????????*t?=?(bintree)malloc(sizeof(BinNode));??
  • ????????(*t)->data?=?c;??
  • ????????createtree(&(*t)->lchild);??
  • ????????createtree(&(*t)->rchild);??
  • ????}??
  • }??

  • 6、二叉樹的查找

    [cpp]?view plaincopyprint?
  • bintree?search_tree(bintree?t,datatype?x){??
  • ????if(!t){??
  • ????????return?NULL;??
  • ????}??
  • ????if(t->data?==?x){??
  • ????????return?t;??
  • ????}else{??
  • ????????if(!search_tree(t->lchild,x)){??
  • ????????????return?search_tree(t->rchild,x);??
  • ????????}??
  • ????????return?t;??
  • ????}??
  • }??

  • 7、統計結點個數

    [cpp]?view plaincopyprint?
  • int?count_tree(bintree?t){??
  • ????if(t){??
  • ????????return?(count_tree(t->lchild)+count_tree(t->rchild)+1);??
  • ????}??
  • ????return?0;??
  • }??

  • 8、比較兩個樹是否相同

    [cpp]?view plaincopyprint?
  • int?is_equal(bintree?t1,bintree?t2){??
  • ????if(!t1?&&?!t2){??????//都為空就相等??
  • ????????return?1;??
  • ????}??
  • ????if(t1?&&?t2?&&?t1->data?==?t2->data){??????//有一個為空或數據不同就不判斷了??
  • ????????if(is_equal(t1->lchild,t2->lchild))??
  • ????????????if(is_equal(t1->rchild,t2->rchild)){??
  • ????????????????return?1;??
  • ????????????}??
  • ????}??
  • ????return?0;??
  • }??

  • 9、求二叉樹的深度

    [cpp]?view plaincopyprint?
  • int?hight_tree(bintree?t){??
  • ????int?h,left,right;??
  • ????if(!t){??
  • ????????return?0;??
  • ????}??
  • ????left?=?hight_tree(t->lchild);??
  • ????right?=?hight_tree(t->rchild);??
  • ????h?=?(left>right?left:right)+1;??
  • ????return?h;??
  • }??

  • ?

    總結

    以上是生活随笔為你收集整理的二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 中文字幕免费在线播放 | 欧美日韩中出 | av资源网在线观看 | 国产一区二区亚洲 | 免费一级片网站 | 国产av一区二区不卡 | 国产一级特黄a高潮片 | 成人黄色视屏 | 欧洲一级黄色片 | 91久久国产视频 | 免费在线网站 | 波多野42部无码喷潮 | 在线播放一区二区三区 | 天天干夜夜操 | 久久国产中文字幕 | 钰慧的mv视频在线观看 | 免费日韩成人 | 美女黄页网站 | 永久免费黄色片 | 成年人www | 一区二区天堂 | 亚洲男女| 综合色播| 欧洲色av| 日本视频www | 亚欧精品在线 | 99毛片| 一级一片免费播放 | www久久99 | 欧美国产日韩视频 | 视频一区二区三区在线观看 | 男人都懂的网站 | 亚洲熟妇无码一区二区三区 | 极品人妻一区二区 | 日韩亚州 | 91视频高清| 97视频免费看 | 国产免费激情视频 | 精品久久一区二区 | 欧美专区在线 | 久久人人超碰 | 蜜臀精品| 最好看的中文字幕国语电影mv | 黄色女女 | 亚洲一区二区久久久 | 日韩色婷婷| 亚洲国产成人精品一区二区三区 | 免费在线观看成人 | 欧美aa视频 | 精品国产乱码久久久久久婷婷 | 男女猛烈无遮挡免费视频 | 婷婷中文字幕在线 | 中文字幕2区| 中文字幕第315页 | 国产一区二区三区在线观看免费 | 在线观看国产一级片 | 国产资源站 | 91精品小视频 | 国产精品丝袜一区二区 | 中文字幕资源网 | 欧美影院一区 | 北条麻妃久久精品 | 无码h肉动漫在线观看 | 亚洲自拍中文 | 日韩激情一区二区三区 | 日韩伦理在线视频 | 日本一区二区视频在线播放 | 亚洲二区在线观看 | 亚洲午夜免费 | 五月色婷婷综合 | 麻豆av在线播放 | www.色日本| 欧美一级性生活视频 | 国产露脸91国语对白 | 亚洲国产精品无码久久久久高潮 | 免费麻豆 | 善良的女朋友在线观看 | 日韩精品伦理 | 男女日批视频 | 粗大黑人巨茎大战欧美成人免费看 | 可以免费看的av | 视频一区二区三区精品 | 九九热精品视频在线 | 欧美性猛交xx | 色片在线播放 | 日韩欧美高清在线 | 亚洲AV无码成人精品区东京热 | 97人妻精品一区二区三区视频 | 亚洲国产精品久久久久婷婷老年 | 粗了大了 整进去好爽视频 日本女优中文字幕 | 成人乱码一区二区三区 | 亚洲国产成人精品女人久久久 | 天堂色网 | 亚洲一区二区三区在线视频观看 | 亚洲一区二区在线播放 | 97国产在线播放 | 亚洲精品一区二区三区不卡 | 久久9966 | 爱看av|