二叉查找树的创建,查找,插入,删除等操作C语言

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

typedef int type;
typedef struct bst                                                                  //创建结构体
{
	type data;
	struct bst *left, *right;
	struct bst *parent;
}node, *tree;



static node* create_node(type data, node *left, node *right, node *parent)                       //创建结点
{
	node *p;
	p = (node*)malloc(sizeof(node));

	p->left = left;
	p->right = right;
	p->parent = parent;
	p->data = data;
	/*	printf("创造结点完毕");*/
	return p;

}

node* search_(tree x, type key)
{
	if (x == NULL || x->data == key)
	{
		return x;
	}

	if (key < x->data)
	{

		return search_(x->left, key);
	}
	else

	{
		return search_(x->right, key);
	}


}                                                                  //递归查找


node* search(tree y, type key)
{

	while (y != NULL && y->data != key)
	{
		if (y->data < key)
			y = y->right;
		else
			y = y->left;
	}
	return y;
}                                                              //迭代查找


node* max(tree m)                       //最大值
{

	if (m == NULL)
		return NULL;
	while (m->right != NULL)
	{
		m = m->right;
	}
	return m;
}

node* min(tree m)                     //最小值
{

	if (m == NULL)
		return NULL;
	while (m->left != NULL)
	{
		m = m->left;
	}
	return m;
}

node* successor(node *s)           //后继
{


	if (s->right != NULL)             //结点右子树非空

		return  min(s->right);
	

	else
	{
		node* p = s->parent;                //结点是左孩子,后继就是他的父节点
		while (p != NULL && p->right == s)
		{                                       //结点是右孩子,向上查找,直到遇到一个有左孩子的父节点,那就是后继
			{
				s = p;
				p = p->parent;
			}

		}
		return p;
	}
	
}

node* insert(tree t, node *z)              //将建好的结点插入进二叉树里
{
	node *y = NULL;
	node *i;
	i = t;

	while (i != NULL)
	{
		y = i;                        //循环完了之后y是i的父节点
		if (i->data < z->data)
			i = i->right;
		else
			i = i->left;
	}
	z->parent = y;
	if (y == NULL)                         //整棵树在插入之前都是空的
		t = z;
	else if (z->data < y->data)
		y->left = z;
	else
		y->right = z;

	return t;



}

node* insert_(tree t, type k)                    //建立一个结点,没有连接
{
	node *z;
	z = create_node(k, NULL, NULL, NULL);


	return  insert(t, z);


}



node* deletes(tree d, node* z)                                           //删除
{
	tree x = NULL, y = NULL;

	if (z->left == NULL || z->right == NULL)                            //z至多有一个子女      
		y = z;
	else                                                                 //z有两个子女
		y = successor(z);
	if (y->left != NULL)                                                //y(也就是z,或z的后继)如果有子女,将它赋给x
		x = y->left;
	else
		x = y->right;
	if (x != NULL)                                                       //x如果得到了y赋的值(也就是z的子女或者后继的子女)
		x->parent = y->parent;
	if (y->parent == NULL)                                               //如果y是根节点
		d = x;
	else if (y == y->parent->left)                                         //如果y是左子女
		y->parent->left = x;
	else                                                                   //如果y是右子女
		y->parent->right = x;
	if (y != z)                                                            //y不等于z就是等于后继,z有两个子女的情况,就把后继的值拿给z
		z->data = y->data;
	return d;

}

node* delete_(tree t, type k)
{
	node* z=NULL;
	z = search_(t, k);

	if (z != NULL)
	{
		printf("查找");
		t = deletes(t, z);
		printf("删除完了");
	}
	else
		printf("无此元素");

	return t;
}


void print_tree(tree t)                        //中序遍历打印
{
	if (t)
	{
		print_tree(t->left);
		printf("%d      ", t->data);
		print_tree(t->right);
	}
}


