#include<stdio.h>
#include<stdlib.h>
#include<string.h>
static int arr[]= {1,5,4,3,2,6};
#define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )
/*
二叉查找树的节点包含的基本信息:
(01) key -- 它是关键字,是用来对二叉查找树的节点进行排序的。
(02) left -- 它指向当前节点的左孩子。
(03) right -- 它指向当前节点的右孩子。
(04) parent -- 它指向当前节点的父结点。
*/
typedef struct treeNode
{
int key;
struct treeNode *left;
struct treeNode *right;
struct treeNode *parent;
}treeNode_t;
treeNode_t* creat_tree(int key, treeNode_t *left, treeNode_t *right, treeNode_t *parent)
{
treeNode_t* pnode = malloc(sizeof(treeNode_t));
if (pnode)
{
pnode->key = key;
pnode->left = left;
pnode->right = right;
pnode->parent = parent;
return pnode;
}
return NULL;
}
/*
前序遍历
若二叉树非空,则执行以下操作:
(01) 访问根结点;
(02) 先序遍历左子树;
(03) 先序遍历右子树。
*/
void preorder_bstree(treeNode_t *tree)
{
if(tree != NULL)
{
printf("%d ", tree->key);
preorder_bstree(tree->left);
preorder_bstree(tree->right);
}
}
/*
中序遍历
若二叉树非空,则执行以下操作:
(01) 中序遍历左子树;
(02) 访问根结点;
(03) 中序遍历右子树。
*/
void inorder_bstree(treeNode_t *tree)
{
if(tree != NULL)
{
inorder_bstree(tree->left);
printf("%d ", tree->key);
inorder_bstree(tree->right);
}
}
/*
后序遍历
若二叉树非空,则执行以下操作:
(01) 后序遍历左子树;
(02) 后序遍历右子树;
(03) 访问根结点。
*/
void postorder_bstree(treeNode_t *tree)
{
if(tree != NULL)
{
postorder_bstree(tree->left);
postorder_bstree(tree->right);
printf("%d ", tree->key);
}
}
/*
递归查找
*/
treeNode_t* bstree_search(treeNode_t *x, int key)
{
if (x==NULL || x->key==key)
return x;
if (key < x->key)
return bstree_search(x->left, key);
else
return bstree_search(x->right, key);
}
/*
查找
*/
treeNode_t* iterative_bstree_search(treeNode_t *x, int key)
{
while ((x!=NULL) && (x->key!=key))
{
if (key < x->key)
x = x->left;
else
x = x->right;
}
return x;
}
/*
最大值查找
*/
treeNode_t* bstree_maximum(treeNode_t *tree)
{
if (tree == NULL)
return NULL;
while(tree->right != NULL)
tree = tree->right;
return tree;
}
/*
最小值查找
*/
treeNode_t* bstree_minimum(treeNode_t *tree)
{
if (tree == NULL)
return NULL;
while(tree->left != NULL)
tree = tree->left;
return tree;
}
/*
节点的前驱:是该节点的左子树中的最大节点。
节点的后继:是该节点的右子树中的最小节点。
*/
treeNode_t* bstree_predecessor(treeNode_t *x)
{
// 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
if (x->left != NULL)
return bstree_maximum(x->left);
// 如果x没有左孩子。则x有以下两种可能:
// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
// (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
treeNode_t* y = x->parent;
while ((y!=NULL) && (x==y->left))
{
x = y;
y = y->parent;
}
return y;
}
treeNode_t* bstree_successor(treeNode_t *x)
{
// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if (x->right != NULL)
return bstree_minimum(x->right);
// 如果x没有右孩子。则x有以下两种可能:
// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
treeNode_t* y = x->parent;
while ((y!=NULL) && (x==y->right))
{
x = y;
y = y->parent;
}
return y;
}
static treeNode_t* bstree_insert(treeNode_t *tree, treeNode_t *z)
{
treeNode_t *y = NULL;
treeNode_t *x = tree;
// 查找z的插入位置
while (x != NULL)
{
y = x;
#if 1
//允许相同key
if (z->key < x->key)
x = x->left;
else
x = x->right;
#else
if (z->key < x->key)
x = x->left;
else if (z->key > x->key)
x = x->right;
else
{
free(z); // 释放之前分配的系统。
return tree;
}
#endif
}
z->parent = y;
if (y==NULL)
tree = z;
else if (z->key < y->key)
y->left = z;
else
y->right = z;
return tree;
}
treeNode_t* insert_bstree(treeNode_t *tree, int key)
{
treeNode_t *z; // 新建结点
// 如果新建结点失败,则返回。
if ((z=creat_tree(key, NULL, NULL, NULL)) == NULL)
return tree;
return bstree_insert(tree, z);
}
static treeNode_t* bstree_delete(treeNode_t *tree, treeNode_t *z)
{
treeNode_t *x=NULL;
treeNode_t *y=NULL;
if ((z->left == NULL) || (z->right == NULL))
y = z;
else
y = bstree_successor(z);
if (y->left != NULL)
x = y->left;
else
x = y->right;
if (x != NULL)
x->parent = y->parent;
if (y->parent == NULL)
tree = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
if (y != z)
z->key = y->key;
if (y!=NULL)
free(y);
return tree;
}
treeNode_t* delete_bstree(treeNode_t *tree, int key)
{
treeNode_t *z, *node;
if ((z = bstree_search(tree, key)) != NULL)
tree = bstree_delete(tree, z);
return tree;
}
void print_bstree(treeNode_t *tree, int key, int direction)
{
if(tree != NULL)
{
if(direction==0) // tree是根节点
printf("%2d is root\n", tree->key);
else // tree是分支节点
printf("%2d is %2d's %6s child\n", tree->key, key, direction==1?"right" : "left");
print_bstree(tree->left, tree->key, -1);
print_bstree(tree->right,tree->key, 1);
}
}
void destroy_bstree(treeNode_t *tree)
{
if (tree==NULL)
return ;
if (tree->left != NULL)
destroy_bstree(tree->left);
if (tree->right != NULL)
destroy_bstree(tree->right);
free(tree);
}
int main(int argc, char*argv[])
{
int i, ilen;
treeNode_t * 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== 前序遍历: ");
preorder_bstree(root);
printf("\n== 中序遍历: ");
inorder_bstree(root);
printf("\n== 后序遍历: ");
postorder_bstree(root);
printf("\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);
printf("\n");
// 销毁二叉树
destroy_bstree(root);
return 1;
}