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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉查找树(一)之 C语言的实现

發布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉查找树(一)之 C语言的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉查找樹(一)之 圖文解析 和 C語言的實現

?

概要

? ? ? ?本章先對二叉樹的相關理論知識進行介紹,然后給出C語言的詳細實現。關于二叉樹的學習,需要說明的是:它并不難,不僅不難,而且它非常簡單。初次接觸樹的時候,我也覺得它似乎很難;而之所產生這種感覺主要是由于二叉樹有一大堆陌生的概念、性質等內容。而當我真正的實現了二叉樹再回過頭來看它的相關概念和性質的時候,覺得原來它是如此的簡單!因此,建議在學習二叉樹的時候:先對二叉樹基本的概念、性質有個基本了解,遇到難懂的知識點,可以畫圖來幫助理解;在有個基本的概念之后,再親自動手實現二叉查找樹(這一點至關重要!);最后再回過頭來總結一下二叉樹的理論知識時,你會發現——它的確很簡單!在代碼實踐中,我以"二叉查找樹,而不是單純的二叉樹"為例子進行說明,單純的二叉樹非常簡單,實際使用很少。況且掌握了二叉查找樹,二叉樹也就自然掌握了。

? ? ? 本篇實現的二叉查找樹是C語言版的,后面章節再分別給出C++和Java版本的實現。您可以根據自己熟悉的語言進行實踐學習!

? ? ? 請務必深刻理解、實踐并掌握"二叉查找樹"!它是后面學習AVL樹、伸展樹、紅黑樹等相關樹結構的基石!

?

目錄
1.?樹的介紹
2.?二叉樹的介紹
3.?二叉查找樹的C實現
4.?二叉查找樹的C測試程序

轉載請注明出處:http://www.cnblogs.com/skywang12345/p/3576328.html


更多內容:?數據結構與算法系列 目錄?

(01).?二叉查找樹(一)之 圖文解析 和 C語言的實現
(02).?二叉查找樹(二)之 C++的實現

?

樹的介紹

1. 樹的定義

樹是一種數據結構,它是由n(n>=1)個有限節點組成一個具有層次關系的集合。

把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
(01) 每個節點有零個或多個子節點;
(02) 沒有父節點的節點稱為根節點;
(03) 每一個非根節點有且只有一個父節點;
(04) 除了根節點外,每個子節點可以分為多個不相交的子樹。

?

2. 樹的基本術語

若一個結點有子樹,那么該結點稱為子樹根的"雙親",子樹的根是該結點的"孩子"。有相同雙親的結點互為"兄弟"。一個結點的所有子樹上的任何結點都是該結點的后裔。從根結點到某個結點的路徑上的所有結點都是該結點的祖先。

結點的度:結點擁有的子樹的數目。
葉子:度為零的結點。
分支結點:度不為零的結點。
樹的度:樹中結點的最大的度。

層次:根結點的層次為1,其余結點的層次等于該結點的雙親結點的層次加1。
樹的高度:樹中結點的最大層次。
無序樹:如果樹中結點的各子樹之間的次序是不重要的,可以交換位置。
有序樹:如果樹中結點的各子樹之間的次序是重要的, 不可以交換位置。
森林:0個或多個不相交的樹組成。對森林加上一個根,森林即成為樹;刪去根,樹即成為森林。

?

二叉樹的介紹

1. 二叉樹的定義

二叉樹是每個節點最多有兩個子樹的樹結構。它有五種基本形態:二叉樹可以是空集;根可以有空的左子樹或右子樹;或者左、右子樹皆為空。

?

2. 二叉樹的性質

二叉樹有以下幾個性質:TODO(上標和下標)
性質1:二叉樹第i層上的結點數目最多為?2{i-1}?(i≥1)。
性質2:深度為k的二叉樹至多有2{k}-1個結點(k≥1)。
性質3:包含n個結點的二叉樹的高度至少為log2?(n+1)
性質4:在任意一棵二叉樹中,若終端結點的個數為n0,度為2的結點數為n2,則n0=n2+1

?

2.1 性質1:二叉樹第i層上的結點數目最多為?2{i-1}?(i≥1)

