【資料結構】——搜尋二叉樹的插入,查詢和刪除(遞迴&非遞迴)
一、搜尋二叉樹的插入,查詢,刪除
簡單說說搜尋二叉樹概念:
二叉搜尋樹又稱二叉排序樹,它或者是一棵空樹,或者是具有以下性質的二叉樹
若它的左子樹不為空,則左子樹上所有節點的值都小於根節點的值
若它的右子樹不為空,則右子樹上所有節點的值都大於根節點的值
它的左右子樹也分別為二叉搜尋樹
例如:int a [] = {5,3,4,1,7,8,2,6,0,9};
二叉樹結構
typedef struct BSTreeNode
{
struct BSTreeNode *_left;
struct BSTreeNode *_right;
DataType _data;
}BSTreeNode;
二叉樹節點建立
BSTreeNode *BuyTreeNode(DataType x) //建立節點
{
BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
assert(node);
node->_data = x;
node->_left = NULL;
node->_right = NULL;
return node;
}
二叉搜尋樹操作:
1、搜尋二叉樹的插入:在二叉搜尋樹中插入新元素時,必須先檢測該元素是否在樹中已經存在。如果已經存在,則不進行插入;否則將新元素加入到搜尋停止的地方。
非遞迴程式碼
int BSTreeNodeInsert(BSTreeNode **pptree,DataType x) //搜尋樹的插入
{
BSTreeNode *parent = NULL;
BSTreeNode *cur = *pptree;
if (*pptree == NULL)
{
*pptree = BuyTreeNode(x);
return 0;
}
while (cur)
{
parent = cur;
if (cur->_data > x)
cur = cur->_left;
else if (cur->_data < x)
cur = cur->_right;
else
return -1;
}
if (parent->_data > x)
parent->_left = BuyTreeNode(x);
else
parent->_right = BuyTreeNode(x);
return 0;
}
遞迴程式碼 :
int BSTreeNodeInsertR(BSTreeNode **tree,DataType x) //搜尋樹的插入
{
if(*tree == NULL)
{
*tree = BuyTreeNode(x);
return 0;
}
if ((*tree)->_data > x)
return BSTreeNodeInsertR(&(*tree)->_left,x);
else if ((*tree)->_data < x)
return BSTreeNodeInsertR(&(*tree)->_right,x);
else
return -1;
}
2、搜尋二叉樹的查詢:
非遞迴程式碼
BSTreeNode *BSTreeNodeFind(BSTreeNode *tree,DataType x) //查詢
{
while (tree)
{
if (tree->_data == x)
return tree;
else if (tree->_data < x)
tree = tree->_right;
else
tree = tree->_left;
}
return NULL;
}
遞迴程式碼
BSTreeNode *BSTreeNodeFindR(BSTreeNode *tree,DataType x) //查詢
{
if (!tree)
return NULL;
if (tree->_data > x)
BSTreeNodeFindR(tree->_left,x);
else if (tree->_data < x)
BSTreeNodeFindR(tree->_right,x);
else
return tree;
}
3、搜尋二叉樹的刪除:
首先查詢元素是否在二叉搜尋樹中,如果不存在,則返回, 否則要刪除的結點可能分下面四種情況:
a. 要刪除的結點無孩子結點
b. 要刪除的結點只有左孩子結點
c. 要刪除的結點只有右孩子結點
d. 要刪除的結點有左、右孩子結點
情況1可以歸類到2或者3
對於上述情況,相應的刪除方法如下:
a. 直接刪除該結點
b. 刪除該結點且使被刪除節點的雙親結點指向被刪除節點的左孩子結點
c. 刪除該結點且使被刪除節點的雙親結點指向被刪除結點的右孩子結點
d. 在它的右子樹中尋找中序下的第一個結點(關鍵碼最小),用它的值填補到被刪除節點中,在來處理該結點的刪除問題
非遞迴程式碼實現:
int BSTreeNodeDel(BSTreeNode **tree,DataType x) //刪除
{
BSTreeNode *cur = *tree;
BSTreeNode *parent = *tree;
BSTreeNode *del = NULL;
while (cur)
{
if (cur->_data > x)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_data < x)
{
parent = cur;
cur = cur->_right;
}
else
{
del = cur;
if (cur->_left == NULL) //1、左孩子為空
{
if (parent->_left == cur)
parent->_left = cur->_right;
else if (parent->_right == cur)
parent->_right = cur->_right;
else if (parent == cur) //沒有父親節點時
*tree = parent->_right;
}
else if (cur->_right == NULL) //2、右孩子為空
{
if (parent->_left == cur)
parent->_left = cur->_left;
else if (parent->_right == cur)
parent->_right = cur->_left;
else if (parent == cur) //沒有父親節點時
*tree = parent->_left;
}
else//3、左右孩子都不為空
{
BSTreeNode *sub = cur->_right;
while (sub->_left)
{
parent = sub;
sub = sub->_left;
}
del = sub;
cur->_data = sub->_data;
if (parent->_left == sub)
parent->_left = sub->_right;
else
parent->_right = sub->_right;
}
free(del);
del = NULL;
return 0;
}
}
return -1;
}
遞迴程式碼實現
int BSTreeNodeDelR(BSTreeNode **tree,DataType x) //刪除
{
if (!*tree)
return -1;
if ((*tree)->_data > x)
return BSTreeNodeDelR(&(*tree)->_left,x);
else if ((*tree)->_data < x)
return BSTreeNodeDelR(&(*tree)->_right,x);
else
{
BSTreeNode *del = *tree;
if (!(*tree)->_left) //左為空
*tree = (*tree)->_right;
else if (!(*tree)->_right) //右為空
*tree = (*tree)->_left;
else //左右都不為空
{
BSTreeNode *sub = (*tree)->_right;
while (sub->_left)
sub = sub->_left;
(*tree)->_data = sub->_data;
return BSTreeNodeDelR(&(*tree)->_right,sub->_data);
}
free(del);
del = NULL;
return 0;
}
}
完整程式碼請私信或者點此連結下載【資料結構】——搜尋二叉樹的插入,查詢和刪除(遞迴&非遞迴)
相關文章
- 【資料結構】二叉樹遍歷(遞迴+非遞迴)資料結構二叉樹遞迴
- 關於樹型結構資料遞迴查詢,轉非遞迴查詢的實現遞迴
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- Java實現遞迴查詢樹結構Java遞迴
- 資料結構之二叉樹遞迴操作資料結構二叉樹遞迴
- 二叉樹的四種遍歷(遞迴與非遞迴)二叉樹遞迴
- 二叉樹的前中後序遍歷(遞迴和非遞迴版本)二叉樹遞迴
- 二叉樹非遞迴遍歷二叉樹遞迴
- 資料結構-樹以及深度、廣度優先遍歷(遞迴和非遞迴,python實現)資料結構遞迴Python
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 通用-遞迴樹結構遞迴
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- [java] 二叉樹的後序遍歷(遞迴與非遞迴實現)Java二叉樹遞迴
- 二叉樹建立及遍歷演算法(遞迴及非遞迴)二叉樹演算法遞迴
- 資料結構-遞迴資料結構遞迴
- 什麼是遍歷二叉樹,JavaScript實現二叉樹的遍歷(遞迴,非遞迴)二叉樹JavaScript遞迴
- 【Java資料結構與演算法筆記(二)】樹的四種遍歷方式(遞迴&非遞迴)Java資料結構演算法筆記遞迴
- 利用非遞迴演算法來搜尋二叉樹中的某個元素java遞迴演算法二叉樹Java
- 非遞迴先序遍歷二叉樹遞迴二叉樹
- 【刷題】二叉樹非遞迴遍歷二叉樹遞迴
- 二叉樹的非遞迴遍歷寫法二叉樹遞迴
- 二叉查詢樹的插入刪除查詢
- Java遍歷資料夾的兩種方法(非遞迴和遞迴)Java遞迴
- 資料結構初階--二叉樹(前中後序遍歷遞迴+非遞迴實現+相關求算結點實現)資料結構二叉樹遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- js樹型結構資料簡易遞迴JS遞迴
- 樹結構表遞迴查詢在ORACLE和MSSQL中的實現方法遞迴OracleSQL
- python實現二叉樹及其七種遍歷方式(遞迴+非遞迴)Python二叉樹遞迴
- oracle之樹狀結構的儲存與展示(遞迴查詢)Oracle遞迴
- 樹3-二叉樹非遞迴遍歷(棧)二叉樹遞迴
- 二叉樹的遞迴套路二叉樹遞迴
- 遞迴樹形查詢所有分類遞迴
- Mysql 實現樹狀遞迴查詢MySql遞迴
- 實現二叉搜尋樹的新增,查詢和刪除(JAVA)Java
- PostgreSQL 遞迴查詢SQL遞迴
- PostgreSQL=>遞迴查詢SQL遞迴