二叉排序树(Binary Sort Tree) 又称为二叉查找树(Binary Search Tree) - (代码、分析)
生活随笔
收集整理的這篇文章主要介紹了
二叉排序树(Binary Sort Tree) 又称为二叉查找树(Binary Search Tree) - (代码、分析)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄:
- 代碼:
- 分析:
代碼:
BSTree.h
#ifndef _BSTREE_H_ #define _BSTREE_H_typedef void BSTree;//定義二叉樹類型 typedef void BSKey;//定義節(jié)點(diǎn)的鍵值類型(用于節(jié)點(diǎn)排序)typedef struct _tag_BSTreeNode BSTreeNode;//定義二叉樹節(jié)點(diǎn)類型 struct _tag_BSTreeNode {BSKey* key;//鍵值BSTreeNode* left;//左子節(jié)點(diǎn)BSTreeNode* right;//右子節(jié)點(diǎn) };typedef void (BSTree_Printf)(BSTreeNode*);//定義參數(shù)為一個(gè)節(jié)點(diǎn)指針并且無返回值的函數(shù)類型 typedef int (BSTree_Compare)(BSKey*, BSKey*);//定義參數(shù)為兩個(gè)鍵值指針并且無返回值的函數(shù)類型BSTree* BSTree_Create();//聲明創(chuàng)建樹函數(shù)void BSTree_Destroy(BSTree* tree);//聲明銷毀樹函數(shù)void BSTree_Clear(BSTree* tree);//聲明清空樹函數(shù)int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* compare);//聲明插入節(jié)點(diǎn)函數(shù)BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key, BSTree_Compare* compare);//聲明刪除節(jié)點(diǎn)函數(shù)BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* compare);//聲明獲取節(jié)點(diǎn)函數(shù)BSTreeNode* BSTree_Root(BSTree* tree);//聲明獲取根節(jié)點(diǎn)函數(shù)int BSTree_Height(BSTree* tree);//聲明獲取樹高度函數(shù)int BSTree_Count(BSTree* tree);//聲明獲取節(jié)點(diǎn)數(shù)量函數(shù)int BSTree_Degree(BSTree* tree);//聲明獲取樹度數(shù)函數(shù)void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div);//定義統(tǒng)一用函數(shù)處理節(jié)點(diǎn)函數(shù)#endifBSTree.c
#include <stdio.h> #include <malloc.h> #include "BSTree.h"typedef struct _tag_BSTree TBSTree;//定義實(shí)際使用二叉樹類型 struct _tag_BSTree {int count;//數(shù)量BSTreeNode* root;//根節(jié)點(diǎn) }; //用遞歸調(diào)用函數(shù)處理節(jié)點(diǎn)函數(shù) static void recursive_display(BSTreeNode* node, BSTree_Printf* pFunc, int format, int gap, char div) // O(n) {int i = 0;if( (node != NULL) && (pFunc != NULL) ){for(i=0; i<format; i++){printf("%c", div);}pFunc(node);printf("\n");if( (node->left != NULL) || (node->right != NULL) ){recursive_display(node->left, pFunc, format + gap, gap, div);recursive_display(node->right, pFunc, format + gap, gap, div);}}else{for(i=0; i<format; i++){printf("%c", div);}printf("\n");} }static int recursive_count(BSTreeNode* root) //遞歸計(jì)算節(jié)點(diǎn)數(shù)量函數(shù)(沒使用到) {int ret = 0;if( root != NULL ){ret = recursive_count(root->left) + 1 + recursive_count(root->right);}return ret; }static int recursive_height(BSTreeNode* root) // 遞歸計(jì)算高度函數(shù) {int ret = 0;if( root != NULL ){int lh = recursive_height(root->left);int rh = recursive_height(root->right);ret = ((lh > rh) ? lh : rh) + 1;}return ret; }static int recursive_degree(BSTreeNode* root) //遞歸計(jì)算度數(shù)函數(shù) {int ret = 0;if( root != NULL ){if( root->left != NULL ){ret++;}if( root->right != NULL ){ret++;}if( ret == 1 ){int ld = recursive_degree(root->left);int rd = recursive_degree(root->right);if( ret < ld ){ret = ld;}if( ret < rd ){ret = rd;}}}return ret; }static int recursive_insert(BSTreeNode* root, BSTreeNode* node, BSTree_Compare* compare) {int ret = 1;int r = compare(node->key, root->key);//1參數(shù)小于2參數(shù)返回負(fù)數(shù),大于返回正數(shù),等于返回0if( r == 0 )//如果兩個(gè)鍵相等插入結(jié)果等于0返回到調(diào)用函數(shù),表示插入失敗{ret = 0;}else if( r < 0 )//如果插入節(jié)點(diǎn)的鍵小于當(dāng)前比較的節(jié)點(diǎn)的鍵,表示應(yīng)該是往當(dāng)前比較的節(jié)點(diǎn)的左子節(jié)點(diǎn)走{if( root->left != NULL )//如果當(dāng)前比較的節(jié)點(diǎn)的左子節(jié)點(diǎn)不為空{//將其左子節(jié)點(diǎn)作為下一個(gè)與插入節(jié)點(diǎn)比較的節(jié)點(diǎn)再調(diào)用函數(shù)進(jìn)棧,是否插入成功結(jié)果返回這里ret = recursive_insert(root->left, node, compare);}else{//否則直接將插入節(jié)點(diǎn)作為當(dāng)前比較節(jié)點(diǎn)的左子節(jié)點(diǎn)root->left = node;}}else if( r > 0 )//如果插入節(jié)點(diǎn)的鍵小于當(dāng)前比較根節(jié)點(diǎn)的鍵,表示應(yīng)該是往當(dāng)前比較根節(jié)點(diǎn)的右子節(jié)點(diǎn)走{if( root->right != NULL )//如果當(dāng)前比較的節(jié)點(diǎn)的右子節(jié)點(diǎn)不為空{//將其右子節(jié)點(diǎn)作為下一個(gè)與插入節(jié)點(diǎn)比較的節(jié)點(diǎn)再調(diào)用函數(shù)進(jìn)棧,是否插入成功結(jié)果返回這里ret = recursive_insert(root->right, node, compare);}else{//否則直接將插入節(jié)點(diǎn)作為當(dāng)前比較節(jié)點(diǎn)的右子節(jié)點(diǎn)root->right = node;}}return ret;//將結(jié)果返回 }static BSTreeNode* recursive_get(BSTreeNode* root, BSKey* key, BSTree_Compare* compare)//遞歸查找節(jié)點(diǎn)函數(shù) {BSTreeNode* ret = NULL;if( root != NULL ){int r = compare(key, root->key);if( r == 0 ){ret = root;}else if( r < 0 ){ret = recursive_get(root->left, key, compare);}else if( r > 0 ){ret = recursive_get(root->right, key, compare);}}return ret; }static BSTreeNode* delete_node(BSTreeNode** pRoot)//進(jìn)行刪除節(jié)點(diǎn)函數(shù) {BSTreeNode* ret = *pRoot;//取得要?jiǎng)h除節(jié)點(diǎn)地址if( (*pRoot)->right == NULL )//如果刪除節(jié)點(diǎn)的右子節(jié)點(diǎn)等于空{*pRoot = (*pRoot)->left;//將刪除節(jié)點(diǎn)的左子節(jié)點(diǎn)賦到本來指向刪除節(jié)點(diǎn)的指針}else if( (*pRoot)->left == NULL )//如果刪除節(jié)點(diǎn)的左子節(jié)點(diǎn)等于空{*pRoot = (*pRoot)->right;//將刪除節(jié)點(diǎn)的右子節(jié)點(diǎn)賦到本來指向刪除節(jié)點(diǎn)的指針}else//否則表示左右子節(jié)點(diǎn)都不為空{BSTreeNode* g = *pRoot;//取得要?jiǎng)h除節(jié)點(diǎn)地址BSTreeNode* c = (*pRoot)->left;//取得要?jiǎng)h除節(jié)點(diǎn)的左子節(jié)點(diǎn)地址//從刪除節(jié)點(diǎn)左子節(jié)點(diǎn)開始找出一個(gè)鍵與刪除節(jié)點(diǎn)鍵最接近的節(jié)點(diǎn),作為刪除節(jié)點(diǎn)的那個(gè)位置//因?yàn)閺膭h除節(jié)點(diǎn)的左子節(jié)點(diǎn)開始,所以它的右子節(jié)點(diǎn)一直沿伸的節(jié)點(diǎn)的鍵是最接近刪除節(jié)點(diǎn)的//c用于指向作為替換到刪除節(jié)點(diǎn)位置的節(jié)點(diǎn) g是c的父節(jié)點(diǎn)while( c->right != NULL )//從刪除節(jié)點(diǎn)的左子節(jié)點(diǎn)往右查找,找到右節(jié)點(diǎn)為空的節(jié)點(diǎn){g = c;//更新位置c = c->right;//更新下一個(gè)檢測(cè)的位置}if( g != *pRoot )//g不等于刪除節(jié)點(diǎn),表示找到合適的節(jié)點(diǎn){//因?yàn)閏要替換到刪除節(jié)點(diǎn)的位置,這時(shí)c節(jié)點(diǎn)只有左子節(jié)點(diǎn)(有指向或NULL)需要處理連接的,//因?yàn)閏的右子節(jié)點(diǎn)確保為NULL了,經(jīng)過上面的查找,再將c父節(jié)點(diǎn)的本來指向c節(jié)點(diǎn)的右子節(jié)點(diǎn)//指向c的左子節(jié)點(diǎn),而且c的左子節(jié)點(diǎn)鍵肯定大于c的父節(jié)點(diǎn)所以是c的父節(jié)點(diǎn)的右子節(jié)點(diǎn)//相當(dāng)替換了c節(jié)點(diǎn)原來的位置g->right = c->left;}else//否則表示刪除節(jié)點(diǎn)的左子節(jié)點(diǎn)就是合適替換到刪除節(jié)點(diǎn)位置的節(jié)點(diǎn){//直接將刪除節(jié)點(diǎn)的左子節(jié)點(diǎn)等于c的左子節(jié)點(diǎn),這里就只有c左子節(jié)點(diǎn)有指向的g->left = c->left;}c->left = (*pRoot)->left;//將刪除節(jié)點(diǎn)本來的左子節(jié)點(diǎn)部分賦給c節(jié)點(diǎn)左子節(jié)點(diǎn)c->right = (*pRoot)->right;//將刪除節(jié)點(diǎn)本來的右子節(jié)部分賦給c節(jié)點(diǎn)的右子節(jié)點(diǎn)*pRoot = c;//把c節(jié)點(diǎn)更新到原來刪除節(jié)點(diǎn)的指針位置}return ret;//返回刪除節(jié)點(diǎn) }static BSTreeNode* recursive_delete(BSTreeNode** pRoot, BSKey* key, BSTree_Compare* compare) {BSTreeNode* ret = NULL;if( (pRoot != NULL) && (*pRoot != NULL) )//比較節(jié)點(diǎn)指針地址與指向不為空{ //將當(dāng)前節(jié)點(diǎn)與key值進(jìn)行比較等于0表示找到了,小于表示應(yīng)該往當(dāng)前節(jié)點(diǎn)左子節(jié)點(diǎn)查找,大于往右子節(jié)點(diǎn)查找int r = compare(key, (*pRoot)->key);if( r == 0 )//找到后調(diào)用刪除節(jié)點(diǎn)函數(shù)進(jìn)行刪除{//注意:pRoot不是當(dāng)前節(jié)點(diǎn)地址,是指向要?jiǎng)h除節(jié)點(diǎn)的節(jié)點(diǎn)指針的地址(也就是樹的根節(jié)點(diǎn)指針地址或是上一個(gè)節(jié)點(diǎn)的左子節(jié)點(diǎn)指針或右子節(jié)點(diǎn)指針地址)ret = delete_node(pRoot);//將節(jié)點(diǎn)指針地址作為參數(shù)進(jìn)行刪除操作}else if( r < 0 ){//將當(dāng)前節(jié)點(diǎn)的左子節(jié)點(diǎn)指針地址調(diào)用函數(shù)繼續(xù)查找ret = recursive_delete(&((*pRoot)->left), key, compare);}else if( r > 0 ){//將當(dāng)前節(jié)點(diǎn)的右子節(jié)點(diǎn)指針地址調(diào)用函數(shù)繼續(xù)查找ret = recursive_delete(&((*pRoot)->right), key, compare);}}return ret; }BSTree* BSTree_Create() // 定義創(chuàng)建樹函數(shù) {TBSTree* ret = (TBSTree*)malloc(sizeof(TBSTree));if( ret != NULL ){ret->count = 0;ret->root = NULL;}return ret; }void BSTree_Destroy(BSTree* tree) // 定義銷毀樹函數(shù) {free(tree); }void BSTree_Clear(BSTree* tree) // 定義清空樹函數(shù) {TBSTree* btree = (TBSTree*)tree;if( btree != NULL ){btree->count = 0;btree->root = NULL;} }int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* compare) //定義插入節(jié)點(diǎn)函數(shù) {TBSTree* btree = (TBSTree*)tree;//取得樹int ret = (btree != NULL) && (node != NULL) && (compare != NULL);//判斷參數(shù)不為空if( ret ){node->left = NULL;//將插入節(jié)點(diǎn)左子節(jié)點(diǎn)設(shè)空node->right = NULL;//將插入節(jié)點(diǎn)右子節(jié)點(diǎn)設(shè)空if( btree->root == NULL )//如果根節(jié)點(diǎn)等于空表示是第一個(gè)節(jié)點(diǎn){btree->root = node;}else{//調(diào)用遞歸檢測(cè)插入位置ret = recursive_insert(btree->root, node, compare);}if( ret )//如果插入成功{btree->count++;//節(jié)點(diǎn)數(shù)量增加}}return ret; }BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key, BSTree_Compare* compare)//定義刪除節(jié)點(diǎn)函數(shù) {TBSTree* btree = (TBSTree*)tree;//取得樹BSTreeNode* ret = NULL; if( (btree != NULL) && (key != NULL) && (compare != NULL) )//判斷參數(shù)不為空{ret = recursive_delete(&btree->root, key, compare);if( ret != NULL ){btree->count--;}}return ret; }BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* compare)//定義獲取節(jié)點(diǎn)函數(shù) {TBSTree* btree = (TBSTree*)tree;//取得樹BSTreeNode* ret = NULL; if( (btree != NULL) && (key != NULL) && (compare != NULL) )//判斷參數(shù)不為空{ret = recursive_get(btree->root, key, compare);//調(diào)用遞歸查找 }return ret;//返回獲取節(jié)點(diǎn) }BSTreeNode* BSTree_Root(BSTree* tree) // 定義獲取根節(jié)點(diǎn)函數(shù) {TBSTree* btree = (TBSTree*)tree;BSTreeNode* ret = NULL;if( btree != NULL ){ret = btree->root;}return ret; }int BSTree_Height(BSTree* tree) // 定義獲取樹高度函數(shù) {TBSTree* btree = (TBSTree*)tree;int ret = 0;if( btree != NULL ){ret = recursive_height(btree->root);//調(diào)用遞歸計(jì)算高度函數(shù)}return ret; }int BSTree_Count(BSTree* tree) // 定義獲取節(jié)點(diǎn)數(shù)量函數(shù) {TBSTree* btree = (TBSTree*)tree;int ret = 0;if( btree != NULL ){ret = btree->count;}return ret; }int BSTree_Degree(BSTree* tree) // 定義獲取樹度數(shù)函數(shù) {TBSTree* btree = (TBSTree*)tree;int ret = 0;if( btree != NULL ){ret = recursive_degree(btree->root);//調(diào)用遞歸計(jì)算度數(shù)函數(shù)}return ret; }void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div) //定義用統(tǒng)一函數(shù)處理節(jié)點(diǎn)函數(shù) {TBSTree* btree = (TBSTree*)tree;if( btree != NULL ){recursive_display(btree->root, pFunc, 0, gap, div);} }main.c
#include <stdio.h> #include <stdlib.h> #include "BSTree.h"struct Node {BSTreeNode header;char v; };void printf_data(BSTreeNode* node) {if( node != NULL ){printf("%c", ((struct Node*)node)->v);} }int compare_key(BSKey* k1, BSKey* k2) {return (int)k1 - (int)k2; }int main(int argc, char *argv[]) {BSTree* tree = BSTree_Create();struct Node n1 = {{(BSKey*)1, NULL, NULL}, 'A'};struct Node n2 = {{(BSKey*)2, NULL, NULL}, 'B'};struct Node n3 = {{(BSKey*)3, NULL, NULL}, 'C'};struct Node n4 = {{(BSKey*)4, NULL, NULL}, 'D'};struct Node n5 = {{(BSKey*)5, NULL, NULL}, 'E'};struct Node n6 = {{(BSKey*)6, NULL, NULL}, 'F'};BSTree_Insert(tree, (BSTreeNode*)&n4, compare_key);BSTree_Insert(tree, (BSTreeNode*)&n1, compare_key);BSTree_Insert(tree, (BSTreeNode*)&n3, compare_key);BSTree_Insert(tree, (BSTreeNode*)&n6, compare_key);BSTree_Insert(tree, (BSTreeNode*)&n2, compare_key);BSTree_Insert(tree, (BSTreeNode*)&n5, compare_key);printf("Height: %d\n", BSTree_Height(tree));printf("Degree: %d\n", BSTree_Degree(tree));printf("Count: %d\n", BSTree_Count(tree));printf("Search Key 5: %c\n", ((struct Node*)BSTree_Get(tree, (BSKey*)5, compare_key))->v);printf("Full Tree: \n");BSTree_Display(tree, printf_data, 4, '-');BSTree_Delete(tree, (BSKey*)4, compare_key);printf("After Delete Key 4: \n");printf("Height: %d\n", BSTree_Height(tree));printf("Degree: %d\n", BSTree_Degree(tree));printf("Count: %d\n", BSTree_Count(tree));printf("Full Tree: \n");BSTree_Display(tree, printf_data, 4, '-');BSTree_Clear(tree);printf("After Clear: \n");printf("Height: %d\n", BSTree_Height(tree));printf("Degree: %d\n", BSTree_Degree(tree));printf("Count: %d\n", BSTree_Count(tree));BSTree_Display(tree, printf_data, 4, '-');BSTree_Destroy(tree);getchar();return 0; }分析:
總結(jié)
以上是生活随笔為你收集整理的二叉排序树(Binary Sort Tree) 又称为二叉查找树(Binary Search Tree) - (代码、分析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别云剑无用适合红眼带吗?
- 下一篇: 哈希表 - (代码、分析 )