二叉排序树——构建,插入,查找,删除

一、二叉排序树的特点

在这里插入图片描述
创建二叉排序树时,头放入后,每往树中插入元素,从树根开始比较。该数比比较的这个结点小,就放入左孩子,比它大,就放入右孩子。然后进入下一个结点,重复上述操作进行比较,以此来完成二叉排序树的构建。

二、代码实现

在这里插入图片描述

结构体

// 结构体
typedef int KeyType;
typedef struct BSTNode {
	KeyType data; // 存放数据
	struct BSTNode* lchild;
	struct BSTNode* rchild;
}BSTNode,*BiTree;

1.构建二叉排序树

// 创建二叉排序树
void Create_BST(BiTree& T, KeyType str[], int n) {
	T = NULL; //树根为空
	for (int i = 0; i < n; i++) {
		BST_Insert(T, str[i]); // 每个元素插入二叉排序树中
	}
}

2.插入元素到二叉排序树中

// 插入
// 比本身小,就插入左孩子,比本身大,就插入右孩子
int BST_Insert(BiTree& T, KeyType k) {
	// 树根为空时
	if (T == NULL) {
		// 申请空间
		T = (BiTree)calloc(1, sizeof(BSTNode));
		T->data = k;
		T->lchild = T->rchild = NULL;
		return 1; // 为真表示插入成功
	}
	// 如果元素相同,就不插入
	else if (k == T->data) {
		return 0;
	}
	else if (k < T->data) {
		return BST_Insert(T->lchild, k);
	}
	else {
		return BST_Insert(T->rchild, k);
	}
}

3.查找

// 查找
BiTree BST_Search(BiTree T, KeyType key, BiTree& p) {
	p = NULL; // 存储要找的结点的父亲
	while (T != NULL && key != T->data) {
		p = T;
		// 比当前结点小,就去左边找
		if (key < T->data) {
			T = T->lchild;
		}
		else {
			T = T->rchild;
		}
	}
	return T;
}

4.删除

// 删除某个结点
void DeleteNode(BiTree& root, KeyType x) {
	if (root == NULL) {
		return;
	}
	if (root->data > x) {
		DeleteNode(root->lchild, x);
	}
	else if (root->data < x) {
		DeleteNode(root->rchild, x);
	}
	else {
		// 查到了删除结点
		if (root->lchild == NULL) {
			// 左子树为空,右子树顶上
			BiTree tempNode = root;
			root = root->rchild;
			free(tempNode);
		}
		else if (root->rchild == NULL) {
			// 右子树为空,左子树顶上
			BiTree tempNode = root;
			root = root->lchild;
			free(tempNode);
		}
		else {
			// 左右子树都不为空
			// 删除左子树的最大数据或者右子树最小数据,代替要删除的元素
			BiTree tempNode = root->lchild;
			if (tempNode->rchild != NULL) {
				tempNode = tempNode->rchild;
			}
			root->data = tempNode->data;
			DeleteNode(root->lchild, tempNode->data);
		}
	}
}

完整代码

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

// 结构体
typedef int KeyType;
typedef struct BSTNode {
	KeyType data; // 存放数据
	struct BSTNode* lchild;
	struct BSTNode* rchild;
}BSTNode,*BiTree;

// 插入
// 比本身小,就插入左孩子,比本身大,就插入右孩子
int BST_Insert(BiTree& T, KeyType k) {
	// 树根为空时
	if (T == NULL) {
		// 申请空间
		T = (BiTree)calloc(1, sizeof(BSTNode));
		T->data = k;
		T->lchild = T->rchild = NULL;
		return 1; // 为真表示插入成功
	}
	// 如果元素相同,就不插入
	else if (k == T->data) {
		return 0;
	}
	else if (k < T->data) {
		return BST_Insert(T->lchild, k);
	}
	else {
		return BST_Insert(T->rchild, k);
	}
}


// 创建二叉排序树
void Create_BST(BiTree& T, KeyType str[], int n) {
	T = NULL; //树根为空
	for (int i = 0; i < n; i++) {
		BST_Insert(T, str[i]); // 每个元素插入二叉排序树中
	}
}

// 递归实现中序遍历(左中右)
void inOrder(BiTree p) {
	if (p != NULL) {
		inOrder(p->lchild);
		printf("%d ",p->data);
		inOrder(p->rchild);
	}
}

// 查找
BiTree BST_Search(BiTree T, KeyType key, BiTree& p) {
	p = NULL; // 存储要找的结点的父亲
	while (T != NULL && key != T->data) {
		p = T;
		// 比当前结点小,就去左边找
		if (key < T->data) {
			T = T->lchild;
		}
		else {
			T = T->rchild;
		}
	}
	return T;
}

// 删除某个结点
void DeleteNode(BiTree& root, KeyType x) {
	if (root == NULL) {
		return;
	}
	if (root->data > x) {
		DeleteNode(root->lchild, x);
	}
	else if (root->data < x) {
		DeleteNode(root->rchild, x);
	}
	else {
		// 查到了删除结点
		if (root->lchild == NULL) {
			// 左子树为空,右子树顶上
			BiTree tempNode = root;
			root = root->rchild;
			free(tempNode);
		}
		else if (root->rchild == NULL) {
			// 右子树为空,左子树顶上
			BiTree tempNode = root;
			root = root->lchild;
			free(tempNode);
		}
		else {
			// 左右子树都不为空
			// 删除左子树的最大数据或者右子树最小数据,代替要删除的元素
			BiTree tempNode = root->lchild;
			if (tempNode->rchild != NULL) {
				tempNode = tempNode->rchild;
			}
			root->data = tempNode->data;
			DeleteNode(root->lchild, tempNode->data);
		}
	}
}

int main()
{
	BiTree T; // 树根
	// 放入二叉排序树中的元素
	KeyType str[] = { 54,20,66,40,28,79,58 };
	Create_BST(T, str, 7); // 创建二叉排序树
	inOrder(T);
	printf("\n");
	BiTree search; // 存放要查找的元素
	BiTree parent; // 存储父亲结点的地址值
	search = BST_Search(T, 40, parent);
	if (search) {
		printf("找到对应结点,值=%d\n", search->data);
	}
	else {
		printf("未找到该结点\n");
	}
	DeleteNode(T, 66); // 删除结点
	inOrder(T);
	printf("\n");
	return 0;
}

在这里插入图片描述
加油你一定能学会的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值