C++实现二叉排序树(顺序存储)

1、任务描述:编写函数,建立有序表,利用二叉排序树的插入算法建立二叉排序树;在以上二叉排序树中删除某一指定关键字元素;采用折半查找实现某一已知的关键字的查找(采用顺序表存储结构)
2、亮点:无亮点 我觉得用顺序表写树是一个很蠢的事情
3、运行情况(测试数据见代码第8行)
PS:由于最后输入了^Z 所以无法读取要删除的数,如果有大佬知道在VS2019中如何冲走缓冲区的结束符请告诉我
在这里插入图片描述
4、源代码

#include <iostream>
#include <stack>

#define ElemType int

using namespace std;

//测试数据 30 15 41 33 50 35 34 ^Z

class BinSortTree {

private:
	class BinNode {
	public:
		ElemType date;
		int left;
		int right;
	};
	BinNode* head;
	int length = 3;

	const int null = -1;
	const int right = 1;
	const int left = 0;

public:

	BinSortTree() {
		head = new BinNode[length];
		head[0].left = null;
		head[0].right = null;

		for (int i = 1; i < length; i++) {
			head[i].left = null;
			head[i].right = null;
			head[i].date = INT_MIN;
		}
	}

	void ReSize() {

		BinNode* tmp = new BinNode[length * 2];
		for (int i = 0; i < length; i++) {
			tmp[i] = head[i];
		}
		delete[] head;
		head = tmp;

		for (int i = length; i < length * 2; i++) {
			head[i].left = null;
			head[i].right = null;
			head[i].date = INT_MIN;
		}
		length *= 2;
	}

	//中序遍历 输出排序好的数据
	void PreTravel(int pos) {

		if (null == pos)
			return;
		PreTravel(head[pos].left);
		cout << head[pos].date << " ";
		PreTravel(head[pos].right);
	}

	void DisPlay() {
		PreTravel(1);
		cout << endl;
	}

	bool IsEmpty() {

		return null == head->left && null == head->right ? true : false;
	}

	void Creat() {

		int num;
		cout << "请输入数据:    ";

		while (cin >> num) {

			int pos = 1, pre = pos;

			//寻找这个数据应该在的结点
			while (INT_MIN != head[pos].date || null != head[pos].left || null != head[pos].right) {
				pre = pos;
				pos = num > head[pos].date ? 2 * pos + 1 : 2 * pos;
				while (pos >= length)
					ReSize();
			}

			head[pos].date = num;

			if (2 * pre == pos)
				head[pre].left = pos;
			else if ((2 * pre + 1 == pos))
				head[pre].right = pos;

		//	cout << "请继续输入数据:";
		}
	}

	//判断pos位置的元素在上一个元素的左边还是右边 
	int GetDirection(int pos) {

		return head[pos].date > head[pos / 2].date ? right : left;
	}

	int Find(ElemType e) {

		stack<int> s;
		s.push(1);

		while (!s.empty()) {

			int pos = s.top();
			s.pop();

			if (e == head[pos].date)
				return pos;

			if (null != head[pos].left)
				s.push(head[pos].left);
			if (null != head[pos].right)
				s.push(head[pos].right);
		}
		return false;
	}

	void Delete(ElemType e) {

		int pos = Find(e);
		if (false == pos) {
			cout << e << "不存在" << endl;
			return;
		}

		cout << e << "删除成功" << endl;

		while (false != pos) {

			if (null == head[pos].left && null == head[pos].right) {
				if (GetDirection(pos) == right)
					head[pos / 2].right = null;
				else
					head[pos / 2].left = null;
				pos = Find(e);
				continue;
			}

			if (null == head[pos].left) {
				if (GetDirection(pos) == right)
					head[pos / 2].right = head[pos].right;
				else
					head[pos / 2].left = head[pos].right;
				head[pos].right = null;
				pos = Find(e);
				continue;
			}

			if (null == head[pos].right) {
				if (GetDirection(pos) == right)
					head[pos / 2].right = head[pos].left;
				else
					head[pos / 2].left = head[pos].left;
				head[pos].left = null;
				pos = Find(e);
				continue;
			}

			int min = head[pos].right, pre = pos;
			while (null != head[min].left) {
				pre = min;
				min = head[min].left;
			}

			if(pos != pre)
				head[pre].left = head[min].right;
			head[min].right = null;
			if (left == GetDirection(min))
				head[pre].left = null;
			else
				head[pre].right = null;
			head[pos].date = head[min].date;		

			pos = Find(e);
		}
	}
};


int main() {

	BinSortTree* t = new BinSortTree;

	t->Creat();
	t->DisPlay();
	t->Delete(41);
	t->DisPlay();
}

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值