搜索插入位置
【问题描述】
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。数组中无重复元素,下标从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");
}