1. 程式人生 > >數據結構——樹筆記1

數據結構——樹筆記1

其余 劃分 right class log 並且 否則 -1 尋找

樹屬於非線性數據結構,它是一種層次結構:如果存在前驅節點,則是唯一
的,如果存在後繼節點,則可以是多個。即樹的元素之間是一對多的關系。
樹是由n個節點構成的有限集合T,如果n = 0,則是空樹,如果n不等於0,則
一個非空樹,有且只有一個根結點root,如果n>1,則除了根結點外,其余節
點又可以劃分為有限集T1,T2......Tm 其中每個有限集有是一棵樹。稱為子
樹subtree.
樹的存儲結構
雙親表示法
孩子表示法
孩子兄弟表示法(二叉樹表示法)

森林:M棵互不相交的樹的集合。

二叉樹:
二叉樹的特點是每個節點至多只有兩顆子樹,並且二叉樹的子樹有左右之
分,它的次序不能任意顛倒。

二叉樹的特點:
在二叉樹的第i層上至多有2的i-1次方個節點
深度為k的二叉樹至多有2的k次方-1個節點
如果一顆二叉樹的終端節點的數目為i,深度為2的節點數目為j,則i=j+1

滿二叉樹:深度為k且節點數目為2的k次方-1的二叉樹
完全二叉樹:只有在最下面一層的右邊缺少若幹個節點的滿二叉樹

二叉樹的存儲結構:
按順序儲存,即使用一組連續的儲存單元,自上而下,自左而右的儲存,每
個空節點也會占用一個儲存單元。這樣的儲存方式只適合完全二叉樹,因為
會浪費大量空間。

鏈式儲存結構:二叉樹的節點至少包括三個域,數據域和指向左右子樹的指
針域,有時候也增加一個指向雙親的指針域來方便指向節點的雙親。

二叉樹的遍歷:以一定的規則將非線性的節點排列成線性序列
先序遍歷二叉樹:
先訪問根結點,再先序遍歷左子樹,最後先序遍歷右子樹
中序遍歷二叉樹
先中序遍歷左子樹,在訪問根結點,最後中序遍歷右子樹
後序遍歷二叉樹
先後序遍歷左子樹,在後序遍歷右子樹,最後訪問根結點

在已知兩種遍歷的情況下可以得出原二叉樹的形狀,這兩種遍歷可以是先序
和後序,也可以是中序和後序

// 二叉樹的初始化
void Init_BitTree(BiTree * T)
{
    *T = NULL;
    
    return;
}

// 銷毀二叉樹
void Destroy_BitTree(BiTree * T)
{
    if ((*T)->lchild)
        Destroy_BitTree(&((*T)->lchild));
    if ((*T)->rchild)
        Destroy_BitTree(&((*T)->rchild));
    free(*T);
    *T = NULL;
    
    
return; } // 二叉樹的插入,通過判斷LR的值,判斷插入選擇 int Insert_Child(BiTree p, int LR, BiTree c) { if (p) // p指向的二叉樹非空 { if (0 == LR) { c->rchild = p->lchild; // p原來的左子樹稱為c的右子樹 p->lchild = c; // 子樹c作為p的左子樹 } else { c->rchild = p->rchild; p
->rchild = c; return 1; } } return 0; } // 返回二叉樹e的左孩子節點的元素值 int Left_Child(BiTree T, int e) { BiTree p; if (T) // 當二叉樹T不為空時 { p = Point(T, e); // p是元素值e的節點的指針 if (p && p->lchild) // 如果p的節點不為空,且p的左孩子節點存在 return p->lchild->data; // 返回左孩子節點的元素值 } return 0; } // 返回二叉樹e的右孩子節點的元素值 int Right_Child(BiTree T, int e) { BiTree p; if (T) // 當二叉樹T不為空時 { p = Point(T, e); // p是元素值e的節點的指針 if (p && p->rchild) // 如果p的節點不為空,且p的左右孩子節點存在 return p->rchild->data; // 返回右孩子節點的元素值 } return 0; } // 在二叉樹中尋找元素值為e的節點,此處假定該二叉樹的節點元素值各不相同,如果找到返回該節點的地址,否則返回NULL BiTree Point(BiTree T, int e) { if (e == T->data) { return T; } else { if (T->lchild != NULL) Point(T->lchild, e); if (T->rchild != NULL) Point(T->rchild, e); } return NULL; } // 刪除子樹操作,根據LR的值選擇刪除的是左子樹還是右子樹 int Delete_Child(BiTree p, int LR) { if (p) // 判斷p不空 { if (0 == LR) Destroy_BitTree(&(p->lchild)); else Destroy_BitTree(&(p->rchild)); return 1; } return 0; }

數據結構——樹筆記1