#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode{
struct TreeNode* lchild;
struct TreeNode* rchild;
int val;
}TreeNode;
//构造树节点
TreeNode* createTreeNode(int val){
TreeNode *node;
node = (TreeNode*)malloc(sizeof(TreeNode));
node->val = val;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
//创建树
TreeNode* createTree(int *array,int length){
TreeNode *root = createTreeNode(array[0]);
TreeNode *temp = root;
TreeNode *parent = root;
int i = 1;
while(i<length){
temp = root;
while(temp){
parent = temp;
if(temp->val>array[i]){
temp = temp->lchild;
}
else if(temp->val<array[i]){
temp = temp->rchild;
}
else{
break;
}
}
if(parent->val>array[i])
parent->lchild=createTreeNode(array[i]);
else
parent->rchild=createTreeNode(array[i]);
i++;
}
return root;
}
//递归寻找删除节点的位置
void del(TreeNode *node,int key,TreeNode *parent){
if(node==NULL)
return;
if(key==node->val){
deleteNode(node,parent);
}
else if(key>node->val){
del(node->rchild,key,node);
}else{
del(node->lchild,key,node);
}
}
//删除节点的核心方法
void deleteNode(TreeNode *node,TreeNode *parent){
int flag = -1;
if(parent->lchild==node){
flag=1;
}else{
flag=0;
}
if(node->lchild==NULL&&node->rchild==NULL){
if(flag==1){
parent->lchild = NULL;
}else{
parent->rchild = NULL;
}
}
else if(node->lchild!=NULL&&node->rchild==NULL){//删除节点有左子树
//重接左子树
if(flag==1){
parent->lchild = node->lchild;
}else{
parent->rchild = node->lchild;
}
}
else if(node->rchild!=NULL&&node->lchild==NULL){//删除节点有右子树
//重接右子树
if(flag==1){
parent->lchild = node->rchild;
}else{
parent->rchild = node->rchild;
}
}else{
//左右子树都不空
//右子树取最小的拿过来替代删除节点 或者将删除节点左子树上最大的替代 因为左子树最大的和右子树最小的都一定是叶子节点
//替代之后,既能保持排序二叉树的特性,移除叶子节点也很轻松
TreeNode *pre = node;
TreeNode *in = node->rchild;//往右一步
while(in->lchild){//向左搜索 找到最左边的
pre = in;//保存前缀节点
in = in->lchild;
}
//替补
node->val = in->val;
if(pre==node)//判断删除节点右子树是否只有一个节点
pre->rchild = NULL;
else//如果不是 则删除pre的左子树
pre->lchild = NULL;
}
}
//先序输出
void output(TreeNode *root){
if(root==NULL)
return;
printf("%d ",root->val);
output(root->lchild);
output(root->rchild);
}
//查找节点
TreeNode* searchTree(TreeNode *root,int key){
if(root==NULL){
return NULL;
}
if(root->val==key){
return root;
}
root->val>key?searchTree(root->lchild,key):searchTree(root->rchild,key);//向左或向右查找
}
//插入节点
TreeNode* insertNode(int value,TreeNode *root){
if(root==NULL){
TreeNode *node = createTreeNode(value);
return node;
}
if(root->val == value){//如果相等 则直接返回
return root;
}
if(root->val>value){
//向左遍历
root->lchild = insertNode(value,root->lchild);
}else{
//向右遍历
root->rchild = insertNode(value,root->rchild);
}
return root;
}
int main()
{
int a[7]={10,5,17,20,6,15,18};
TreeNode *root = createTree(a,7);
root = insertNode(17,root);//插入
output(root);
del(root,10,root);//删除
output(root);
//查找
TreeNode *node = searchTree(root,20);
output(node);
return 0;
}C语言实现二叉排序树的增删查操作
最新推荐文章于 2022-07-10 16:19:22 发布
这篇博客介绍了如何使用C语言实现二叉排序树的基本操作,包括创建、插入节点、删除节点和查找节点。通过示例代码展示了如何构建、输出、删除和搜索树中的元素,并提供了完整的main函数来演示这些操作。
2704

被折叠的 条评论
为什么被折叠?



