※【数据结构】二叉排序树

在这里插入图片描述
在这里插入图片描述
为什么public的方法还要去调用private的方法呢?它们的功能实现不都是一样的吗?为什么不能直接定义成public呢?

为了保证封闭性,有些函数如果直接暴露给外界可能比较危险,但是如果通过public间接调用,虽然功能一样,但是后期利于维护,如果这个功能我不想让外界用,直接把public里的方法修改就行了,不用去动private方法,private都比较重要,避免后期修改private产生错误

在这里插入图片描述
在这里插入图片描述

二叉排序树的删除(难)

在这里插入图片描述

在这里插入图片描述

#include <iostream>
using namespace std;
#define DataType int
struct BiNode {
	DataType data;
	BiNode * lchild;
	BiNode * rchild;
};
class BiSortTree {
	private:
		BiNode *root;
	public:
		BiSortTree(DataType array[], int arrayLength);
		~BiSortTree() {
			release(root);
		}
		BiNode* searchBST(int key) {
			searchBST(root, key);
		}
		bool deleteBST(int key) {
			return deleteBST(root, key);
		}
		void inOrder() {
			inOrder(root);
		}
	private:
		void insertBST(BiNode* &bt, DataType key);  //插入
		void release(BiNode *bt);                   //二叉树销毁
		void inOrder(BiNode *bt);                   //中序遍历
		bool deleteBST(BiNode* &bt, DataType key);  //删除
		void deleteNode(BiNode* &bt);               //删除节点
		BiNode *searchBST(BiNode *bt, DataType key); //查找

};

BiSortTree::BiSortTree(DataType array[], int length) { //循环建立平衡二叉树
	root = NULL;
	for (int i = 0; i < length; i++) {
		insertBST(root, array[i]);
	}
}

void BiSortTree::insertBST(BiNode * &bt, DataType key) {
	if (NULL == bt) {
		bt = new BiNode;
		bt->data = key;
		bt->lchild = NULL;
		bt->rchild = NULL;
	} else {
		if (key < bt->data) { //左小右大
			insertBST(bt->lchild, key);
		} else {
			insertBST(bt->rchild, key);
		}
	}
}

BiNode * BiSortTree::searchBST(BiNode * bt, DataType key) {
	if (NULL == bt) {
		return NULL;
	} else {
		if (key == bt->data) {
			return bt;
		} else if (key < bt->data) {
			return searchBST(bt->lchild, key);
		} else if (key > bt->data) {
			return searchBST(bt->rchild, key);
		}
	}
}

bool BiSortTree::deleteBST(BiNode * &bt, int key) {
	if (NULL == bt) {
		return false;
	} else {
		if (key == bt->data) {
			deleteNode(bt);
		} else if (key < bt->data) {
			return deleteBST(bt->lchild, key);
		} else {
			return deleteBST(bt->rchild, key);
		}
		return true;
	}
}

void BiSortTree::deleteNode(BiNode * &bt) {
	BiNode * p;
	if (NULL == bt->lchild && NULL == bt->rchild) {
		p = bt;
		bt = NULL;
		delete p;
	} else if (NULL == bt->rchild) {
		p = bt;
		bt = bt->lchild;
		delete p;
	} else if (NULL == bt->lchild) {
		p = bt;
		bt = bt->rchild;
		delete p;
	} else { //左右子树均不为空
		BiNode * parent = bt;
		//用左子树最大值代替删除的节点

		BiNode * pre = bt->lchild;
		while (pre->rchild) { //找到左子树中最大的结点
			parent = pre;
			pre = pre->rchild;
		}

		bt->data = pre->data;
		if (parent != bt) {
			//执行了while循环,parent右子树重新接pre左子树
			parent->rchild = pre->lchild;
		} else {
	
			//未执行while循环,parent左子树重新接pre左子树
			parent->lchild = pre->lchild;
		}
		delete pre;
	}
}

void BiSortTree::inOrder(BiNode * bt) {
	if (NULL == bt) {
		return;
	} else {
		inOrder(bt->lchild);
		cout << bt->data << " ";
		inOrder(bt->rchild);
	}
}

void BiSortTree::release(BiNode *bt) {
	if (bt != NULL) {
		//如果采用先序遍历或者中序遍历,销毁根节点后就找不到左右孩子
		//在销毁的时候需要保存左右孩子的地址
		release(bt->lchild);       //后序遍历销毁二叉树
		release(bt->rchild);
		delete bt;
		bt = NULL;
	}
}

int main() {
	int length;
	int *array;
	cout << "请输入数组长度" << endl;
	cin >> length;
	cout << "请输入" << length << "个数据" << endl;
	array = new int[length];
	for (int i = 0; i < length; i++)
		cin >> array[i];

	BiSortTree bitree(array, length);
	cout << "中序遍历结果:" << endl;
	bitree.inOrder();
	cout << endl;
	cout << "查找34" << (bitree.searchBST(34) ? "成功" : "失败") << endl;
	cout << endl;
	cout << "删除40:" << (bitree.deleteBST(40) ? "成功" : "失败") << endl;
	cout << "删除34:" << (bitree.deleteBST(34) ? "成功" : "失败") << endl;
	cout << "删除13:" << (bitree.deleteBST(13) ? "成功" : "失败") << endl;
	cout << "删除38:" << (bitree.deleteBST(38) ? "成功" : "失败") << endl;
	cout << "删除12:" << (bitree.deleteBST(12) ? "成功" : "失败") << endl;
	cout << "删除4:" << (bitree.deleteBST(4) ? "成功" : "失败") << endl;
	return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序,也称为二搜索(Binary Search Tree,简称BST),是一种特殊的二结构,它具有以下性质: 1. 对于二排序的任意一个非叶子节点,其左子的所有节点的值都小于该节点的值,右子的所有节点的值都大于该节点的值。 2. 对于二排序的任意一个节点,其左子和右子都是二排序。 下面是一个示例代码,演示了如何构建一个二排序,并进行插入和查找操作: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert(root.left, val) else: root.right = insert(root.right, val) return root def search(root, val): if root is None or root.val == val: return root if val < root.val: return search(root.left, val) else: return search(root.right, val) # 构建二排序 root = None values = [5, 3, 8, 2, 4, 7, 9] for val in values: root = insert(root, val) # 查找节点 target = 4 result = search(root, target) if result: print("找到了节点", target) else: print("未找到节点", target) ``` 这段代码首先定义了一个`TreeNode`类,表示二排序的节点。然后定义了`insert`函数,用于向二排序中插入节点。最后定义了`search`函数,用于在二排序中查找指定的节点。通过构建二排序并进行查找操作,可以实现对数据的快速插入和查找。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值