證明:下面用"數學歸納法"進行證明。
? ? ? ? (01) 當i=1時,第i層的節點數目為2{i-1}=2{0}=1。因為第1層上只有一個根結點,所以命題成立。
? ? ? ? (02) 假設當i>1,第i層的節點數目為2{i-1}。這個是根據(01)推斷出來的!
? ? ? ? ? ? ? ?下面根據這個假設,推斷出"第(i+1)層的節點數目為2{i}"即可。
? ? ? ? ? ? ? ? 由于二叉樹的每個結點至多有兩個孩子,故"第(i+1)層上的結點數目" 最多是 "第i層的結點數目的2倍"。即,第(i+1)層上的結點數目最大值=2×2{i-1}=2{i}
? ? ? ? ? ? ? ? 故假設成立,原命題得證!

?

2.2 性質2:深度為k的二叉樹至多有2{k}-1個結點(k≥1)

證明:在具有相同深度的二叉樹中,當每一層都含有最大結點數時,其樹中結點數最多。利用"性質1"可知,深度為k的二叉樹的結點數至多為:
? ? ? ? ? ?20+21+…+2k-1=2k-1
? ? ? ? ? ?故原命題得證!

?

2.3 性質3:包含n個結點的二叉樹的高度至少為log2?(n+1)

證明:根據"性質2"可知,高度為h的二叉樹最多有2{h}–1個結點。反之,對于包含n個節點的二叉樹的高度至少為log2(n+1)。

?

2.4 性質4:在任意一棵二叉樹中,若終端結點的個數為n0,度為2的結點數為n2,則n0=n2+1

證明:因為二叉樹中所有結點的度數均不大于2,所以結點總數(記為n)="0度結點數(n0)" + "1度結點數(n1)" + "2度結點數(n2)"。由此,得到等式一。
? ? ? ? ?(等式一)?n=n0+n1+n2
  ? ? 另一方面,0度結點沒有孩子,1度結點有一個孩子,2度結點有兩個孩子,故二叉樹中孩子結點總數是:n1+2n2。此外,只有根不是任何結點的孩子。故二叉樹中的結點總數又可表示為等式二。
? ? ? ? ?(等式二)?n=n1+2n2+1
? ? ? ? 由(等式一)和(等式二)計算得到:n0=n2+1。原命題得證!

?

3. 滿二叉樹,完全二叉樹和二叉查找樹

3.1 滿二叉樹

定義:高度為h,并且由2{h}?–1個結點的二叉樹,被稱為滿二叉樹。

?

3.2 完全二叉樹

定義:一棵二叉樹中,只有最下面兩層結點的度可以小于2,并且最下一層的葉結點集中在靠左的若干位置上。這樣的二叉樹稱為完全二叉樹。
特點:葉子結點只能出現在最下層和次下層,且最下層的葉子結點集中在樹的左部。顯然,一棵滿二叉樹必定是一棵完全二叉樹,而完全二叉樹未必是滿二叉樹。

?

3.3 二叉查找樹

定義:二叉查找樹(Binary Search Tree),又被稱為二叉搜索樹。設x為二叉查找樹中的一個結點,x節點包含關鍵字key,節點x的key值記為key[x]。如果y是x的左子樹中的一個結點,則key[y] <= key[x];如果y是x的右子樹的一個結點,則key[y] >= key[x]。

在二叉查找樹中:
(01) 若任意節點的左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;
(02) 任意節點的右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;
(03) 任意節點的左、右子樹也分別為二叉查找樹。
(04) 沒有鍵值相等的節點(no duplicate nodes)。

在實際應用中,二叉查找樹的使用比較多。下面,用C語言實現二叉查找樹。

?

二叉查找樹的C實現

1. 節點定義

1.1 節點定義

