数据结构与算法——二叉排序树详解以及代码实现
生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法——二叉排序树详解以及代码实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉排序樹介紹
我們知道二叉樹,每個結點最多有2棵子樹,被稱為左子樹 和 右子樹。
二叉排序樹,顯然也是一顆二叉樹,它有更突出的特性在數據域上呈現排序的特性。
在二叉排序樹中,每個樹的左子樹的數據域均小于它的根結點值,每個樹的右子樹的數據域均大于它的根結點值,每棵樹的左、右子樹 均為二叉排序樹。從它特性很容易得到,對二叉排序樹 進行中序遍歷一定是升序序列。
代碼實現思路
二叉排序樹,相關算法主要有:
- 創建二叉排序樹
- 結點的查詢
- 結點的插入
- 結點的刪除
查詢?很好實現吧,遞歸結點查詢key的值是否相等 ,不相等就遞歸查詢唄,遞歸出口 node==NULL,查詢到結點通過傳出參數返回,沒有查詢到返回離key值最近的結點。
插入?根據二叉排序的特性進行插入唄,可以調用查詢接口,如果二叉排序樹沒有該結點,則允許插入,將插入結點掛到返回的結點上唄。
刪除?刪除就要分情況了,第3種情況有點繞,初學者要好好結合代碼理解。
創建二叉排序樹?利用插入算法直接實現唄,剛開始為空二叉樹,利用插入算法,可以生成二叉排序樹。
實現代碼
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h>//二叉樹節點 typedef struct BiNode {int data;struct BiNode* lchild, *rchild; }BiNode,*BiTree;typedef enum bool{ false,true }bool;//二叉樹 中序遍歷 void TraverseMid(BiTree root) {if (root == NULL){return;}TraverseMid(root->lchild);printf("%d ", root->data);TraverseMid(root->rchild); } /* 二叉排序樹的查詢tree 查找的二叉樹根結點parent tree的雙親結點node 傳出參數,查找到的結點指針,沒找到為最接近key的結點的指針key 查找關鍵字 */ bool SearchBST(BiTree root,BiTree parent,BiNode** node,int key ) {if (root == NULL) //已經找到頭了,還沒有找到,返回最接近key的結點的指針{*node = parent;return false;}else{if (key < root->data) //key 比root 小,搜索root的左子樹{return SearchBST(root->lchild, root, node, key);}else if(key > root->data) //key 比root 大,搜索root的右子樹{return SearchBST(root->rchild, root, node, key);}else //key == root->data,找到key 返回{*node = root;return true;}} } //插入 bool InsertBST(BiTree root, int data) {BiNode* node = NULL;if (SearchBST(root, NULL, &node, data)) //在樹上有相同的結點,不允許插入{return false;}else{BiNode * newNode = (BiNode*)malloc(sizeof(BiNode));newNode->lchild = newNode->rchild = NULL;newNode->data = data;if (data < node->data){node->lchild = newNode;}else{node->rchild = newNode;}return true;} } //具體刪除結點動作 bool DeleteNode(BiTree* node) {BiTree tmp, pre, pre_parent;if ((*node)->lchild == NULL) //刪除結點的左子樹為NULL,將右子樹頂替,釋放刪除結點內存{tmp = *node;*node = (*node)->rchild; free(tmp);}else if ((*node)->rchild == NULL) //刪除結點的右子樹為NULL,將左子樹頂替,釋放刪除結點內存{tmp = *node;*node = (*node)->lchild;free(tmp);}else //刪除結點的左右子樹均不為空,刪除結點數據換成其前驅或者后繼的數據 結點并不釋放,這里換成前驅{pre_parent = *node;pre = pre_parent->lchild; //pre 刪除結點的中序遍歷前驅結點while (pre->rchild != NULL) //while循環 尋找左子樹中最大結點{pre_parent = pre;pre = pre->rchild;}if (pre == (*node)->lchild){(*node)->data = pre->data;(*node)->lchild = pre->lchild;}else{(*node)->data = pre->data;pre_parent->rchild = pre->lchild;}free(pre);}return true; } //刪除 bool DeleteBST(BiTree *root, int key) {if (root == NULL)return false;if (key == (*root)->data){return DeleteNode(root);}else if (key < (*root)->data){return DeleteBST(&(*root)->lchild, key);}else{return DeleteBST(&(*root)->rchild, key);} } //利用二叉樹插入操作,創建二叉排序樹 void CreateBST(BiTree *tree) {int num;printf("請輸入根節點數據:");scanf("%d", &num);*tree = malloc(sizeof(BiNode));(*tree)->data = num;(*tree)->lchild = (*tree)->rchild = NULL;while (1){printf("請輸入結點數據(-1結束):");scanf("%d", &num);if (num == -1){break;}InsertBST(*tree, num);} }int main(int argc, char *argv[]) {BiTree binarySortTree;//二叉排序樹CreateBST(&binarySortTree);int menu, key,ret;BiNode* node;while (1){printf("----菜單----------------\n");printf("----1.中序遍歷二叉排序樹\n");printf("----2.查找結點\n");printf("----3.插入結點\n");printf("----4.刪除結點\n");printf("----5.退出\n");scanf("%d", &menu);switch (menu){case 1:TraverseMid(binarySortTree);printf("\n");break;case 2:printf("請輸入key:");scanf("%d", &key);ret = SearchBST(binarySortTree, NULL, &node, key);ret == true ? printf("%d存在\n",key) : printf("%d不存在\n", key);break;case 3:printf("請輸入插入data:");scanf("%d", &key);ret = InsertBST(binarySortTree,key);ret == true ? printf("%d插入成功\n", key) : printf("%d插入失敗\n", key);break;case 4:printf("請輸入刪除data:");scanf("%d", &key);ret = DeleteBST(&binarySortTree,key);ret == true ? printf("%d刪除成功\n", key) : printf("%d刪除失敗\n", key);break;case 5:exit(0);}}return 0; }運行檢測
總結
以上是生活随笔為你收集整理的数据结构与算法——二叉排序树详解以及代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下c/c++实例之socket
- 下一篇: caffe新手常遇到的三个问题