SJTU 利用二叉查找树的logk插入

搜索插入位置

【问题描述】

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。数组中无重复元素,下标从0开始。

【输入形式】

输入一共三行。

第一行是一个正整数N,代表数组的长度。

第二行有N个数,代表排序数组,用空格隔开。

第三行是目标值。

【输出形式】

若目标值存在数组中,返回索引。否则,返回它被按顺序插入的位置。

【样例输入1】

4
1 3 5 6
5
【样例输出1】

2
【样例输入2】

4
1 3 5 6
2
【样例输出1】

1
【评分标准】

要求时间复杂度是O(log n)

#pragma once
#include<iostream>
using namespace std;
template <class KEY, class OTHER>
struct SET {
	KEY key;
	OTHER other;
};
template <class KEY, class OTHER>
class BinarySearchTree
{
private:
	
	struct BinaryNode
	{
		SET <KEY, OTHER>data;
		BinaryNode*left;
		BinaryNode*right;
		BinaryNode(const SET<KEY, OTHER>&thedata, BinaryNode*lt = NULL, BinaryNode*rt = NULL):
			data(thedata),left(lt),right(rt){}
	};
	BinaryNode*root;
public:
	BinarySearchTree();
	~BinarySearchTree();
	SET<KEY, OTHER>*find(const KEY &x)const;
	void insert(const SET<KEY, OTHER>&x);
	void insert_x(const SET<KEY, OTHER>&x);//专门为a准备
	void remove(const KEY&x);
private:
	void Insert(const SET<KEY, OTHER>&x, BinaryNode*&t);
	void Insert_x(const SET<KEY, OTHER>&x, BinaryNode*&t);
	void Remove(const KEY&x);
	SET<KEY, OTHER>*Find(const KEY&x)const;
	void makeEmpty(BinaryNode*t);
};

template<class KEY, class OTHER>
BinarySearchTree<KEY, OTHER>::BinarySearchTree()
{
	root = NULL;
}
template<class KEY, class OTHER>
BinarySearchTree<KEY, OTHER>::~BinarySearchTree()
{
	makeEmpty(root);
}
template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::makeEmpty(BinaryNode *t)
{
	if (!t)return ;
	makeEmpty(t->left);
	makeEmpty(t->right);
	delete t;
}
template<class KEY, class OTHER>
SET<KEY, OTHER>*BinarySearchTree<KEY, OTHER>::find(const KEY&x)const//一定由根查
{
	return Find(x);
}
//template<class KEY, class OTHER>
//SET<KEY, OTHER>*BinarySearchTree<KEY, OTHER>::find(const KEY&x, BinaryNode*t)const
//{
//	if (t == NULL)return NULL;
//	if (t->data.key == x)return &t->data;//返回值为*
//	if (x < t->data.key) {
//		return find(x, t->left);
//	}
//	if (x > t->data.key) {
//		return find(x, t->right);
//	}
//}
template<class KEY, class OTHER>
SET<KEY, OTHER>*BinarySearchTree<KEY, OTHER>::Find(const KEY&x)const//直接处理root
{
	if (!root) { return NULL; }//左右子空亦在此步
	BinaryNode*p = root;
	while (p)
	{
		if (x == p->data.key) { cout << p->data.other<<'\n'; return &p->data; }
		if (x < p->data.key) {
			p = p->left;
		}
		else {
			p = p->right;
		}
	}
	return NULL;
}

template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::insert(const SET<KEY, OTHER>&x)
{
	Insert(x, root);
}
//template<class KEY,class OTHER>
//void BinarySearchTree<KEY, OTHER>::insert(const SET<KEY, OTHER>&x, BinaryNode*&t)
//{
//	if (!t) { t = new BinaryNode(x.key, NULL, NULL);return }
//	if (x.key == t->data.key) { return; }
//	if (x.key < t->data.key) { insert(x, t->left); }
//	else insert(x, t->right);
//}
template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::Insert(const SET<KEY, OTHER>&x, BinaryNode*&t)
{
	BinaryNode*p;
	if (!root) { root = new BinaryNode(x, NULL, NULL); return; }
	p = root;
	while (p) {
		if (x.key == p->data.key) return;
		if (x.key < p->data.key)
		{
			if (!p->left) { p->left = new BinaryNode(x, NULL, NULL);  return; }
			p = p->left;
		}
		else {
			if (!p->right) { p->right = new BinaryNode(x, NULL, NULL);  return; }
			p = p->right;
		}
	}
}