int main()
{
	int i;
	tree zz = NULL, yy = NULL,kk=NULL,gg=NULL;
	type k;
	int a[12] = { 15,5,16,3,12,10,13,6,7,20,18,23 };
	printf("\n原来的数字是:----------------------------------------");
	for (i = 0; i<12; i++)
	{
		printf("%d ", a[i]);
		zz = insert_(zz, a[i]);

	}
	/* printf("插入完毕");*/
	printf("\n中序遍历结果是:------------------------------------");
	print_tree(zz);
	printf("\n最大值是:-------------------------------------------");
	printf("%d  ", max(zz)->data);
	printf("\n请输入要查找的值:--------------------------------");
	scanf_s("%d", &k);
	search_(zz, k);
	if (search_(zz, k) != NULL)
		printf("查找成功");
	else
		printf("无此元素");
	printf("\n要查找的后继是:---------------------------------");
	scanf_s("%d", &k);
	kk=search_(zz, k);
	gg=successor(kk);
	printf("%d", gg->data);
	printf("\n要删除的值是:---------------------------------------");
	scanf_s("%d", &k);
	yy = delete_(zz, k);
	print_tree(yy);
	printf("\n要插入的值是:--------------------------------------");
	scanf_s("%d", &k);
	insert_(zz, k);
	print_tree(zz);

}


参照了算法导论的伪代码和https://www.cnblogs.com/skywang12345/p/3576328.html这位博主的代码
感觉自己主函数写得好乱。。。。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉查找树(Binary Search Tree,BST)是一种二叉树,其中每个节点都包含一个关键字以及其对应的值。对于任意节点,左子树中的所有节点的关键字都小于该节点的关键字,右子树中的所有节点的关键字都大于该节点的关键字。 此外,BST 具有以下性质: - 在 BST 中进行查找插入删除操作的时间复杂度均为 O(log n),其中 n 为 BST 中节点的数量; - 中序遍历 BST 可以得到有序的节点序列; - 对于任意节点,其左子树和右子树均为 BST。 下面是 C 语言实现 BST 的代码: ```c #include <stdio.h> #include <stdlib.h> // BST 节点结构体 struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; // 创建一个新的 BST 节点 struct TreeNode *createTreeNode(int val) { struct TreeNode *node = (struct TreeNode *)malloc(sizeof(struct TreeNode)); node->val = val; node->left = NULL; node->right = NULL; return node; } // 在 BST 中查找节点 val struct TreeNode *findNode(struct TreeNode *root, int val) { if (root == NULL || root->val == val) { return root; } if (val < root->val) { return findNode(root->left, val); } else { return findNode(root->right, val); } } // 在 BST 中插入一个新的节点 val struct TreeNode *insertNode(struct TreeNode *root, int val) { if (root == NULL) { return createTreeNode(val); } if (val < root->val) { root->left = insertNode(root->left, val); } else { root->right = insertNode(root->right, val); } return root; } // 在 BST 中删除一个节点 val struct TreeNode *deleteNode(struct TreeNode *root, int val) { if (root == NULL) { return NULL; } if (val < root->val) { root->left = deleteNode(root->left, val); } else if (val > root->val) { root->right = deleteNode(root->right, val); } else { if (root->left == NULL) { struct TreeNode *temp = root->right; free(root); return temp; } else if (root->right == NULL) { struct TreeNode *temp = root->left; free(root); return temp; } else { struct TreeNode *temp = root->right; while (temp->left != NULL) { temp = temp->left; } root->val = temp->val; root->right = deleteNode(root->right, temp->val); } } return root; } // 中序遍历 BST void inOrderTraversal(struct TreeNode *root) { if (root != NULL) { inOrderTraversal(root->left); printf("%d ", root->val); inOrderTraversal(root->right); } } int main() { struct TreeNode *root = NULL; root = insertNode(root, 5); root = insertNode(root, 3); root = insertNode(root, 7); root = insertNode(root, 1); root = insertNode(root, 9); printf("BST 中序遍历结果:"); inOrderTraversal(root); // 1 3 5 7 9 root = deleteNode(root, 3); printf("\nBST 删除节点 3 后中序遍历结果:"); inOrderTraversal(root); // 1 5 7 9 return 0; } ``` 以上代码实现了 BST 的查找插入删除操作,并且提供了中序遍历 BST 的函数。在 main 函数中,我们创建了一个 BST,插入了几个节点,然后进行了一次删除操作,并输出删除后的中序遍历结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值