typedef int Type;typedef struct BSTreeNode{Type key; // 關鍵字(鍵值)struct BSTreeNode *left; // 左孩子struct BSTreeNode *right; // 右孩子struct BSTreeNode *parent; // 父結點 }Node, *BSTree;

二叉查找樹的節點包含的基本信息:
(01)?key ? ? ??-- 它是關鍵字,是用來對二叉查找樹的節點進行排序的。
(02)?left ? ? ??-- 它指向當前節點的左孩子。
(03)?right? ? -- 它指向當前節點的右孩子。
(04)?parent?-- 它指向當前節點的父結點。

?

1.2 創建節點

創建節點的代碼

static Node* create_bstree_node(Type key, Node *parent, Node *left, Node* right) {Node* p;if ((p = (Node *)malloc(sizeof(Node))) == NULL)return NULL;p->key = key;p->left = left;p->right = right;p->parent = parent;return p; }

?

2 遍歷

這里講解前序遍歷中序遍歷后序遍歷3種方式。

2.1 前序遍歷

若二叉樹非空,則執行以下操作:
(01) 訪問根結點;
(02) 先序遍歷左子樹;
(03) 先序遍歷右子樹。

前序遍歷代碼

void preorder_bstree(BSTree tree) {if(tree != NULL){printf("%d ", tree->key);preorder_bstree(tree->left);preorder_bstree(tree->right);} }

?

2.2 中序遍歷

若二叉樹非空,則執行以下操作:
(01) 中序遍歷左子樹;
(02) 訪問根結點;
(03) 中序遍歷右子樹。

中序遍歷代碼

void inorder_bstree(BSTree tree) {if(tree != NULL){inorder_bstree(tree->left);printf("%d ", tree->key);inorder_bstree(tree->right);} }

?

2.3 后序遍歷

若二叉樹非空,則執行以下操作:
(01) 后序遍歷左子樹;
(02) 后序遍歷右子樹;
(03) 訪問根結點。

后序遍歷代碼

void postorder_bstree(BSTree tree) {if(tree != NULL){postorder_bstree(tree->left);postorder_bstree(tree->right);printf("%d ", tree->key);} }

?

?

下面通過例子對這些遍歷方式進行介紹。

對于上面的二叉樹而言,
(01) 前序遍歷結果:?3 1 2 5 4 6
(02) 中序遍歷結果:?1 2 3 4 5 6?
(03) 后序遍歷結果:?2 1 4 6 5 3

?

3. 查找

遞歸版本的代碼

Node* bstree_search(BSTree x, Type key) {if (x==NULL || x->key==key)return x;if (key < x->key)return bstree_search(x->left, key);elsereturn bstree_search(x->right, key); }

非遞歸版本的代碼

Node* iterative_bstree_search(BSTree x, Type key) {while ((x!=NULL) && (x->key!=key)){if (key < x->key)x = x->left;elsex = x->right;}return x; }

?

4. 最大值和最小值

查找最大值的代碼

Node* bstree_maximum(BSTree tree) {if (tree == NULL)return NULL;while(tree->right != NULL)tree = tree->right;return tree; }

查找最小值的代碼

Node* bstree_minimum(BSTree tree) {if (tree == NULL)return NULL;while(tree->left != NULL)tree = tree->left;return tree; }


5. 前驅和后繼

節點的前驅:是該節點的左子樹中的最大節點。
節點的后繼:是該節點的右子樹中的最小節點。

查找前驅節點的代碼

Node* bstree_predecessor(Node *x) {// 如果x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。if (x->left != NULL)return bstree_maximum(x->left);// 如果x沒有左孩子。則x有以下兩種可能:// (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。// (01) x是"一個左孩子",則查找"x的最低的父結點,并且該父結點要具有右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。Node* y = x->parent;while ((y!=NULL) && (x==y->left)){x = y;y = y->parent;}return y; }

查找后繼節點的代碼

Node* bstree_successor(Node *x) {// 如果x存在右孩子,則"x的后繼結點"為 "以其右孩子為根的子樹的最小結點"。if (x->right != NULL)return bstree_minimum(x->right);// 如果x沒有右孩子。則x有以下兩種可能:// (01) x是"一個左孩子",則"x的后繼結點"為 "它的父結點"。// (02) x是"一個右孩子",則查找"x的最低的父結點,并且該父結點要具有左孩子",找到的這個"最低的父結點"就是"x的后繼結點"。Node* y = x->parent;while ((y!=NULL) && (x==y->right)){x = y;y = y->parent;}return y; }

?

6. 插入

插入節點的代碼

static Node* bstree_insert(BSTree tree, Node *z) {Node *y = NULL;Node *x = tree;// 查找z的插入位置while (x != NULL){y = x;if (z->key < x->key)x = x->left;elsex = x->right;}z->parent = y;if (y==NULL)tree = z;else if (z->key < y->key)y->left = z;elsey->right = z;return tree; }Node* insert_bstree(BSTree tree, Type key) {Node *z; // 新建結點// 如果新建結點失敗,則返回。if ((z=create_bstree_node(key, NULL, NULL, NULL)) == NULL)return tree;return bstree_insert(tree, z); }

bstree_insert(tree, z)是內部函數,它的作用是:將結點(z)插入到二叉樹(tree)中,并返回插入節點后的根節點。
insert_bstree(tree, key)是對外接口,它的作用是:在樹中新增節點,key是節點的值;并返回插入節點后的根節點。

?

注:本文實現的二叉查找樹是允許插入相同鍵值的節點的!若用戶不希望插入相同鍵值的節點,將bstree_insert()修改為以下代碼即可。

static Node* bstree_insert(BSTree tree, Node *z) {Node *y = NULL;Node *x = tree;// 查找z的插入位置while (x != NULL){y = x;if (z->key < x->key)x = x->left;else if (z->key > x->key)x = x->right;else{free(z); // 釋放之前分配的系統。return tree;}}z->parent = y;if (y==NULL)tree = z;else if (z->key < y->key)y->left = z;elsey->right = z;return tree; }

?

7. 刪除

刪除節點的代碼

static Node* bstree_delete(BSTree tree, Node *z) {Node *x=NULL;Node *y=NULL;if ((z->left == NULL) || (z->right == NULL) )y = z;elsey = bstree_successor(z);if (y->left != NULL)x = y->left;elsex = y->right;if (x != NULL)x->parent = y->parent;if (y->parent == NULL)tree = x;else if (y == y->parent->left)y->parent->left = x;elsey->parent->right = x;if (y != z) z->key = y->key;if (y!=NULL)free(y);return tree; }Node* delete_bstree(BSTree tree, Type key) {Node *z, *node; if ((z = bstree_search(tree, key)) != NULL)tree = bstree_delete(tree, z);return tree; }

bstree_delete(tree, z)是內部函數,它的作用是:刪除二叉樹(tree)中的節點(z),并返回刪除節點后的根節點。
delete_bstree(tree, key)是對外接口,它的作用是:在樹中查找鍵值為key的節點,找到的話就刪除該節點;并返回刪除節點后的根節點。


8. 打印

打印二叉樹的代碼

void print_bstree(BSTree tree, Type key, int direction) {if(tree != NULL){if(direction==0) // tree是根節點printf("%2d is root\n", tree->key);else // tree是分支節點printf("%2d is %2d's %6s child\n", tree->key, key, direction==1?"right" : "left");print_bstree(tree->left, tree->key, -1);print_bstree(tree->right,tree->key, 1);} }

print_bstree(tree, key, direction)的作用是打印整顆二叉樹(tree)。其中,tree是二叉樹節點,key是二叉樹的鍵值,而direction表示該節點的類型:

direction為 0,表示該節點是根節點;
direction為-1,表示該節點是它的父結點的左孩子;
direction為?1,表示該節點是它的父結點的右孩子。

?

9. 銷毀二叉樹

銷毀二叉樹的代碼

void destroy_bstree(BSTree tree) {if (tree==NULL)return ;if (tree->left != NULL)destroy_bstree(tree->left);if (tree->right != NULL)destroy_bstree(tree->right);free(tree); }

?

完整的實現代碼

二叉查找樹的頭文件(bstree.h)

#ifndef _BINARY_SEARCH_TREE_H_ #define _BINARY_SEARCH_TREE_H_typedef int Type;typedef struct BSTreeNode{Type key; // 關鍵字(鍵值)struct BSTreeNode *left; // 左孩子struct BSTreeNode *right; // 右孩子struct BSTreeNode *parent; // 父結點 }Node, *BSTree;// 前序遍歷"二叉樹" void preorder_bstree(BSTree tree); // 中序遍歷"二叉樹" void inorder_bstree(BSTree tree); // 后序遍歷"二叉樹" void postorder_bstree(BSTree tree);// (遞歸實現)查找"二叉樹x"中鍵值為key的節點 Node* bstree_search(BSTree x, Type key); // (非遞歸實現)查找"二叉樹x"中鍵值為key的節點 Node* iterative_bstree_search(BSTree x, Type key);// 查找最小結點:返回tree為根結點的二叉樹的最小結點。 Node* bstree_minimum(BSTree tree); // 查找最大結點:返回tree為根結點的二叉樹的最大結點。 Node* bstree_maximum(BSTree tree);// 找結點(x)的后繼結點。即,查找"二叉樹中數據值大于該結點"的"最小結點"。 Node* bstree_successor(Node *x); // 找結點(x)的前驅結點。即,查找"二叉樹中數據值小于該結點"的"最大結點"。 Node* bstree_predecessor(Node *x);// 將結點插入到二叉樹中,并返回根節點 Node* insert_bstree(BSTree tree, Type key);// 刪除結點(key為節點的值),并返回根節點 Node* delete_bstree(BSTree tree, Type key);// 銷毀二叉樹 void destroy_bstree(BSTree tree);// 打印二叉樹 void print_bstree(BSTree tree, Type key, int direction);#endif

二叉查找樹的實現文件(bstree.c)

/*** 二叉搜索樹(C語言): C語言實現的二叉搜索樹。** @author skywang* @date 2013/11/07*/#include <stdio.h> #include <stdlib.h> #include "bstree.h"/** 前序遍歷"二叉樹"*/ void preorder_bstree(BSTree tree) {if(tree != NULL){printf("%d ", tree->key);preorder_bstree(tree->left);preorder_bstree(tree->right);} }/** 中序遍歷"二叉樹"*/ void inorder_bstree(BSTree tree) {if(tree != NULL){inorder_bstree(tree->left);printf("%d ", tree->key);inorder_bstree(tree->right);} }/** 后序遍歷"二叉樹"*/ void postorder_bstree(BSTree tree) {if(tree != NULL){postorder_bstree(tree->left);postorder_bstree(tree->right);printf("%d ", tree->key);} }/** (遞歸實現)查找"二叉樹x"中鍵值為key的節點*/ Node* bstree_search(BSTree x, Type key) {if (x==NULL || x->key==key)return x;if (key < x->key)return bstree_search(x->left, key);elsereturn bstree_search(x->right, key); }/** (非遞歸實現)查找"二叉樹x"中鍵值為key的節點*/ Node* iterative_bstree_search(BSTree x, Type key) {while ((x!=NULL) && (x->key!=key)){if (key < x->key)x = x->left;elsex = x->right;}return x; }/* * 查找最小結點:返回tree為根結點的二叉樹的最小結點。*/ Node* bstree_minimum(BSTree tree) {if (tree == NULL)return NULL;while(tree->left != NULL)tree = tree->left;return tree; }/* * 查找最大結點:返回tree為根結點的二叉樹的最大結點。*/ Node* bstree_maximum(BSTree tree) {if (tree == NULL)return NULL;while(tree->right != NULL)tree = tree->right;return tree; }/* * 找結點(x)的后繼結點。即,查找"二叉樹中數據值大于該結點"的"最小結點"。*/ Node* bstree_successor(Node *x) {// 如果x存在右孩子,則"x的后繼結點"為 "以其右孩子為根的子樹的最小結點"。if (x->right != NULL)return bstree_minimum(x->right);// 如果x沒有右孩子。則x有以下兩種可能:// (01) x是"一個左孩子",則"x的后繼結點"為 "它的父結點"。// (02) x是"一個右孩子",則查找"x的最低的父結點,并且該父結點要具有左孩子",找到的這個"最低的父結點"就是"x的后繼結點"。Node* y = x->parent;while ((y!=NULL) && (x==y->right)){x = y;y = y->parent;}return y; }/* * 找結點(x)的前驅結點。即,查找"二叉樹中數據值小于該結點"的"最大結點"。*/ Node* bstree_predecessor(Node *x) {// 如果x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。if (x->left != NULL)return bstree_maximum(x->left);// 如果x沒有左孩子。則x有以下兩種可能:// (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。// (01) x是"一個左孩子",則查找"x的最低的父結點,并且該父結點要具有右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。Node* y = x->parent;while ((y!=NULL) && (x==y->left)){x = y;y = y->parent;}return y; }/** 創建并返回二叉樹結點。** 參數說明:* key 是鍵值。* parent 是父結點。* left 是左孩子。* right 是右孩子。*/ static Node* create_bstree_node(Type key, Node *parent, Node *left, Node* right) {Node* p;if ((p = (Node *)malloc(sizeof(Node))) == NULL)return NULL;p->key = key;p->left = left;p->right = right;p->parent = parent;return p; }/* * 將結點插入到二叉樹中** 參數說明:* tree 二叉樹的根結點* z 插入的結點* 返回值:* 根節點*/ static Node* bstree_insert(BSTree tree, Node *z) {Node *y = NULL;Node *x = tree;// 查找z的插入位置while (x != NULL){y = x;if (z->key < x->key)x = x->left;elsex = x->right;}z->parent = y;if (y==NULL)tree = z;else if (z->key < y->key)y->left = z;elsey->right = z;return tree; }/* * 新建結點(key),并將其插入到二叉樹中** 參數說明:* tree 二叉樹的根結點* key 插入結點的鍵值* 返回值:* 根節點*/ Node* insert_bstree(BSTree tree, Type key) {Node *z; // 新建結點// 如果新建結點失敗,則返回。if ((z=create_bstree_node(key, NULL, NULL, NULL)) == NULL)return tree;return bstree_insert(tree, z); }/* * 刪除結點(z),并返回根節點** 參數說明:* tree 二叉樹的根結點* z 刪除的結點* 返回值:* 根節點*/ static Node* bstree_delete(BSTree tree, Node *z) {Node *x=NULL;Node *y=NULL;if ((z->left == NULL) || (z->right == NULL) )y = z;elsey = bstree_successor(z);if (y->left != NULL)x = y->left;elsex = y->right;if (x != NULL)x->parent = y->parent;if (y->parent == NULL)tree = x;else if (y == y->parent->left)y->parent->left = x;elsey->parent->right = x;if (y != z) z->key = y->key;if (y!=NULL)free(y);return tree; }/* * 刪除結點(key為節點的鍵值),并返回根節點** 參數說明:* tree 二叉樹的根結點* z 刪除的結點* 返回值:* 根節點*/ Node* delete_bstree(BSTree tree, Type key) {Node *z, *node; if ((z = bstree_search(tree, key)) != NULL)tree = bstree_delete(tree, z);return tree; }/** 銷毀二叉樹*/ void destroy_bstree(BSTree tree) {if (tree==NULL)return ;if (tree->left != NULL)destroy_bstree(tree->left);if (tree->right != NULL)destroy_bstree(tree->right);free(tree); }/** 打印"二叉樹"** tree -- 二叉樹的節點* key -- 節點的鍵值 * direction -- 0,表示該節點是根節點;* -1,表示該節點是它的父結點的左孩子;* 1,表示該節點是它的父結點的右孩子。*/ void print_bstree(BSTree tree, Type key, int direction) {if(tree != NULL){if(direction==0) // tree是根節點printf("%2d is root\n", tree->key);else // tree是分支節點printf("%2d is %2d's %6s child\n", tree->key, key, direction==1?"right" : "left");print_bstree(tree->left, tree->key, -1);print_bstree(tree->right,tree->key, 1);} }

二叉查找樹的測試程序(btree_test.c)

?/*** C 語言: 二叉查找樹** @author skywang* @date 2013/11/07*/#include <stdio.h> #include "bstree.h"static int arr[]= {1,5,4,3,2,6}; #define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )void main() {int i, ilen;BSTree root=NULL;printf("== 依次添加: ");ilen = TBL_SIZE(arr);for(i=0; i<ilen; i++){printf("%d ", arr[i]);root = insert_bstree(root, arr[i]);}printf("\n== 前序遍歷: ");preorder_bstree(root);printf("\n== 中序遍歷: ");inorder_bstree(root);printf("\n== 后序遍歷: ");postorder_bstree(root);printf("\n");printf("== 最小值: %d\n", bstree_minimum(root)->key);printf("== 最大值: %d\n", bstree_maximum(root)->key);printf("== 樹的詳細信息: \n");print_bstree(root, root->key, 0);printf("\n== 刪除根節點: %d", arr[3]);root = delete_bstree(root, arr[3]);printf("\n== 中序遍歷: ");inorder_bstree(root);printf("\n");// 銷毀二叉樹destroy_bstree(root); }

?

二叉查找樹的C測試程序

上面的btree_test.c是二叉查找樹的測試程序,它的運行結果如下:

== 依次添加: 1 5 4 3 2 6 == 前序遍歷: 1 5 4 3 2 6 == 中序遍歷: 1 2 3 4 5 6 == 后序遍歷: 2 3 4 6 5 1 == 最小值: 1 == 最大值: 6 == 樹的詳細信息: 1 is root5 is 1's right child4 is 5's left child3 is 4's left child2 is 3's left child6 is 5's right child== 刪除根節點: 3 == 中序遍歷: 1 2 4 5 6

?

下面對測試程序的流程進行分析!

(01) 新建"二叉查找樹"root。

?

(02) 向二叉查找樹中依次插入1,5,4,3,2,6?。如下圖所示:

?

(03) 打印樹的信息
插入1,5,4,3,2,6之后,得到的二叉查找樹如下:

前序遍歷結果:?1 5 4 3 2 6?
中序遍歷結果:?1 2 3 4 5 6?
后序遍歷結果:?2 3 4 6 5 1?
最小值是1,而最大值是6。

?

?

(04) 刪除節點3。如下圖所示:

?

(05) 重新遍歷該二叉查找樹。
中序遍歷結果:?1 2 4 5 6

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的二叉查找树(一)之 C语言的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。