template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::insert_x(const SET<KEY, OTHER>&x)
{
	Insert_x(x, root);
}
template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::Insert_x(const SET<KEY, OTHER>&x, BinaryNode*&t)
{
	BinaryNode*p;
	if (!root) { root = new BinaryNode(x, NULL, NULL); return; }
	p = root;
	while (p) {
		if (x.key == p->data.key) return;
		if (x.key < p->data.key)
		{
			if (!p->left) { 
				p->left = new BinaryNode(x, NULL, NULL);cout<<p->data.other<<'\n';  return;
			}
			p = p->left;
		}
		else {
			if (!p->right) {
				p->right = new BinaryNode(x, NULL, NULL); cout << p->data.other + 1<<'\n'; return; 
			}
			p = p->right;
		}
	}
}

template <class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::remove(const KEY&x)
{
	Remove(x);
}
//template<class KEY,class OTHER>
//void BinarySearchTree<KEY, OTHER>::remove(const KEY&x,BinaryNode*&t)
//{
//	if (!t)return;
//	if (x < t->data.key) { remove(x, t->left); }
//	else if (x > t->data.key) { remove(x, t->right); }
//	else	{//x==t->data.key
//		if (t->left&&t->right)//有两个孩子
//		{
//			BinaryNode*tmp;
//			tmp = t->right;
//			while (!tmp->left) { tmp = tmp->left; }
//			t->data= tmp->data;//整体替换
//			remove(tmp->data.key, t->right);
//		}
//		else //被删结点是叶节点或只有一个孩子
//		{
//			BinaryNode *oldNode = t;
//			t = (t->left) ? t->left : t->right;
//			delete oldNode;
//		}
//	}
//}
template<class KEY, class OTHER>
void BinarySearchTree<KEY, OTHER>::Remove(const KEY&x)
{
	if (!root)return;
	BinaryNode*p, *parent;
	int flag;//0为父节点顺左子下来,1为父节点顺右子下来
	p = root; parent = NULL;
	while (p)
	{
		if (x < p->data.key)
		{
			parent = p;
			flag = 0;
			p = p->left;
			continue;
		}
		if (x > p->data.key)
		{
			parent = p;
			flag = 1;
			p = p->right;
			continue;
		}//p即为要删除的结点,若是根结点则parent=NULL,反之不为空
		 //删除开始
		if (!p->left && !p->right)
		{
			delete p;
			if (!parent) { root = NULL; return; }//待删除结点为根,且根为叶子
			if (flag == 0)//待删除结点为父节点左子
			{
				parent->left = NULL;
			}
			else {
				parent->right = NULL;
			}
			return;
		}//叶子
		if (!p->left || !p->right)//待删除结点仅有一个孩子结点
		{
			BinaryNode*tmp; tmp = p;
			if (!parent)
			{
				root = (p->left) ? p->left : p->right;
			}
			else
			{
				if (flag == 0)//待删除结点为左孩子
				{
					parent->left = (p->left) ? p->left : p->right;
				}
				else
				{
					parent->right = (p->left) ? p->left : p->right;
				}
			}
			return;
		}//仅有一个孩子
		BinaryNode*q, *substitute;//待删除结点有两个孩子结点
		parent = p; q = p->left; flag = 0;
		while (q->right) { parent = q; flag = 1; q = q->right; }
		substitute = q;//找到替换节点

					   //交换二者的值
		SET<KEY, OTHER>e; e = p->data;
		p->data = substitute->data;
		substitute->data = e;

		p = substitute;
	}
}

#include<iostream>
using namespace std;
int main()
{
	BinarySearchTree<int, int>tree;
	int n,i;
	SET<int, int>a;
	cin >> n;
	SET<int,int>*x = new SET<int,int>[n];
	for (i = 0; i <= n - 1; i++)
	{
		cin >> x[i].key;
		x[i].other = i;
		tree.insert(x[i]);
	}
	cin >> a.key;
	if (!tree.find(a.key))
	{
		tree.insert_x(a);
	}
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值