資料結構中的樹
之前我們講的都是一對一的線性結構,在實際應用上,還有許多一對多的情況需要我們去處理,所以這一篇我要講一種一對多的資料結構——樹。
樹
對於A來說,它和B、C、D都有關係,對於B來說它和E、F都有關係,這就是“一對多”的關係
樹的概念
結點:樹中的每一個元素都是一個結點,如A、B、C。
父結點:對於B、C、D來說,A是它們的父結點。
子結點:對於A來說,B、C、D都是它的子結點。
根結點:如果一個結點沒有父結點,那麼個結點就是根結點。
兄弟結點:對於B、C、D來說它們是兄弟結點,對於E、F來說它們也是兄弟結點。
葉子結點:如果結點沒有任何子結點,那麼此結點為葉子結點。例如(K、L、F、G、M、I、J)
樹的層次:從根開始定義,根為第一層,根的孩子(BCD)為第二層,(BCD)的孩子為第三層,以此類推。
結點的度:對於A來將,它的度是3(BCD),對於B來講它的度是2(EF)。
滿二叉樹和完全二叉樹
如果二叉樹中除了葉子結點,每個結點的度都為2,那麼此二叉樹為滿二叉樹如果二叉樹中有一層結點的子樹中不是從左到右分佈那麼它就是完全二叉樹
圖1和2都是二叉樹,但是圖2是完全二叉樹,圖一是滿二叉樹(二叉樹中各個結點的度最多是2,可以是0,1,2)
二叉樹的結點構成
Lchild 代表指向左孩子的指標域;data 為資料域;Rchild 代表指向右孩子的指標域。使用此種結點構建的二叉樹稱為“二叉連結串列”。程式碼實現
#include <stdio.h>
#define TElemType int
//利用佇列遍歷二叉樹
//初始化隊頭和隊尾指標開始時都為0
int front=0,rear=0;
typedef struct BiTNode{
TElemType data;//資料域
struct BiTNode *lchild,*rchild;//定義左樹指標域和右樹指標域
}BiTNode,*BiTree;
複製程式碼
建立樹
//前面學過指標的應該有基礎了,這裡我就不過多講解了
void CreateBiTree(BiTree *T){
*T=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->data=1;
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data=2;
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild->data=5;
(*T)->lchild->rchild->lchild=NULL;
(*T)->lchild->rchild->rchild=NULL;
(*T)->rchild->data=3;
(*T)->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->lchild->data=6;
(*T)->rchild->lchild->lchild=NULL;
(*T)->rchild->lchild->rchild=NULL;
(*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->rchild->data=7;
(*T)->rchild->rchild->lchild=NULL;
(*T)->rchild->rchild->rchild=NULL;
(*T)->lchild->lchild->data=4;
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
}
複製程式碼
使用佇列來遍歷樹
void EnQueue(BiTree *a,BiTree node){
a[rear++]=node;
}
//出隊函式
BiTNode* DeQueue(BiTNode** a){//這裡需要用二級指標(BiTNode)
return a[front++];
}
//輸出函式
void displayNode(BiTree node){
printf("%d ",node->data);
}
int main() {
BiTree tree;
//建立二叉樹
CreateBiTree(&tree);
BiTNode * p;
//採用順序佇列,初始化建立佇列陣列
BiTree a[20];
//根結點入隊
EnQueue(a, tree);
//當隊頭和隊尾相等時,表示佇列為空
while(front<rear) {
//隊頭結點出隊
p=DeQueue(a);//front++
displayNode(p);//列印
//將隊頭結點的左右孩子依次入隊
if (p->lchild!=NULL) {
EnQueue(a, p->lchild);//rear++
}
if (p->rchild!=NULL) {
EnQueue(a, p->rchild);//rear++
}
}
return 0;
}
複製程式碼
執行結果
1 2 3 4 5 6 7