二叉查找树的基本操作

点击查看代码
#include<cstdio>
#pragma warning(disable:4996)

//二叉查找树的基本操作

//结点定义
struct node { 
	int data; //结点权值
	node* lchild; //左孩子指针
	node* rchild; //有孩子指针
};

//新建结点,结点权值为x
node* newNode(int x) { 
	node* Node = new node; //申请新结点的内存
	Node->data = x; //结点权值为x
	Node->lchild = Node->rchild = NULL; //初始状态下没有左右孩子
	return Node; //返回新建结点的地址
}

//查找权值为x的结点
void search(node* root, int x) { 
	if (root == NULL) {	//到达空结点,查找失败
		printf("search failed\n");
		return; //结束递归,返回上一层
	}
	if (x == root->data) { //查找成功
		printf("%d\n", root->data);
	}
	else if (x < root->data) { //x比根结点的权值小
		search(root->lchild, x); //进入左子树中查找
	}
	else { //x比根结点的权值大
		search(root->rchild, x); //进入右子树中查找
	}
}

//插入权值为x的新结点,root地址会被修改,要使用引用型
void insert(node*& root, int x) { 
	if (root == NULL) {	//到达空结点,查找失败,在该位置插入新结点
		root = newNode(x); //调用newNode()创建权值为x的新结点,将地址赋给root
		return; //结束递归返回上一层
	}
	if (x == root->data) { //查找成功,结点已存在,不需要重复插入
		return; //结束递归返回上一层
	}
	else if (x < root->data) { //权值x小于根结点的权值
		insert(root->lchild, x); //进入左子树中查找插入位置
	}
	else { //权值x大于根结点的权值
		insert(root->rchild, x); //进入右子树中查找插入位置
	}
}

//二叉查找树的建立
node* create(int data[], int n) { 
	node* root = NULL; //新建根结点,初始为空地址
	for (int i = 0; i < n; i++) { //依次将a[0]~a[n-1]插入二叉查找树中
		insert(root, data[i]);
	}
	return root; //返回根结点地址
}

//查找以root为根结点的树中的最大权值结点
node* findMax(node* root) {	
	while (root->rchild != NULL) {
		root = root->rchild; //不断往右子树中查找,直到没有右孩子
	}
	return root; //返回最大权值结点
}

//查找以root为根结点的树中的最小权值结点
node* findMin(node* root) {	
	while (root->lchild != NULL) {
		root = root->lchild; //不断往左子树中查找,直到没有左孩子
	}
	return root; //返回最小权值结点
}

//删除以root为根结点的树中权值为x的结点
void deleteNode(node*& root, int x) { 
	if (root == NULL) return; //1、不存在权值为x的结点
	if (root->data == x) { //2、找到权值为x的结点
		if (root->lchild == NULL && root->rchild == NULL) { //2.1、该结点是叶子结点
			root = NULL; //直接删除即可,将结点指向空地址
		}
		else if (root->lchild != NULL) { //2.2、该结点左子树非空
			node* pre = findMax(root->lchild); //查找root的前驱结点
			root->data = pre->data; //用前驱结点的权值覆盖待删除结点权值
			deleteNode(root->lchild, pre->data); //然后在左子树中删除前驱结点pre
		}
		else { //2.3、该结点右子树非空
			node* next = findMin(root->rchild); //查找root的后继结点
			root->data = next->data; //用后继结点的权值覆盖待删除结点权值
			deleteNode(root->rchild, next->data); //然后在右子树中删除后继结点next
		}
	}
	else if (x < root->data) { //3、待删除权值x小于当前根结点权值
		deleteNode(root->lchild, x); //进入左子树中查找待删除结点位置
	}
	else { //4、待删除权值x大于当前根结点权值
		deleteNode(root->rchild, x); //进入右子树中查找待删除结点位置
	}
}

posted @ 2022-09-30 21:10  zhaoo_o  阅读(7)  评论(0编辑  收藏  举报