构造一颗二叉排序树的目的,其实并不是为了排序,而是为了提高查找和插入删除关键字的速度。不管怎么说,在一个有序数据集上的查找,速度总是要快于无序数据集的,而二叉排序树这种非线性的结构,也有利于插入和删除的实现。

二叉排序树的查找:

先查找其根节点,如果根节点的数据与data值相等,则返回该根节点;

否则, 如果data值大于根节点,则查询其右子树;

如果小于根节点,则查询其左子树。

pnode search(pnode root,int data)
{
pnode temp = root;
while(temp != NULL)
{
if(temp->data == data)
return temp;
else if(data < temp->data)
temp = temp->left;
else
temp = temp->right;
}
return NULL;
}

 

二叉排序树的删除:

二叉排序树的查找与删除_子树

pnode max_left_tree(pnode root)
{
pnode temp = root->left;//该结点的左子树
while (temp != NULL && temp->right != NULL)
{
temp = temp->right;
}
return temp;
}
pnode min_right_tree(pnode root)
{
pnode temp = root->right;//该结点的右子树
while (temp != NULL && temp->left != NULL)
{
temp = temp->left;
}
return temp;
}
void cut_link_from_tree(pnode node)
{
if (node->left == NULL && node->right == NULL)
{
if (node->parent->left == node)
node->parent->left = NULL;
else if(node->parent->right == node)
node->parent->right = NULL;
}
else
{
if (node->left != NULL)
node->parent->right = node->left;
else if (node->right != NULL)
node->parent->left = node->right;
}
}

pnode del_tree(pnode root, int data)
{
pnode res = search_tree(root, data);//查找到要删除的结点
pnode replace = NULL;
if (res == NULL)
{
printf("not has this data \n ");
return root;
}
//用该结点的左子数里的最大值或右子树的最小值来代替它
if (res->left != NULL)
{
replace = max_left_tree(res);
}
else if(res->right != NULL)
{
replace = min_right_tree(res);
}
else//若该删除的结点左子树和右子树都为空,则其为叶子结点,直接删除即可
{
if (res == root)
return NULL;
else
{
cut_link_from_tree(res);
free(res);
return root;
}
}
cut_link_from_tree(replace);
res->data = replace->data;//将数据替换即可
free(replace);
}

完整代码: 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//构造结点
typedef struct _node {
int data;
struct _node *parent;
struct _node *left;
struct _node *right;
}node,*pnode;
//申请一个结点
pnode construct_node(int data) {
pnode temp = (pnode)malloc(sizeof(node));
temp->data = data;
temp->left = temp->right = temp->parent = NULL;
return temp;
}
//添加结点(构建二插排序树)
pnode add_node(pnode root, pnode newnode) {
if (root == NULL)
return newnode;
pnode temp = root;
while (temp != NULL)
{
if (newnode->data < temp->data)
{
if (temp->left == NULL)
{
temp->left = newnode;
newnode->parent = temp;
return root;
}
else
temp = temp->left;
}
else
{
if (temp->right == NULL)
{
temp->right = newnode;
newnode->parent = temp;
return root;
}
else
temp = temp->right;
}

}
}
//访问根结点
void visit(pnode temp)
{
printf("%d ", temp->data);
}
//中序遍历(左-根-右)(中序相当于排序)
void inorder(pnode root)
{
if (root == NULL)
return;
pnode temp = root;
if (temp != NULL)
{
inorder(temp->left);//访问左子节点
visit(temp);//访问根结点
inorder(temp->right);//访问右子结点
}
}

//二叉排序树的查找
pnode search_tree(pnode root, int data)
{
pnode temp = root;
while (temp != NULL)
{
if (temp->data == data)
return temp;
else if (data < temp->data )
temp = temp->left;
else
temp = temp->right;
}
return NULL;
}

pnode max_left_tree(pnode root)
{
pnode temp = root->left;
while (temp != NULL && temp->right != NULL)
{
temp = temp->right;
}
return temp;
}
pnode min_right_tree(pnode root)
{
pnode temp = root->right;
while (temp != NULL && temp->left != NULL)
{
temp = temp->left;
}
return temp;
}
void cut_link_from_tree(pnode node)
{
if (node->left == NULL && node->right == NULL)
{
if (node->parent->left == node)
node->parent->left = NULL;
else if(node->parent->right == node)
node->parent->right = NULL;
}
else
{
if (node->left != NULL)
node->parent->right = node->left;
else if (node->right != NULL)
node->parent->left = node->right;
}
}
//二叉排序树的删除
pnode del_tree(pnode root, int data)
{
pnode res = search_tree(root, data);
pnode replace = NULL;
if (res == NULL)
{
printf("not has this data \n ");
return root;
}
if (res->left != NULL)
{
replace = max_left_tree(res);
}
else if(res->right != NULL)
{
replace = min_right_tree(res);
}
else
{
if (res == root)
return NULL;
else
{
cut_link_from_tree(res);
free(res);
return root;
}
}
cut_link_from_tree(replace);
res->data = replace->data;
free(replace);
}

int main()
{
//构建二叉排序树
pnode root = NULL;
int num = 10;
for (int i = 0; i < num; i++)
{
pnode temp = construct_node(rand()%100);
printf("%d ", temp->data);
root = add_node(root, temp);
}

//中序遍历输出(左-根-右)
printf("\n");
inorder(root);
printf("\n");

//二叉排序树的查找
printf("pls input search data:");
int data;
scanf_s("%d", &data);
pnode res = search_tree(root, data);
if (res == NULL)
printf("not found.\n");
else
printf("found,data local:%p,data:%d\n", res, res->data);

//二叉排序树的删除
while (1)
{
printf("pls input del data:");
int data;
scanf_s("%d", &data);
del_tree(root, data);
inorder(root);
printf("\n");
}
return 0;
}

二叉排序树的查找与删除_结点_02