二叉查找树

前驱节点

  1. 有左子树,前驱节点为左子树的最右节点;
  2. 没有左子树,且本身为右子树,前驱节点为父节点;
  3. 没有左子树,且本身为左子树,向父节点查找,第一个作为右子树节点的父节点的父节点;

删除节点

  1. 没有子树,直接删除
  2. 只有左子树或者右子树,孩子节点代替删除节点;
  3. 同时又左右子树,前驱节点的值保存到当前节点,删除前驱节点;(这时前驱节点一定为第1种情况,一定没有子树,可以直接删除)

 

#include <iostream>
#include <map>
using namespace std;

template<class T>
class Node{
public:
	Node() {}
	Node(T key):_value(key),lchild(nullptr), rchild(nullptr), parent(nullptr){}
	~Node() {}
public:
	T _value;
	Node<T>* lchild;
	Node<T>* rchild;
	Node<T>* parent;
};

template<class T>
class BTree {
public:
	BTree();
	~BTree();
public:
	void insert(T key);
	void remove(T key);
	void preOrder();
	void inOrder();
	void postOrder();
	Node<T>* search_Iterator(T key);
	Node<T>* successor(Node<T>* pnode);
	Node<T>* predecessor(Node<T>* pnode);
public:
	Node<T>* root;
private:
	void preOrder(Node<T>* pnode);
	void inOrder(Node<T>* pnode);
	void postOrder(Node<T>* pnode);
};

template<class T>
BTree<T>::BTree() {
	root = nullptr;
}

template<class T>
BTree<T>::~BTree() {

}

template<class T>
void BTree<T>::insert(T key) {
	Node<T>* pnode = root;
	Node<T>* pparent = nullptr;
	while (pnode != nullptr) {
		if (key < pnode->_value) {
			pparent = pnode;
			pnode = pnode->lchild;
		}
		else if(key > pnode->_value){
			pparent = pnode;
			pnode = pnode->rchild;
		}
		else {
			break;
		}
	}

	pnode = new Node<T>(key);
	if (pparent == nullptr) {
		root = pnode;
	}
	else {
		if (key < pparent->_value) {
			pparent->lchild = pnode;
	}
		else pparent->rchild = pnode;
	}
	pnode->parent = pparent;
		
}

template<class T>
void BTree<T>::preOrder() {
	preOrder(root);
}

template<class T>
void BTree<T>::inOrder() {
	inOrder(root);
}

template<class T>
void BTree<T>::postOrder() {
	postOrder(root);
}

template<class T>
void BTree<T>::preOrder(Node<T>* pnode) {
	if (pnode != nullptr) {
		cout << pnode->_value << " ";
		preOrder(pnode->lchild);
		preOrder(pnode->rchild);
	}
}

template<class T>
void BTree<T>::inOrder(Node<T>* pnode) {
	if (pnode != nullptr) {
		inOrder(pnode->lchild);
		cout << pnode->_value << " ";
		inOrder(pnode->rchild);
	}
}

template<class T>
void BTree<T>::postOrder(Node<T>* pnode) {
	if (pnode != nullptr) {
		postOrder(pnode->lchild);
		postOrder(pnode->rchild);
		cout << pnode->_value << " ";
	}
}

template<class T>
Node<T>* BTree<T>::search_Iterator(T key) {
	Node<T>* pnode = root;
	while (pnode != nullptr) {
		if (key < pnode->_value) {
			pnode = pnode->lchild;
		}
		else if (key > pnode->_value) {
			pnode = pnode->rchild;
		}
		else
			break;
	}
	return pnode;
}

template<class T>
Node<T>* BTree<T>::predecessor(Node<T>* pnode) {
	if (pnode->lchild != nullptr) {
		pnode = pnode->lchild;
		while (pnode->rchild != nullptr) {
			pnode = pnode->rchild;
		}
		return pnode;
	}
	else {
		Node<T>* pparent = pnode->parent;
		while (pparent != nullptr && pnode != pparent->rchild) {
			pnode = pparent;
			pparent = pparent->parent;
		}
		return pparent;
	}
}

template<class T>
void BTree<T>::remove(T key) {
	Node<T>* pnode = nullptr;
	Node<T>* pdel = nullptr;
	Node<T>* pchild = nullptr;
	Node<T>* pparent = nullptr;
	pnode = search_Iterator(key);
	if (pnode == nullptr)return;
	if (pnode->lchild != nullptr && pnode->rchild != nullptr) {
		pdel = predecessor(pnode);
	}
	else {
		pdel = pnode;
	}
	pparent = pdel->parent;
	if (pdel->lchild != nullptr) {
		pchild = pdel->lchild;
	}
	else {
		pchild = pdel->rchild;
	}

	if (pchild != nullptr) {
		pchild->parent = pdel->parent;
	}

	if (pdel->parent == nullptr) {
		root = pchild;
	}
	else if (pparent->lchild == pdel) {
		pparent->lchild = pchild;
	}
	else if(pdel->parent->rchild == pdel) {
		pparent->rchild = pchild;
	}
	if (pdel->_value != key) {
		pnode->_value = pdel->_value;
	}
	delete pdel;
}

int main() {

	BTree<int> t;
	t.insert(5);
	t.insert(2);
	t.insert(8);
	t.insert(6);
	t.insert(9);
	t.insert(4);
	t.insert(1);
	t.postOrder();
	cout << endl;
	t.remove(1);
	t.inOrder();
	cout << endl;
	t.remove(8);
	t.inOrder();
	cout << endl;
	t.remove(5);
	t.inOrder();
	cout << endl;


	getchar();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值