BSTree.h
/** * 二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree) * 在二叉查找树中: * (01) 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; * (02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; * (03) 任意节点的左、右子树也分别为二叉查找树。 * (04) 没有键值相等的节点(no duplicate nodes)。 */
#pragma once
typedef int Type;
typedef struct BSTreeNode
{
Type key;
struct BSTreeNode *left;
struct BSTreeNode *right;
struct BSTreeNode *parent;
}Node, *BSTree;
// 前序遍历二叉树(递归) 根->左->右
void PreOrder_BSTree(BSTree root);
// 中序遍历二叉树(递归) 左->根->右
void InOrder_BSTree(BSTree root);
// 后序遍历二叉树(递归) 左->右->根
void PostOrder_BSTree(BSTree root);
// 递归查找二叉树中键值为key的节点
Node* BSTree_Search(BSTree root, Type key);
// 非递归查找二叉树中键值为key的节点
Node* BSTree_Search_Non_Recursion(BSTree root, Type key);
// 查找值最大节点
Node* BSTree_Maximum(BSTree root);
// 查找值最小节点
Node* BSTree_Minimum(BSTree root);
// 找结点(node)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
Node* BSTree_Successor(Node *node);
// 找结点(node)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
Node* BSTree_Predecessor(Node *node);
// 将数据插入二叉查找树,并返回根节点
Node* Insert_BSTree(BSTree root, Type key);
// 删除值为key的节点,并返回根节点
Node *Delete_BSTree(BSTree root, Type key);
// 销毁二叉树
void Destory_BSTree(BSTree root);
// 打印二叉树
void Print_BSTree(BSTree node, Type key, int direction);
BSTree.c
#include <stdio.h>
#include <stdlib.h>
#include <BSTree.h>
// 处理二叉树节点
static void ProcessCurrNode(BSTree root)
{
printf("%d ", root->key);
}
// 前序遍历二叉树(递归) 根->左->右
void PreOrder_BSTree(BSTree root)
{
if (root != NULL)
{
// Do Something with root
ProcessCurrNode(root);
PreOrder_BSTree(root->left);
PreOrder_BSTree(root->right);
}
}
// 中序遍历二叉树(递归) 左->根->右
void InOrder_BSTree(BSTree root)
{
if (root != NULL)
{
InOrder_BSTree(root->left);
// Do Something with root
ProcessCurrNode(root);
InOrder_BSTree(root->right);
}
}
// 后序遍历二叉树(递归) 左->右->根
void PostOrder_BSTree(BSTree root)
{
if (root != NULL)
{
PostOrder_BSTree(root->left);
PostOrder_BSTree(root->right);
// Do Something with root
ProcessCurrNode(root);
}
}
// 递归查找二叉树中键值为key的节点
Node* BSTree_Search(BSTree root, Type key)
{
if (root == NULL || root->key == key)
return root;
if (key < root->key)
return BSTree_Search(root->left, key);
else
return BSTree_Search(root->right, key);
}
// 非递归查找二叉树中键值为key的节点
Node* BSTree_Search_Non_Recursion(BSTree root, Type key)
{
while (root != NULL && root->key != key)
{
if (key < root->key)
root = root->left;
else
root = root->right;
}
return root;
}
// 查找值最大节点
Node* BSTree_Maximum(BSTree root)
{
if (root == NULL)
return NULL;
while (root->right != NULL)
root = root->right;
return root;
}
// 查找值最小节点
Node* BSTree_Minimum(BSTree root)
{
if (root == NULL)
return NULL;
while (root->left != NULL)
root = root->left;
return root;
}
// 找结点(node)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
Node* BSTree_Successor(Node *node)
{
// 如果node存在右孩子,则后继节点为右孩子中的最小节点。
if (node->right != NULL)
return BSTree_Minimum(node->right);
// 如果node不存在右孩子。则有两种情况:
// (01) node是一个左孩子,则node的后继节点为它的父节点;
// (02) node是一个右孩子,则查找"node的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"node的后继结点"。
Node *p = node->parent;
while (p != NULL && node == p->right)
{
node = p;
p = p->parent;
}
return p;
}
// 找结点(node)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
Node* BSTree_Predecessor(Node *node)
{
// 如果node存在左孩子,则前驱节点为左孩子中的最大节点
if (node->left != NULL)
return BSTree_Maximum(node->left);
// 如果node不存在左孩子,则有两种情况:
// (01) node是一个右孩子,则node的前驱节点是的它的父节点;
// (02) node是一个左孩子,则查找"node的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"node的前驱结点"。
Node *p = node->parent;
while (p != NULL && node == p->left)
{
node = p;
p = p->parent;
}
return p;
}
// 创建树节点
static Node* Create_BSTree_Node(Type key, Node *parent, Node *left, Node* right)
{
Node *p = (Node*)malloc(sizeof(Node));
if (p == NULL)
return NULL;
p->key = key;
p->parent = parent;
p->left = left;
p->right = right;
return p;
}
/** * 内部函数: * * 二叉树中插入节点 * * 参数: * root 根节点 * node 要插入的节点 * 返回值: * 根节点 */
static Node* BSTree_Insert(BSTree root, Node *insnode)
{
Node *p = NULL;
Node *tmp = root;
while (tmp != NULL)
{
p = tmp;
if (insnode->key < p->key)
tmp = p->left;
else
tmp = p->right;
}
insnode->parent = p;
// p为NULL,则root为NULL
if (p == NULL)
root = insnode;
else if (insnode->key < p->key)
p->left = insnode;
else
p->right = insnode;
return root;
}
/** * 对外接口 * * 新建节点,并将其二叉树中插入节点 * * 参数: * root 根节点 * key 要插入的值 * 返回值: * 根节点 */
Node* Insert_BSTree(BSTree root, Type key)
{
//新建节点
Node* node = Create_BSTree_Node(key, NULL, NULL, NULL);
if (node == NULL)
return root;
return BSTree_Insert(root, node);
}
/** * 内部函数: * * 二叉树中删除节点 * * 参数: * root 根节点 * node 要删除的节点 * 返回值: * 根节点 */
static Node* BSTree_Delete(BSTree root, Node *delnode)
{
Node *p = NULL;
Node *c = NULL;
if (delnode->left == NULL || delnode->right == NULL)
p = delnode;
else
p = BSTree_Successor(delnode); //选择后继节点与当前节点的值互换,删除后继节点
if (p->left != NULL)
c = p->left;
else
c = p->right;
if (c != NULL)
c->parent = p->parent;
if (p->parent == NULL)
root = c;
else if (p == p->parent->left)
p->parent->left = c;
else
p->parent->right = c;
if (p != delnode)
delnode->key = p->key;
if (p != NULL)
free(p);
p = NULL;
return root;
}
/** * 对外接口 * * 删除节点,并返回根节点 * * 参数: * root 根节点 * key 删除的值 * 返回值: * 根节点 */
Node *Delete_BSTree(BSTree root, Type key)
{
Node *delnode = BSTree_Search(root, key);
if (delnode != NULL)
root = BSTree_Delete(root, delnode);
return root;
}
// 销毁二叉树
void Destory_BSTree(BSTree root)
{
if (root == NULL)
return;
if (root->left != NULL)
Destory_BSTree(root->left);
if (root->right != NULL)
Destory_BSTree(root->right);
free(root);
}
/** * * 打印二叉树 * * 参数: * root : 二叉树节点 * key : 节点的值 * direction : 0 根节点 * -1 左孩子 * 1 右孩子 */
void Print_BSTree(BSTree node, Type key, int direction)
{
if (node != NULL)
{
if (direction == 0)
printf("%d is root\n", key);
else
printf("%d is %d`s %s child\n", node->key, key, direction == -1 ? "left" : "right");
Print_BSTree(node->left, node->key, -1);
Print_BSTree(node->right, node->key, 1);
}
}
BSTree_Test.c
#include <stdio.h>
#include <BSTree.h>
static int arr[] = { 1,5,4,3,2,6 };
#define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )
void main()
{
int i, ilen;
BSTree root = NULL;
printf("== 依次添加: ");
ilen = TBL_SIZE(arr);
for (i = 0; i < ilen; i++)
{
printf("%d ", arr[i]);
root = Insert_BSTree(root, arr[i]);
}
printf("\n");
printf("\n== 前序遍历: ");
PreOrder_BSTree(root);
printf("\n== 中序遍历: ");
InOrder_BSTree(root);
printf("\n== 后续遍历: ");
PostOrder_BSTree(root);
printf("\n\n");
printf("== 最小值: %d\n", BSTree_Minimum(root)->key); printf("== 最大值: %d\n", BSTree_Maximum(root)->key); printf("== 树的详细信息: \n"); Print_BSTree(root, root->key, 0); printf("\n== 删除节点: %d", arr[3]); root = Delete_BSTree(root, arr[3]); printf("\n== 中序遍历: "); InOrder_BSTree(root); Destory_BSTree(root); printf("\n\n"); system("pause"); }
测试结果
参考:http://wangkuiwu.github.io/2013/02/01/bstree-c/