Binary Search Tree C语言实现
Posted createchance
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Binary Search Tree C语言实现相关的知识,希望对你有一定的参考价值。
Binary Search Tree是数据结构中比较有用的一种二叉树结构,这种结构讲大量的数据进行平摊式分布,并且规定大的数在右边,小的数在左边,以这种方式存放的数据可以非常方便地做数据排序和检索。
关于BST的更多信息,可以查看这个链接(英文,讲的非常好,不得不赞):http://algs4.cs.princeton.edu/32bst/
台湾国立清华大学韩永楷老师的MOOC(讲的超级棒,完爆国内,我的代码实现就是参考韩老师的课程内容):http://www.icourse163.org/course/NTHU-451013#/info
下面给出使用C语言的实现方式,我使用了最简单的方式实现,代码中有很多注释,大家可以参考。代码可编译,可运行。
/*************************************************************************
> File Name: bst.c
> Author: Baniel Gao
> Mail: createchance@163.com
> Created Time: Thu 01 Dec 2016 08:29:23 AM EST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct node_t
int key;
struct node_t* parent;
struct node_t* left;
struct node_t* right;
node;
/*
* Get min number of this tree pointed by root.
*
* Return min node pointer, NULL if root is NULL.
*/
node* min(node* root)
node* min_node = root;
if (root == NULL)
return NULL;
while (min_node->left != NULL)
min_node = min_node->left;
return min_node;
/*
* Get max number of this tree pointed by root.
*
* Return max node pointer, NULL if root is NULL.
*/
node* max(node* root)
node* max_node = root;
if (root == NULL)
return NULL;
while (max_node->right != NULL)
max_node = max_node->right;
return max_node;
/*
* Search the number k.
*
* Return node pointer which contains the key, NULL if do not match anything.
*/
node* search(node* root, int k)
node* current = root;
if (root == NULL)
return NULL;
while (1)
if (current->key == k)
break;
else if (current->key > k)
current = current->left;
else
current = current->right;
if (current == NULL)
break;
return current;
/*
* Find the predeccessor of k.
*
* Return node pointer of predeccessor if success, NULL if find nothing.
*/
node* predecessor(node* root, int k)
if (root == NULL)
return NULL;
node* target = search(root, k);
if (target != NULL)
if (target->left != NULL)
target = max(target->left);
else
while (1)
if (target->parent == NULL)
target = target->parent;
break;
else if (target == target->parent->right)
target = target->parent;
break;
else if (target == target->parent->left)
target = target->parent;
return target;
/*
* Find successor of number k.
*
* Return node pointer of successor if success, NULL if find nothing.
*/
node* successor(node* root, int k)
if (root == NULL)
return NULL;
node* target = search(root, k);
if (target != NULL)
if (target->right != NULL)
target = min(target->right);
else
while (1)
if (target->parent == NULL)
target = target->parent;
break;
else if (target == target->parent->left)
target = target->parent;
break;
else if (target == target->parent->right)
target = target->parent;
return target;
/*
* insert one number k to binary search tree.
*
* Return node pointer if success, NULL if key already exists.
*/
node* insert(node* root, int k)
node* current = root;
if (root == NULL)
root = (node*) malloc(sizeof(node));
root->key = k;
return root;
while (1)
if (current->key == k)
current = NULL;
break;
else if (current->key > k)
if (current->left != NULL)
current = current->left;
else
// no left child, so we are left child, create one node and insert.
node* new = (node*) malloc(sizeof(node));
new->key = k;
new->parent = current;
new->left = NULL;
new->right = NULL;
current->left = new;
// move current to target node.
current = current->left;
break;
else if (current->key < k)
if (current->right != NULL)
current = current->right;
else
// no right child, so we are left child, create one node and insert.
node* new = (node*) malloc(sizeof(node));
new->key = k;
new->parent = current;
new->left = NULL;
new->right = NULL;
current->right = new;
// move current to target node.
current = current->right;
break;
return current;
/*
* Delete node contains number k.
*
* Return 0 if succeed, -1 if number k not found or tree root is NULL, 1 if the tree is empty after deletion.
*/
int delete(node* root, int k)
if (root == NULL)
return -1;
// Find this node first.
node* target = search(root, k);
// Well, we can not find this node.
if (target == NULL)
return -1;
/* Case 1: this node is leaf node. */
if (target->left == NULL && target->right == NULL)
if (target != root)
if (target == target->parent->right)
target->parent->right = NULL;
else
target->parent->left = NULL;
else
root = NULL;
free(target);
/* Case 2: this node has only one child node. */
else if (target->left != NULL && target->right == NULL)
// Case 2.1: this node only has a left child.
if (target == root)
node* predecessor_node = predecessor(root, k);
if (predecessor_node == NULL)
return -1;
// Replace the number first.
target->key = predecessor_node->key;
// predecessor does not have any child.
if (predecessor_node->left == NULL && predecessor_node->right == NULL)
if (target->right == predecessor_node)
target->right = NULL;
else
predecessor_node->parent->left = NULL;
// predecessor only have left child.
else
predecessor_node->parent->right = predecessor_node->left;
predecessor_node->left->parent = predecessor_node->parent;
// Free predecessor node.
free(predecessor_node);
else
target->left->parent = target->parent;
if (target == target->parent->left)
target->parent->left = target->left;
else
target->parent->right = target->left;
else if (target->left == NULL && target->right != NULL)
// Case 2.2: this node only has a right child.
if (target == root)
node* successor_node = successor(root, k);
if (successor_node == NULL)
return -1;
// Replace the number first.
target->key = successor_node->key;
// successor does not have any child.
if (successor_node->left == NULL && successor_node->right == NULL)
if (target->right == successor_node)
target->right = NULL;
else
successor_node->parent->left = NULL;
// successor only have right child.
else
successor_node->parent->left = successor_node->right;
successor_node->right->parent = successor_node->parent;
// Free successor node.
free(successor_node);
else
target->right->parent = target->parent;
if (target == target->parent->left)
target->parent->left = target->right;
else
target->parent->right = target->right;
/* Case 3: this node has two child node. */
else if (target->left != NULL && target->right != NULL)
node* successor_node = successor(root, k);
if (successor_node == NULL)
return -1;
// Replace the number first.
target->key = successor_node->key;
// Case 3.1: successor does not have any child.
if (successor_node->left == NULL && successor_node->right == NULL)
if (target->right == successor_node)
target->right = NULL;
else
successor_node->parent->left = NULL;
// Case 3.2: successor only have right child.
else
successor_node->parent->left = successor_node->right;
successor_node->right->parent = successor_node->parent;
// Free successor node.
free(successor_node);
if (root == NULL)
return 1;
return 0;
/*
* Modify one node'key. Change it from src to dst.
*
* Return the node modified, NULL if this node does not exist.
*/
node* modify(node* root, int src, int dst)
if (root == NULL)
return NULL;
// We have to make sure the src exists and dst does not exist.
node* source = search(root, src);
node* destination = search(root, dst);
if (source == NULL)
printf("The source number %d does not exist. \\n", src);
return NULL;
if (destination != NULL)
printf("The destination number %d already exist. \\n", dst);
return NULL;
// we delete the old node first.
delete(root, src);
// then insert new node.
insert(root, dst);
return source;
/*
* Print this tree by inorder.
*
* The numbers printed is sorted.
*/
void print_tree_inorder(node* root)
if(root != NULL)
print_tree_inorder(root->left);
printf("%d ",root->key);
print_tree_inorder(root->right);
/*
* Console helper function.
*/
void show_help()
printf("1. insert\\n");
printf("2. delete\\n");
printf("3. modify\\n");
printf("4. search\\n");
printf("5. predeccessor\\n");
printf("6. successor\\n");
printf("7. min\\n");
printf("8. max\\n");
printf("9. print tree\\n");
int main()
char cmd;
int key, key2;
node* root = NULL;
printf("This is a binary search tree demo.\\n");
while (1)
printf("Command<m for help>: ");
fflush(stdout);
scanf("%c", &cmd);
if (cmd == 'm')
show_help();
else if (cmd == '1')
printf("Input number to insert: ");
fflush(stdout);
scanf("%d", &key);
node* inserted_node = insert(root, key);
if (root == NULL)
root = inserted_node;
if (inserted_node == NULL)
printf("The number %d already exist. \\n", key);
else
printf("Complete!\\n");
else if (cmd == '2')
printf("Input number to delete: ");
fflush(stdout);
scanf("%d", &key);
int ret = delete(root, key);
if (ret < 0)
printf("The numnber %d does not exist. \\n", key);
else if (ret == 1)
printf("The tree is empty now. \\n");
root = NULL;
else
printf("Complete!\\n");
else if (cmd == '3')
printf("Input the number you want to change from and to: ");
fflush(stdout);
scanf("%d %d", &key, &key2);
node* modified_node = modify(root, key, key2);
if (modified_node == NULL)
printf("Modify failed. \\n");
else
printf("Complete!\\n");
else if (cmd == '4')
printf("Input the number you want to search: ");
fflush(stdout);
scanf("%d", &key);
node* result = search(root, key);
if (result == NULL)
printf("The number %d does not exist.\\n", key);
else
printf("Complete!\\n");
else if (cmd == '5')
printf("Input the number you want to find predecessor: ");
fflush(stdout);
scanf("%d", &key);
node* result = predecessor(root, key);
if (result == NULL)
printf("Predecessor do not found!\\n");
else
printf("Predecessor is %d. \\n", result->key);
else if (cmd == '6')
printf("Input the number you want to find successor: ");
fflush(stdout);
scanf("%d", &key);
node* result = successor(root, key);
if (result == NULL)
printf("Successor do not found!\\n");
else
printf("Successor is %d. \\n", result->key);
else if (cmd == '7')
node* result = min(root);
if (result != NULL)
printf("Min number is: %d. \\n", result->key);
else
printf("This tree is empty! \\n");
else if (cmd == '8')
node* result = max(root);
if (result != NULL)
printf("Max number is: %d. \\n", result->key);
else
printf("This tree is empty! \\n");
else if (cmd == '9')
if (root != NULL)
print_tree_inorder(root);
printf("\\n");
else
printf("This tree is empty! \\n");
getchar();
return 0;
上面程序支持9中操作:
1. insert:插入一个数据,如果当前bst为空,那么新建根节点,并且赋值
2. delete:删除一个数据,如果给定数字不存在,则删除失败
3. modify:修改一个数据,需要源数据存在,且目标数据不能存在
4. search:检索一个数据,如果数据存在成功返回,反之失败
5. predeccessor:检索一个数的前导数(这个数必须存在于树中),就是比目标数小的所有数的最大数
6. successor:检索一个数的后导数(这个数必须存在于数中),就是比目标数大的所有数的最小数
7. min:检索树中最小的数
8. max:检索树中最大的数
9. print tree:按照中序打印树,对于BST来说中序就是所有数的升序排序
分别输入以上操作前的序号,就可以对BST发起操作。运行如下图:
以上是关于Binary Search Tree C语言实现的主要内容,如果未能解决你的问题,请参考以下文章
[数据结构]10.2实现binary search tree的查找和插入操作,用非递归的方法实现
[LinkList/Tree]109. Convert Sorted List to Binary Search Tree
Convert Sorted Array to Binary Search Tree & Convert Sorted List to Binary Search Tree
LeetCode Closest Binary Search Tree Value