資料結構 二叉樹鏈結結構基本操作

2021-09-23 15:37:50 字數 3960 閱讀 1905

二叉樹順序儲存的優缺點:

順序儲存結構就是使用陣列來儲存,順序結構操作比較簡單,對於堆結構來說,適合使用順序儲存方式來解決。但陣列只適合表示完全二叉樹,對於一般的二叉樹如果採用順序儲存方式會造成大量的空間浪費,這是我們不希望看到的。

由此引出來二叉樹的鏈式儲存。並實現二叉樹的以下操作:

建立二叉樹、拷貝二叉樹、銷毀二叉樹、二叉樹遍歷(前序、中序、後續、層序)、獲取二叉樹中節點個數、獲取二叉樹中第k層節點個數、獲取二叉樹中葉子節點個數、二叉樹高度(深度)、檢測給定值的元素是否在二叉樹中、二叉樹的映象以及判斷二叉樹是否為完全二叉樹。

二叉樹定義:使用孩子表示法

typedef char btdatatype;

typedef struct btnode

btnode;

標頭檔案中函式宣告:

//二叉樹的建立

btnode* creatbintree(btdatatype* array, int size, btdatatype invalid);

//二叉樹的拷貝

btnode* copybintree(btnode* proot);

//二叉樹的銷毀

void destorybintree(btnode** proot);

//遞迴:前序遍歷

void preorder(btnode* proot);

//遞迴:中序遍歷

void inorder(btnode* proot);

//遞迴:後序遍歷

void postorder(btnode* proot);

//層序遍歷

void levelorder(btnode* proot);

//獲取二叉樹中節點個數

int getbintreesize(btnode* proot);

//獲取二叉樹中第k層節點個數

int getklevelnodecount(btnode* proot, int k);

//獲取二叉樹中葉子節點個數

int getleafcount(btnode* proot);

//獲取二叉樹高度(深度)

int getbintreeheight(btnode* proot);

//檢測值為x的元素是否在二叉樹中,在則返回該節點的位址,否則返回null

btnode* binarytreefind(btnode* proot, btdatatype x);

//二叉樹的映象

void mirrornor(btnode* proot);

void mirror(btnode* proot);

//判斷二叉樹是否是完全二叉樹

int binarytreecomplete(btnode* proot);

1、二叉樹的建立

首先建立二叉樹的根節點,然後遞迴建立根節點的左子樹及右子樹。此處還要用到新建節點的函式buybintreenode。

建立二叉樹函式所需的引數包括存放資料的陣列array、有效元素個數size、存放位置索引index以及無效符號invalid。在這裡為了方便使用者使用,多加了一層封裝,使得使用者呼叫層面只需要傳入三個引數即可。

btnode* buybintreenode(btdatatype data) 

pnewnode->_data = data;

pnewnode->_pleft = null;

pnewnode->_pright = null;

return pnewnode;

}btnode* _creatbintree(btdatatype* array, int size, int* index,btdatatype invalid)

return proot;

}btnode* creatbintree(btdatatype* array, int size, btdatatype invalid)

2、二叉樹的拷貝

也是採用遞迴的方法實現拷貝。

btnode* copybintree(btnode* proot)
3、二叉樹的銷毀

為了防止記憶體洩漏問題發生,在整個程式結束前應當將二叉樹銷毀掉,也是採用的遞迴的方法進行銷毀的,不過需要注意的是因為在銷毀完二叉樹後我們需要將根結點置空,要改變其中指標的指向,所以需要傳入乙個二級指標。

void destorybintree(btnode** proot) 

}

4、二叉樹的遍歷(前序、中序、後序)

void preorder(btnode* proot) 

}void inorder(btnode* proot)

}void postorder(btnode* proot)

}

5、二叉樹的層序遍歷

借助佇列,實現二叉樹的層序遍歷(因為c語言中沒有現成的佇列的方法,所以需要新增乙個佇列),具體步驟:

while迴圈(佇列非空)

取隊頭元素。

遍歷該元素。

如果左孩子存在,將左孩子入佇列。

如果右孩子存在,將右孩子入佇列。

刪除隊頭元素。

void levelorder(btnode* proot) 

queuedestory(&q);

printf("\n");

}

6、獲取二叉樹中節點個數、第k層節點個數、葉子節點個數

根據二叉樹的概念以及所要求節點的特點,採用遞迴的方法實現。

int getbintreesize(btnode* proot) 

int getklevelnodecount(btnode* proot, int k)

int getleafcount(btnode* proot)

7、獲取二叉樹的高度(深度)

遞迴的方法:根結點的左子樹的高度與根結點的右子樹的高度中較大者+1。

int getbintreeheight(btnode* proot)
8、查詢值為x的節點在二叉樹中是否存在

btnode* binarytreefind(btnode* proot, btdatatype x)
9、二叉樹映象(遞迴與非遞迴的方式)

非遞迴的方式與層序遍歷的實現很相似,都需要借助佇列,不同的是需要增加乙個交換左右子樹的步驟。

void swap(btnode** pleft, btnode** pright) 

void mirror(btnode* proot)

}void mirrornor(btnode* proot)

}

10、判斷二叉樹是否為完全二叉樹

需要借助佇列來完成,分析如下:

首先空樹也是乙個完全二叉樹。

利用佇列先將二叉樹根結點入佇列,只要當前不為空,就出佇列該節點,併入佇列該節點的左右孩子,若有孩子不存在,則入佇列null。

若當前節點為空,則判斷佇列是否為空,若隊列為空,則是完全二叉樹。若佇列不為空,則繼續出隊,若當前出隊的節點是null,則該樹不是完全二叉樹。

int binarytreecomplete(btnode* proot) 

} while (!queueempty(&q))

return 1;

}

資料結構 二叉樹的基本操作(二)

1.理解二叉樹的基本概念和特點 2.掌握二叉樹的鏈式儲存結構 3.掌握二叉樹的基本操作 4.掌握二叉樹遍歷操作 1.實現二叉樹的如下操作,先序遍歷 中序遍歷和後序遍歷的遞迴演算法,二叉樹如下圖所示。採用二叉鏈儲存結構實現 1 採用括號表示法,構建如下二叉樹,並輸出二叉樹b 2 採用遞迴演算法,輸出二...

資料結構 二叉樹基本操作 二叉樹面試題

二叉樹的基本概念就不多說了 如下 binarytree.c pragma once include include include include typedef char btdatatype typedef struct binarytreenode btnode a是乙個前序遍歷的陣列 二叉樹...

資料結構 二叉樹的基本操作(一)

1.理解二叉樹的基本概念和特點 2.掌握二叉樹的鏈式儲存結構 3.掌握二叉樹的基本操作 1.實現二叉樹的如下操作,二叉樹如下圖所示。採用二叉鏈儲存結構實現 1 輸出二叉樹b 2 輸出c節點的左 右孩子節點值 3 輸出二叉樹的深度 4 輸出二叉樹b的節點個數 5 輸出二叉樹b的葉子節點個數。根據題目為...