对于任意结点,左子树的所有结点值小于自身的值,右子树的所有结点值大于自身的值;
左右子树也是二叉查找树;
#include<stdio.h>
#include<stdlib.h>
typedef struct BSTreeNode {
int key;//关键值
BSTreeNode *left;//左孩子
BSTreeNode *right;//右孩子
BSTreeNode *parent;//父结点
}Node,BSTree;*
//创建一个结点
static Node create_bstree_node(int key, Node *parent, Node *left, Node right)
{
Node p=(Node)malloc(sizeof(Node));
if (p == NULL)
return NULL;
p->key = key;
p->left = left;
p->right = right;
p->parent = parent;
return p;
}
//三种遍历重点在于对于当前节点的操作在先、中还是后
//先序遍历
void preoder_bstree(BSTree tree)
{
if (tree != NULL)
{
printf("%d ", tree->key);
preoder_bstree(tree->left);
preoder_bstree(tree->right);
}
}
//中序遍历
void inorder_bstrss(BSTree tree)
{
if (tree != NULL)
{
inorder_bstrss(tree->left);
printf("%d ", tree->key);
inorder_bstrss(tree->right);
}
}
//后序遍历
void postorder_bstree(BSTree tree)
{
if (tree != NULL)
{
postorder_bstree(tree->left);
postorder_bstree(tree->right);
printf("%d ", tree->key);
}
}
//查找
//递归版
*Node bstree_search(BSTree x, int key)
{
if (x == NULL || x->key == key)
return x;
if (key < x->key)//根据bstrss的性质
return bstree_search(x->left, key);
else
return bstree_search(x->right, key);
}
//非递归版
Node iterative_bstree_search(BSTree x, int key)*
{
while ((x != NULL) && (x->key != key))
{
if (key < x->key)
x = x->left;
else
x = x->right;
}
return x;
}
//查找最值
Node bstree_maximum(BSTree tree)*
{
if (tree == NULL)
return NULL;
while (tree->right != NULL)
tree = tree->right;
return tree;
}
Node bstree_minimum(BSTree tree)*
{
if (tree == NULL)
return NULL;
while (tree->left != NULL)
tree = tree->left;
return tree;
}
//查找前驱和后继
Node bstree_predecessor(Node x)
{
//如果x存在左孩子,则x的前驱结点为以其左孩子为跟的子树的最大根节点
if (x->left != NULL)
return bstree_maximum(x->left);
//如果x没有左孩子,那么有两种情况
//(1)x是一个右孩子,则x的前驱就是它的父结点
//(2)x是一个左孩子,则查找x的最低父结点,且父结点要有右孩子
Node* y = x->parent;
while (y != NULL && x == y->left)//画图可知在找一个可能比x小的结点
{
x = y;
y = y->parent;
}
return y;
}
Node bstree_successor(Node x)
{
// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if (x->right != NULL)
return bstree_minimum(x->right);
// 如果x没有右孩子。则x有以下两种可能:
// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
Node y = x->parent;*
while ((y != NULL) && (x == y->right))
{
x = y;
y = y->parent;
}
return y;
}
//插入节点(建树),每次插入的都是叶子结点
static Node bstree_insert(BSTree tree, Node z)
{
Node *y = NULL;
Node *x = tree;
// 查找z的插入位置
while (x != NULL)
{
y = x;
if (z->key < x->key)
x = x->left;
else if (z->key > x->key)
x = x->right;
else
{
free(z); // 释放之前分配的系统,有相同的值
return tree;
}
}
z->parent = y;
if (y == NULL)
tree = z;
else if (z->key < y->key)
y->left = z;
else
y->right = z;
return tree;
}
Node insert_bstree(BSTree tree, int key)*
{
Node *z; // 新建结点
// 如果新建结点失败,则返回。
if ((z = create_bstree_node(key, NULL, NULL, NULL)) == NULL)
return tree;
return bstree_insert(tree, z);
}
static Node* bstree_delete(BSTree tree, Node z)
{
Node *x=NULL;
Node *y=NULL;
if ((z->left == NULL) || (z->right == NULL) )
y = z;//z左右子树不都有,直接在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;
}
Node delete_bstree(BSTree tree, Type key)*
{
Node *z, *node;
if ((z = bstree_search(tree, key)) != NULL)
tree = bstree_delete(tree, z);
return tree;
}