我的第一棵樹 家譜

2021-06-18 22:17:17 字數 4501 閱讀 9097

家譜構建第一步,就是要理解記憶體。樹實際上就是乙個多叉鍊錶,乙個資料域,幾個指向跟自己有關係的元素的指標域,就

構成了樹的結點。而要建立鍊錶,把乙個乙個結點賦值,就要傳指向它們的指標bitree了,這樣才能修改結點的值。因為通過

子函式來建立一棵樹,每開闢乙個新節點,就malloc動態申請一塊記憶體區域,這塊區域在堆區,子函式結束時不會銷毀。

但在主函式裡定義一棵樹,一定要把樹的位址傳到子函式裡,這樣才能修改即給樹新增結點建立一棵樹,在子函式裡給樹的

根節點(*t)動態申請一塊記憶體,把輸入的值賦過去,就構造好了根節點。而之後的結點,就通過不斷地malloc構造新節點,

然後利用結點的各種指標域,賦值,把它們連線起來。連線的過程用到的是在子函式裡定義的臨時bitree指標變數,只是通過

它們實現鏈結。而我們剛開始已經抓住了「繩子的頭」(*t),就可以把樹直接拿來操作啦。

理解了子函式的引數型別,就剩下思路了。剛開始我沒有父親節點,幾個子函式勉強寫出了,可是到刪除某人的時候實在做不

下去了,後來加上父親節點發現再縷思路的時候真是得心應手。歷時三天半,我的第一棵樹終於告一段落啦。

這裡關鍵是建樹和遍歷,完成這兩部分,基本就算寫完了。建樹,家譜要用層序建樹,這裡用到佇列,利用它先進先出的排隊

性質,從根節點開始,每一層從左到右遍歷著賦值,先根節點入佇列,用乙個bitree型別的變數接收根節點出佇列,迴圈從此

展開,手動判斷有無孩子,若有,連到lchild域,判斷有沒有孩子也是乙個迴圈,設定乙個標誌,若一直有,則迴圈把新孩子

尾插到rsib兄弟結點,同時當把新結點連到舊結點的時候,新節點入佇列,直到輸入不再有孩子。這時候第乙個入佇列的節點

即左孩子出佇列,重複以上先判斷有無左孩子,把孩子們鏈結到上乙個對應結點併入佇列的過程,佇列實現了每一層從左到右

的順序插入,遍歷,實現了層序。

然後,插入刪除增加查詢,查詢時可以公升級到查出乙個人連帶他的祖宗們兄弟們兒子們,還有問有沒有孩子的時候,記得把當前

結點的名字列印出來,更只能人性化一點。

查詢,在遍歷的基礎上,找到這個人,若是祖先,只列印兒子們;若不是,利用父親指標找到父親,迴圈找到祖宗,再找兄弟,

兩種情況,若是父親的左孩子,依次列印右兄弟,若不是左孩子,則從左孩子開始依次列印父親的孩子,通過判斷跳過本身。

再找兒子,依次遍歷列印。

增加兒子,在遍歷的基礎上,找到要增加兒子的父親節點,若沒有左孩子,。。。若有左孩子,尾插。

增加兄弟,在遍歷的基礎上,找到要增加兄弟的節點,新節點尾插到最後那個兄弟的右兄弟域。

刪除兒子,在遍歷的基礎上,找到要刪除的兒子指標,若本身是父親左孩子,,,,若不是,,,,。

刪除兄弟,在遍歷的基礎上,找到要刪除的兄弟結點,若是父親左孩子,,,,若不是,,,,。

刪除某個人,在遍歷的基礎上,找到要刪除的結點,若是祖宗,,,若是父親左孩子,,,若不是,,,。

注意刪除某個人要把他的子子孫孫都刪掉。

刪除新增操作都要改變一棵樹,所以需要傳樹的位址,二級指標。把樹的根節點位址傳進去,中間的臨時變數不用設為指標型別。

free()括號裡是指標變數,銷毀指向部分的記憶體。

釋放一棵子樹的時候,要提前把它的右兄弟置為null,否則無法通過後序遍歷釋放節點空間。

