您的位置:首页 > 理论基础 > 数据结构算法

二叉查找树

2014-01-04 19:43 218 查看
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node *parent;
struct node *left;
struct node *right;
};

struct tree
{
struct node *root;
};

/* 创建一个结点 */
struct node *node_alloc(int val)
{
struct node *ret = (struct node *) malloc(sizeof(struct node));
ret->data        = val;
ret->parent      = NULL;
ret->left        = NULL;
ret->right       = NULL;
return ret;
}

/* 销毁一个结点 */
void node_dealloc(struct node *n)
{
n->parent = NULL;
n->left   = NULL;
n->right  = NULL;
free(n);
}

/* 销毁整个子树 */
void node_destroy(struct node *n)
{
if (n->left != NULL)
{
node_destroy(n->left);
}
if (n->right != NULL)
{
node_destroy(n->right);
}
node_dealloc(n);
}

/* 返回子树中最小的元素 */
struct node *node_minimum(struct node *n)
{
while (n->left != NULL)
{
n = n->left;
}
return n;
}

/* 返回子树中最大的元素 */
struct node *node_maximum(struct node *n)
{
while (n->right != NULL)
{
n = n->right;
}
return n;
}

/* 查找结点在中序遍历序列中的前趋 */
struct node *node_predecessor(struct node *n)
{
struct node *ret;

if (n->left != NULL)
{
return node_maximum(n->left);
}
else
{
ret = n->parent;
while (ret != NULL && ret->left == n)
{
n   = ret;
ret = n->parent;
}
}
return ret;
}

/* 查找结点在中序遍历序列中的后继 */
struct node *node_successor(struct node *n)
{
struct node *ret;

if (n->right != NULL)
{
return node_minimum(n->right);
}
else
{
ret = n->parent;
while (ret != NULL && ret->right == n)
{
n   = ret;
ret = n->parent;
}
}
return ret;
}

/* 输出子树的中序遍历序列 */
void node_inorder_traversal(struct node *n)
{
if (n->left != NULL)
{
node_inorder_traversal(n->left);
}
printf("%d ", n->data);
if (n->right != NULL)
{
node_inorder_traversal(n->right);
}
}

/* 插入 */
void tree_insert(struct tree *t, int val)
{
struct node *parent = NULL;
struct node *child  = t->root;

/* 查找应该插入的位置parent */
while (child != NULL)
{
parent = child;
if (val < child->data)
{
child = child->left;
}
else
{
child = child->right;
}
}

/* 如果parent == NULL说明为空树 */
if (parent == NULL)
{
t->root = node_alloc(val);
}
else
{
child = node_alloc(val);
child->parent = parent;
if (val < parent->data)
{
parent->left = child;
}
else
{
parent->right = child;
}
}
}

/* 删除 */
void tree_erase(struct tree *t, struct node *n)
{
struct node *del;
struct node *child;

if (n == NULL)
{
return;
}

/* 查找应该删除的结点del,del最多只有一个子结点 */
if (n->left == NULL || n->right == NULL)
{
del = n;
}
else
{
del = node_successor(n);
/* 若待删除的结点不为n,将待删除结点的数据赋给n */
n->data = del->data;
}

/* 调整子节点的父结点指针 */
if (del->left != NULL)
{
child = del->left;
}
else
{
child = del->right;
}
if (child != NULL)
{
child->parent = del->parent;
}

/* 若父结点为NULL,说明待删除的结点为树的根结点,此时需要重新调整树的根结点 */
if (del->parent == NULL)
{
t->root = child;
}
/* 调整父结点的子结点指针 */
else if (del->parent->left == del)
{
del->parent->left = child;
}
else
{
del->parent->right = child;
}

/* 销毁结点 */
node_dealloc(del);
}

/* 查找,返回中序遍历序列中第一个匹配的 */
struct node *tree_search(struct tree *t, int val)
{
struct node *ret = t->root;

while (ret != NULL)
{
if (val == ret->data)
{
break;
}
else if (val < ret->data)
{
ret = ret->left;
}
else
{
ret = ret->right;
}
}
return ret;
}

/* 树结构初始化 */
void tree_init(struct tree *t)
{
t->root = NULL;
}

/* 销毁整棵树 */
void tree_destroy(struct tree *t)
{
if (t->root != NULL)
{
node_destroy(t->root);
t->root = NULL;
}
}

/* 输出树的中序遍历序列 */
void tree_inorder_traversal(struct tree *t)
{
if (t->root != NULL)
{
node_inorder_traversal(t->root);
printf("\n");
}
}

int main(void)
{
struct tree t;
struct node *n;

tree_init(&t);

tree_insert(&t, 1);
tree_insert(&t, 2);
tree_insert(&t, 3);
tree_insert(&t, 4);
tree_insert(&t, 5);
tree_inorder_traversal(&t);

n = tree_search(&t, 1);
tree_erase(&t, n);
tree_inorder_traversal(&t);
n = tree_search(&t, 3);
tree_erase(&t, n);
tree_inorder_traversal(&t);
n = tree_search(&t, 4);
tree_erase(&t, n);
tree_inorder_traversal(&t);

tree_destroy(&t);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息