binary search tree,中文翻譯為二叉搜索樹、二叉查找樹或者二叉排序樹。簡稱為BST
一:二叉搜索樹的定義
他的定義與樹的定義是類似的,也是一個遞歸的定義:
1、要麼是一棵空樹
2、如果不為空,那麼其左子樹節點的值都小於根節點的值;右子樹節點的值都大於根節點的值
3、其左右子樹也是二叉搜索樹
在算法導論中的定義:
下圖中是BST的兩個例子:
其中(b)圖中的樹是很不平衡的(所謂不平衡是值左右子樹的高度差比較大)
BST在數據結構中占有很重要的地位,一些高級樹結構都是其的變種,例如AVL樹、紅黑樹等,因此理解BST對於後續樹結構的學習有很好的作用。同時利用BST可以進行排序,稱為二叉排序,也是很重要的一種思想。
相關代碼如下:
/** 二叉排序樹(BST)創建,刪除,查找操作 **/ #include<stdio.h> #include<stdlib.h> #define LENGTH 15 typedef int ElemType; //數據類型 typedef struct BiTNode{ ElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode,*BiTree; /** * 向下遍歷查找給定結點的相鄰節點,以便插入指定節點 */ void searchBiTreeNode(BiTree &root,BiTree &node){ if(root == NULL){ return; } if(root->data > node->data){ searchBiTreeNode(root->lchild,node); //遞歸遍歷搜索 if(root->lchild == NULL){ root->lchild = node; } }else if(root->data < node->data){ searchBiTreeNode(root->rchild,node); if(root->rchild == NULL){ root->rchild = node; } } } /** * 插入指定節點node */ void insertNode(BiTree &biTree,BiTree &node){ if(biTree==NULL){ biTree = node; }else{ searchBiTreeNode(biTree,node); } } /** * 刪除指定元素x */ void deleteNode(BiTree &root,ElemType x){ if(root == NULL){ return; } if(root->data>x){ deleteNode(root->lchild,x); }else if(root->data<x){ deleteNode(root->rchild,x); }else{ //查找到了刪除節點 if(root->lchild == NULL){ //左子樹為空 BiTree tempNode = root; root = root->rchild; free(tempNode); }else if(root->rchild == NULL){ //右子樹為空 BiTree tempNode = root; root = root->lchild; free(tempNode); }else{ //左右子樹都不為空 //一般的刪除策略是左子樹的最大數據 或 右子樹的最小數據 代替該節點(這裡采用查找左子樹最大數據來代替) BiTree tempNode = root->lchild; if(tempNode->rchild!=NULL){ tempNode = tempNode->rchild; } root->data = tempNode->data; deleteNode(root->lchild,tempNode->data); } } } /** * 查找指定元素x所在的節點 */ BiTree BST_Search(BiTree &root,ElemType x){ if(root == NULL){ return NULL; }else if(root->data>x){ return BST_Search(root->lchild,x); }else if(root->data<x){ return BST_Search(root->rchild,x); }else{ return root; } } /** * 二叉排序樹創建 */ void createBiOrderTree(BiTree &biTree,ElemType arr[]){ for(int i=0;i<LENGTH;i++){ BiTree s = (BiTree)malloc(sizeof(BiTNode)); s->data = arr[i]; s->lchild = NULL; s->rchild = NULL; insertNode(biTree,s); } } /** * 中序打印二叉樹 */ void midSearchBiTreePrint(BiTree &biTree){ if(biTree == NULL){ return; } midSearchBiTreePrint(biTree->lchild); printf("%d ",biTree->data); midSearchBiTreePrint(biTree->rchild); } /** * 測試程序入口 */ int main(){ ElemType arr[LENGTH] = {62,88,58,47,35,73,51,99,37,93,23,27,45,21,12}; BiTree biTree = NULL; /** 創建二叉排序樹,並測試數據 **/ createBiOrderTree(biTree,arr); midSearchBiTreePrint(biTree); printf("\n"); /** 從二叉排序樹中刪除指定元素,並測試數據 **/ deleteNode(biTree,35); midSearchBiTreePrint(biTree); printf("\n"); /** 二叉排序樹查找指定元素操作,並測試數據 **/ BiTree searchNode = BST_Search(biTree,27); if(searchNode == NULL){ fprintf(stdout,"沒有查找到節點\n"); }else{ if(searchNode->lchild==NULL && searchNode->rchild==NULL){ //葉子節點 printf("所查找的節點x=%d是葉子節點\n",searchNode->data); }else{ if(searchNode->lchild != NULL){ printf("x=%d所在節點的左孩子: %d\n",searchNode->data,searchNode->lchild->data); } if(searchNode->rchild != NULL){ printf("x=%d所在節點的右孩子: %d\n",searchNode->data,searchNode->rchild->data); } } } return 0; }
運行結果截圖:
二叉樹的常見問題及其解決程序 http://www.linuxidc.com/Linux/2013-04/83661.htm
【遞歸】二叉樹的先序建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75608.htm
在JAVA中實現的二叉樹結構 http://www.linuxidc.com/Linux/2008-12/17690.htm
【非遞歸】二叉樹的建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75607.htm
二叉樹遞歸實現與二重指針 http://www.linuxidc.com/Linux/2013-07/87373.htm
二叉樹先序中序非遞歸算法 http://www.linuxidc.com/Linux/2014-06/102935.htm
輕松搞定面試中的二叉樹題目 http://www.linuxidc.com/linux/2014-07/104857.htm