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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux C 数据结构——二叉树

發(fā)布時(shí)間:2023/12/9 linux 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux C 数据结构——二叉树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

先放這張圖:

可以看出,樹(shù)是非線(xiàn)性結(jié)構(gòu);

一、樹(shù)的概念

????? 樹(shù)(tree)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合T,它滿(mǎn)足兩個(gè)條件:

1)有且僅有一個(gè)特定的稱(chēng)為根(root)的節(jié)點(diǎn);

2)其余的節(jié)點(diǎn)可以分為m(m>=0)個(gè)互不相交的有限結(jié)合T1、T2、...、Tm,其中每一個(gè)集合又是一棵樹(shù),并成為其根的子數(shù)(Subtree)。

???? 樹(shù)的邏輯結(jié)構(gòu):樹(shù)中任何節(jié)點(diǎn)都可以有零個(gè)或多個(gè)直接后繼節(jié)點(diǎn)(子節(jié)點(diǎn)),但至多只有一個(gè)直接前驅(qū)節(jié)點(diǎn)(父節(jié)點(diǎn)),根節(jié)點(diǎn)沒(méi)有前驅(qū)節(jié)點(diǎn),葉節(jié)點(diǎn)沒(méi)有后繼節(jié)點(diǎn)。

?度數(shù):一個(gè)節(jié)點(diǎn)的子樹(shù)的個(gè)數(shù)稱(chēng)為該節(jié)點(diǎn)的度數(shù),一棵樹(shù)的度數(shù)是指該樹(shù)中節(jié)點(diǎn)的最大度數(shù);

?層數(shù):節(jié)點(diǎn)的層數(shù)等于父節(jié)點(diǎn)的層數(shù)加一,根節(jié)點(diǎn)的層數(shù)定義為一;

?深度:樹(shù)中節(jié)點(diǎn)層數(shù)的最大值稱(chēng)為該樹(shù)的高度或深度;

?

二、二叉樹(shù)

???????二叉樹(shù)(Binary)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合,它或者是空集(n=0),或者是由一個(gè)根節(jié)點(diǎn)以及兩棵互不相交的、分別稱(chēng)為左子樹(shù)和右子樹(shù)的二叉樹(shù);二叉樹(shù)是有序樹(shù)

二叉樹(shù)的性質(zhì):

?

滿(mǎn)二叉樹(shù):深度為k(k>=1)時(shí)2ek-1個(gè)節(jié)點(diǎn)的二叉樹(shù);

完全二叉樹(shù):1)只有最下面兩層有度數(shù)小于2的節(jié)點(diǎn);2)最下面一層的葉節(jié)點(diǎn)集中在最左邊的若干位置上;

滿(mǎn)二叉樹(shù)是完全二叉樹(shù)的一個(gè)特例。

1、二叉樹(shù)的順序存儲(chǔ)結(jié)構(gòu)

?完全二叉樹(shù)節(jié)點(diǎn)的編號(hào)方法是從上到下,從左到右,根節(jié)點(diǎn)為1號(hào)節(jié)點(diǎn)。設(shè)完全二叉樹(shù)的節(jié)點(diǎn)數(shù)為n,某節(jié)點(diǎn)編號(hào)為i :

1)當(dāng)i > 1(不是根節(jié)點(diǎn))時(shí),有父節(jié)點(diǎn),其父節(jié)點(diǎn)編號(hào)為i / 2;

2)當(dāng)2 * i <= n 時(shí),有左子樹(shù),其編號(hào)為2 * i,否則沒(méi)有左子樹(shù),本身是葉節(jié)點(diǎn);

3)當(dāng)2 * i? + 1 < = n時(shí),有右子樹(shù),其編號(hào)為2 * i + 1,否則沒(méi)有右子樹(shù);

如何存儲(chǔ):

有n個(gè)節(jié)點(diǎn)的完全二叉樹(shù)可以用有?n + 1 個(gè)元素的數(shù)組進(jìn)行存儲(chǔ),節(jié)點(diǎn)號(hào)和數(shù)組下標(biāo)一一對(duì)應(yīng),下標(biāo)為零的元素不用。

利用以上特性,可以用下標(biāo)獲得節(jié)點(diǎn)的邏輯關(guān)系。不完全二叉樹(shù)通過(guò)添加虛節(jié)點(diǎn)構(gòu)成完全二叉樹(shù),然后用數(shù)組存儲(chǔ),這要浪費(fèi)一些存儲(chǔ)空間。

?通過(guò)添加非字母字符,構(gòu)成完全二叉樹(shù)。

2、二叉樹(shù)的鏈?zhǔn)酱鎯?chǔ)

1)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu):

