日韩性视频-久久久蜜桃-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网站 | wwwxx欧美| av黄网站 | 成人污在线观看 | 成人免费播放 | 性做久久 | 日韩精品四区 | 中文字幕第二页 | 天天干,天天干 | 献给魔王伊伏洛基亚吧动漫在线观看 | 中文精品在线 | 成人在线影片 | 视频一区二区欧美 | 中文字幕一区二区在线观看 | 久久久久久久成人 | 欧美日韩一区二区三区免费 | 伊人22综合| 中文字幕在线观看三区 | 涩涩视频网站 | 黄色网址中文字幕 | 黄瓜视频污在线观看 | 青青国产在线观看 | 久久欧美精品 | 中文字幕伊人 | 伊人网国产 | 免费看黄20分钟 | 奇米影| 黄色片在线观看免费 | 久青草视频在线观看 | 无码人妻丰满熟妇区五十路百度 | 淫欲av | 久久视频在线免费观看 | 精品一级少妇久久久久久久 | 国产一线二线在线观看 | 日韩精品黄 | 亚洲综合日韩在线 | 91影音 | 天天想你在线观看完整版高清 | 婷婷综合网 | 91亚洲国产成人精品一区二区三 | julia一区二区中文久久97 | 国产精品污污 | 中文字幕第315页 | 精品国产丝袜一区二区三区乱码 | 超碰老司机 | 大肉大捧一进一出好爽动态图 | 日韩精品视频三区 | 久久久国产精品视频 | 欧美另类专区 | 精品人妻一区二区三区蜜桃视频 | 韩国一区二区在线播放 | 久久视 | 人人艹视频| 国产一级淫片a视频免费观看 | 男人操女人下面视频 | 国模av在线| 国产高潮视频在线观看 | 亚洲欧洲成人精品久久一码二码 | 91av网址 | 视频一区三区 | 一卡二卡三卡在线观看 | 白丝久久 | 成年精品| 男人把女人捅爽 | 一区二区国产精品 | 熟女国产精品一区二区三 | 久久久久91 | 一区二区精品在线观看 | 欧美成人性生活 | 人人妻人人澡人人爽人人精品 | 快射视频在线观看 | www 在线观看视频 | 韩国三级一区 | 女同一区二区三区 | www.香蕉视频在线观看 | 尤物毛片 | av免费高清 | 亚洲黄色一级 | 日本高清免费观看 | www.欧美色 | 日本网站在线看 | 五十路中文字幕 | 精品日韩久久 | jzzijzzij亚洲成熟少妇18 欧美www在线观看 | av毛片在线 | 亚洲欧美日韩久久 | 中文字幕在线视频一区二区 | 国产伦理吴梦梦伦理 | 亚洲精品在线播放视频 | 国产在线97 | 琪琪久久 | 中文字幕视频免费 |