1. 程式人生 > >二叉搜尋樹的C++程式碼實現

二叉搜尋樹的C++程式碼實現

template<class K,class V>
struct BinaryNode{
	K _key;
	V _value;
	BinaryNode<K,V>* _left;
	BinaryNode<K,V>* _right;

	BinaryNode(const K& key,const V& value)
		:_key(key), _value(value), _left(NULL), _right(NULL)
	{}
};
/*****************二叉搜尋樹*******************************
1.每個節點都有一個作為搜尋依據的鍵值K,每個節點的K互不相同。
2.左子樹上的所有節點的K都小於根節點的K。
3.右子樹上的所有節點的K都大於根節點的K。
4.左右子樹也都是二叉搜尋樹。
***********************************************************/

template<class K,class V>
class SearchTree{
	typedef BinaryNode<K,V> Node;
public:
	SearchTree()
		:_root(NULL)
	{}

	void Insert(const K& key,const V& value)
	{
		//樹為空時
		if (_root == NULL)
			_root = new Node(key,value);

		Node* cur = _root;
		Node* parent = NULL;//記錄上一個節點,因為當cur走到地方,要根據與上一節點比較的大小,來決定插入左還是右
		while (cur){
			if (key < cur->_key){
				parent = cur;
				cur = cur->_left;
			}
			else if (key > cur->_key){
				parent = cur;
				cur = cur->_right;
			}
			else{//因為每個節點的K不能相同,所以無法插入
				return;
			}
		}

		//已經找到了位置,插入
		cur = new Node(key,value);
		if (key < parent->_key)
			parent->_left = cur;
		if (key > parent->_key)
			parent->_right = cur;
		return;
	}

	Node* Find(const K& key)//O(lgN)
	{
		Node* cur = _root;
		while (cur){
			if (key < cur->_key)
				cur = cur->_left;
			else if (key > cur->_key)
				cur = cur->_right;
			else
				return cur;
		}
		return NULL;
	}

	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

private:
	void _InOrder(Node* _root)
	{
		if (_root == NULL)
			return;

		_InOrder(_root->_left);
		cout << _root->_key << " ";
		_InOrder(_root->_right);
	}

private:
	Node* _root;
};
//*************二叉搜尋樹變雙鏈表***************
struct TreeNode{
	int _key;
	TreeNode* _left;
	TreeNode* _right;

	TreeNode(int key)
		:_key(key)
		, _left(NULL)
		, _right(NULL)
	{}
};

void Func(TreeNode* node, TreeNode** tail)
{
	if (node == NULL)
		return;

	Func(node->_left, tail);//中序,先走到最左節點

	//把最左節點和tail連線
	node->_left = (*tail);
	if ((*tail) != NULL)
		(*tail)->_right = node;

	//每一層給tail賦值
	(*tail) = node;
	
	//如果node有右子樹,就走到右邊
	if (node->_right)
		Func(node->_right, tail);
}

TreeNode* TreeToList(TreeNode* root)
{
	TreeNode* tail = NULL;
	Func(root, &tail);

	//雙鏈表,知道了尾節點,走到頭,返回
	TreeNode* head = tail;
	while (head && head->_left){
		head = head->_left;
	}
	return head;
}