[cpp]?view plaincopy
  • typedef?int?data_t;??
  • typedef?struct?node_t?//定義二叉樹(shù)節(jié)點(diǎn)的內(nèi)部結(jié)構(gòu)??
  • {??
  • ????data_t?data;??
  • ????struct?node_t?*lchild,*rchild;?//指向左孩子和右孩子的指針;??
  • }bitree_t;??
  • bitree_t?*root;?//定義指向二叉樹(shù)的指針??
  • 2)鏈?zhǔn)蕉鏄?shù)的創(chuàng)建

    鏈?zhǔn)蕉鏄?shù)的創(chuàng)建要借助順序存儲(chǔ),比如下面這個(gè)二叉樹(shù)

    ?

    我們需要通過(guò)添加虛節(jié)點(diǎn)使其成為一個(gè)完全二叉樹(shù),并用大小為n+1的數(shù)組來(lái)表示,如下

    data_t a[] = {0,'a','b','c','d','e',0,'f',0,0,'g','h',0,0,'i'}; 因?yàn)楣?jié)點(diǎn)號(hào)與數(shù)組下表是一一對(duì)應(yīng)的,所以我們可以通過(guò)這個(gè)數(shù)組創(chuàng)建一個(gè)鏈?zhǔn)蕉鏄?shù)

    ?利用遞歸創(chuàng)建一個(gè)二叉樹(shù):

    [cpp]?view plaincopy
  • data_t?a[]?=?{0,'a','b','c','d','e',0,'f',0,0,'g','h',0,0,'i'};??
  • ??
  • bitree_t?*CreateBitree(int?i,?data_t?a[],?int?n)??
  • {??
  • ????bitree_t?*root;??
  • ????int?j;??
  • ??
  • ????root?=?(bitree_t?*)malloc(sizeof(bitree_t));??
  • ????root->data?=?a[i];??
  • ??
  • ????j?=?2?*?i;??
  • ????if(j?<=?n?&&?a[j]?!=?'0')??
  • ????{??
  • ????????root->lchild?=?CreateBitree(j,?a,?n);?//創(chuàng)建??
  • ????}??
  • ????else??
  • ????{??
  • ????????root->lchild?=?NULL;??
  • ????}??
  • ??
  • ????j?=?2?*?i?+?1;??
  • ????if(j?<=?n?&&?a[j]?!=?'0')??
  • ????{??
  • ????????root->rchild?=?CreateBitree(j,?a,?n);??
  • ????}??
  • ????else??
  • ????{??
  • ????????root->rchild?=?NULL;??
  • ????}?????
  • ??
  • ????return?root;??
  • }??
  • 它的遍歷順序:

    遞歸不論是在我們創(chuàng)建二叉樹(shù)還是遍歷二叉樹(shù)都起到了很大的作用,至于遞歸,大家可以通過(guò)函數(shù)棧來(lái)理解,函數(shù)在執(zhí)行到 root->lchild = CreateBitree(j, a, n); 這一步時(shí),會(huì)再次調(diào)用CreateBitree()函數(shù),這樣會(huì)在棧區(qū)開(kāi)辟一塊空間,知道遇到終止條件才會(huì)返回,即這片內(nèi)存區(qū)域會(huì)被釋放,函數(shù)執(zhí)行向上回收,直至該二叉樹(shù)被創(chuàng)建,大家可以畫(huà)圖理解一下,有空我會(huì)補(bǔ)上圖;


    3、二叉樹(shù)的遍歷

    ??? 遍歷:沿某條搜索路徑周游二叉樹(shù),對(duì)樹(shù)中的每一個(gè)節(jié)點(diǎn)訪問(wèn)一次且僅訪問(wèn)一次。

    ???? 由于二叉樹(shù)的遞歸性質(zhì),遍歷算法也是遞歸的。三種基本的遍歷算法如下:

    1)先序遍歷:先訪問(wèn)樹(shù)根,再訪問(wèn)左子樹(shù),最后訪問(wèn)右子樹(shù);

    2)中序遍歷:先訪問(wèn)左子樹(shù),再訪問(wèn)樹(shù)根,最后訪問(wèn)右子樹(shù);

    3)后序遍歷:先訪問(wèn)左子樹(shù),再訪問(wèn)右子樹(shù),最后訪問(wèn)樹(shù)根;

    ?

    先序遍歷算法:

    [cpp]?view plaincopy
  • void?PREORDER(bitree_t?*r)??
  • {??
  • ????if(r?==?NULL)??
  • ????????return;??
  • ????printf("%c?",r->data);??
  • ????PREORDER(r->lchild);??
  • ????PREORDER(r->rchild);??
  • }??
  • 中序遍歷算法:

    [cpp]?view plaincopy
  • void?INORDER(bitree_t?*r)??
  • {??
  • ????if(r?==?NULL)??
  • ????????return;??
  • ????INORDER(r->lchild);??
  • ????printf("%c?",r->data);??
  • ????INORDER(r->rchild);??
  • }??
  • 后序遍歷算法:

    [cpp]?view plaincopy
  • void?POSTORDER(bitree_t?*r)??
  • {??
  • ????if(r?==?NULL)??
  • ????????return;??
  • ????POSTORDER(r->lchild);??
  • ????POSTORDER(r->rchild);??
  • ????printf("%c?",r->data);??
  • }??
  • 我們可以把程序整合一下,寫(xiě)個(gè)測(cè)試程序:

    [cpp]?view plaincopy
  • int?main()??
  • {??
  • ????bitree_t?*tree;??
  • ??
  • ????printf("Begin?creating?the?tree!\n");??
  • ????tree?=?CreateBitree(1,a,sizeof(a)/sizeof(data_t)?-?1);??
  • ????printf("Finish!\n");??
  • ??
  • ????printf("Preorder?traversal:\n");??
  • ????PREORDER(tree);??
  • ??
  • ????printf("\nInorder?traversal:\n");??
  • ????INORDER(tree);??
  • ??
  • ????printf("\nPostorder?traversal:\n");??
  • ????POSTORDER(tree);??
  • ????printf("\n");??
  • ??
  • ????return?0;??
  • }??
  • 執(zhí)行結(jié)果如下:

    [cpp]?view plaincopy
  • fs@ubuntu:~/qiang/tree/bitree$?./bitree??
  • Begin?creating?the?tree!??
  • Finish!??
  • Preorder?traversal:??
  • a?b?d?e?g?h?c?f?i???
  • Inorder?traversal:??
  • d?b?g?e?h?a?c?i?f???
  • Postorder?traversal:??
  • d?g?h?e?b?i?f?c?a???
  • fs@ubuntu:~/qiang/tree/bitree$
  • 總結(jié)

    以上是生活随笔為你收集整理的Linux C 数据结构——二叉树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。