主函式:

#include#include"bitree.h"

int main(void)

printf("what you want to do!\n");

c=getchar();

getchar();

} return 0;

}分檔案:

bitree.h

#ifndef bitree_h

#define bitree_h

typedef char elemtype;

typedef struct bitreenode

bitnode,*bitree;

void createbitree(bitree *t);

void levelordertree(bitree t);

void preordertree(bitree t);

int inquire(bitree t,char ch);

void postorderfree(bitree *t);

void delete_son(bitree *t,char ch_d,char ch_s);

void add_sib(bitree *t,char ch,char ch_s);

void add_son(bitree *t,char ch_d,char ch_s);

void delete_sib(bitree *t,char ch,char ch_s);

void delete_someone(bitree *t,char ch);

#endif

bitree.cpp

#include#include#include"bitree.h"

#include"queue.h"

void createbitree(bitree *t)

else

printf("%c還有孩子嗎?1 or 0 \n",x->ch);

scanf("%d",&j);

getchar();

} }}void preordertree(bitree t)

void levelordertree(bitree t)

while(!is_empty(&q))

}} printf("\n");

}

int inquire(bitree t,char ch)

while(!is_empty(&q))

}else

printf("\n");

q=(x->dad)->lchild;

printf("his sibs are: ");

if(q->ch==ch)

}else

}printf("\n");

}if(x->lchild)

}printf("\n");

} if(x->lchild)

}} return 0;

}void postorderfree(bitree *t)

void delete_son(bitree *t,char ch_d,char ch_s)

while(!is_empty(&q))

else

q=q->rsib;}}

} if(x->lchild)

}} printf("\n");

}void add_sib(bitree *t,char ch,char ch_s)

while(!is_empty(&q))

if(x->lchild)

} }}

void add_son(bitree *t,char ch_d,char ch_s)

while(!is_empty(&q))

else

if(x->lchild)

}} }

}void delete_sib(bitree *t,char ch,char ch_s)

while(!is_empty(&q))

else

p=p->rsib;}}

}if(x->lchild)

}} printf("wrong name!\n");

} /*

void delete_someone(bitree t,char ch)

preordertree(t->lchild);

preordertree(t->rsib);}*/

void delete_someone(bitree *t,char ch)

if(*t)

while(!is_empty(&q))

else

p=p->rsib;}}

} if(x->lchild)

} }}

queue.h

#ifndef queue_h

#define queue_h

#define maxqsize 100

#include"bitree.h"

typedef struct queue

queue,*pqueue;

void initqueue(pqueue p);

int is_empty(pqueue p);

int is_full(pqueue p);

void enqueue(pqueue p,bitree x);

bitree dequeue(pqueue p);

#endif

queue.cpp

#include#include"queue.h"

void initqueue(pqueue p)

int is_empty(pqueue p)

int is_full(pqueue p)

void enqueue(pqueue p,bitree x)

bitree dequeue(pqueue p)

我是一棵「樹」

我是一顆樹,之前我們資料結構家族中的乙個小朋友 棧 已經給你們介紹過的我們這個家族了 我是乙個 棧 之所以叫棧為小朋友,是因為我和他的爸爸 陣列是平輩的。之所以存在我們這樣乙個家庭,最主要的原因是陣列他們家庭雖然很強大,但是有一定的侷限性。大家都知道,無論是陣列 鍊錶以及他們家的那幾個小娃娃 棧 佇...

一棵樹是否為另一棵樹的子結構

輸入兩顆二叉樹a,b,判斷b是不是a的子結構。問題描述 給定兩個二叉樹的根節點,判斷第二樹是否是第乙個樹的子樹,如果是返回1,否則返回0.拿第二個樹的每個節點去和第乙個樹做匹配,如果某個節點匹配成功,就接著往下匹配,否則重新從第二個樹的的根節點開始。注意區別 測試用例 樹1 42 6 1 3 5 7...

如何判斷一棵樹是不是另一棵樹的子樹

package suanfatest class treenode treenode int value treenode int value,treenode leftchild,treenode rightchild public int getvalue public void setvalu...