【BST】把两棵BST合并成一棵高度平衡的BST

题目:EPI


class treenode
{
public:
	int data;
	shared_ptr<treenode> left, right;
	treenode(int d) :data(d), left(nullptr), right(nullptr){}
	treenode(int d, shared_ptr<treenode> &l, shared_ptr<treenode> &r) :data(d), left(l), right(r){}
};

//双链表的节点和二叉树节点类似,left当做前继节点prev,right当做后继节点next
typedef treenode doublelist;
typedef shared_ptr<treenode> pnode;

//返回值是pair类型,first是双链表第一个节点,second是双链表最后一个节点
pair<pnode, pnode> covert_BST_to_doublelist_core(const pnode &root)
{
	if (!root)
		return pair<pnode, pnode>(nullptr, nullptr);
	if (!root->left && !root->right)
		return pair<pnode, pnode>(root, root);
	pair<pnode, pnode> l, r, res;
	l = covert_BST_to_doublelist_core(root->left);
	r = covert_BST_to_doublelist_core(root->right);
	if (l.first == nullptr)
		res.first = root;
	else
	{
		res.first = l.first;
		root->left = l.second;
		l.second->right = root;
	}

	if (r.first == nullptr)
		res.second = root;
	else
	{
		res.second = r.second;
		root->right = r.first;
		r.first->left = root;
	}
	return res;
}

pnode covert_BST_to_doublelist(const pnode &root)
{
	if (!root)
		return root;
	if (!root->left && !root->right)
		return root;
	pair<pnode, pnode> l, r;
	pnode head;
	l = covert_BST_to_doublelist_core(root->left);
	r = covert_BST_to_doublelist_core(root->right);
	if (l.first == nullptr)
		head = root;
	else
	{
		head = l.first;
		root->left = l.second;
		l.second->right = root;
	}

	if (r.first != nullptr)
	{
		root->right = r.first;
		r.first->left = root;
	}

	return head;
}

shared_ptr<treenode> cover_doublelist_to_BST(shared_ptr<doublelist> &head)
{
	if (head == nullptr || head->right == nullptr)
		return head;
	shared_ptr<doublelist> tmp, slow = head, fast = head;
	shared_ptr<treenode> root;
	while (fast->right && fast->right->right)
	{
		slow = slow->right;
		fast = fast->right->right;
	}
	//此时slow指向上中位数节点
	root = slow;

	if (root != head)
	{
		slow->left->right = nullptr;//重要,断掉slow前一个节点指向slow的指针
		slow->left = nullptr;
		root->left = cover_doublelist_to_BST(head);
	}
	else
		root->left = nullptr;

	tmp = slow->right;
	slow->right->left = nullptr;
	slow->right = nullptr;
	root->right = cover_doublelist_to_BST(tmp);

	return root;

}

shared_ptr<doublelist> merge_two_doublelist(shared_ptr<doublelist> &h1, shared_ptr<doublelist> &h2)
{
	//nsmall是small的下一个节点,tail是已合并节点的最后一个节点
	shared_ptr<doublelist> small,nsmall,tail, head, p1 = h1, p2 = h2;

	if (p1->data <= p2->data)
	{
		head = p1;
		tail = p1;
		p1 = p1->right;
	}
	else
	{
		head = p2;
		tail = p2;
		p2 = p2->right;
	}

	while (p1 && p2)
	{
		small = p1->data <= p2->data ? p1 : p2;
		//tail指向小
		nsmall = small->right;
		tail->right = small;
		small->left = tail;
		tail = tail->right;//注意移动tail
		p1 = p1 == small ? nsmall : p1;
		p2 = p2 == small ? nsmall : p2;
	}

	if (p1)
	{
		p1->left = tail;
		tail->right = p1;
	}
	if (p2)
	{
		p2->left = tail;
		tail->right = p2;
	}
	return head;
}

shared_ptr<treenode> merge_two_BST(shared_ptr<treenode> &r1, shared_ptr<treenode> &r2)
{
	if (r1 == nullptr)
		return r2;
	if (r2 == nullptr)
		return r1;
	shared_ptr<treenode> l1=covert_BST_to_doublelist(r1);
	shared_ptr<treenode> l2 = covert_BST_to_doublelist(r2);
	shared_ptr<treenode> head=merge_two_doublelist(l1, l2);
	return cover_doublelist_to_BST(head);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值