数据结构:将二叉搜索树转换成一个排序的双向链表

1、将二叉搜索树转换成一个排序的双向链表。提示:要求不能创建任何新的结点,只能调整树中结点指针的指向,也就是left当prev,right当next。--中序线索化的变型。 


	Node* BSTreeToList()  
	{
		if(_pRoot == NULL)  
			return NULL;  
		Node* pHead = _pRoot;
		//找到最左边的结点,即转换后链表的头结点
		while(pHead->_pleft != NULL)
			 pHead = pHead->_pleft; 
		Node* prev = NULL;  
		//进行转换  
		_BSTreeToList(_pRoot, prev);  
		return pHead;  
	}

	void _BSTreeToList(Node*& pRoot, Node*& prev)
	{
		if(pRoot)
		{
			_BSTreeToList(pRoot->_pleft, prev);
			
			pRoot->_pleft = prev;//链表的左孩子指向上一个节点

			if(prev && prev->_pright == NULL)
				prev->_pright = pRoot;

			prev = pRoot;
			if(NULL != pRoot->_pright)
				_BSTreeToList(pRoot->_pright, prev);
		}
	}


完整代码:

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

template<class K, class V>
struct BinarySearchTreeNode
{
	BinarySearchTreeNode<K, V>*_pleft;
	BinarySearchTreeNode<K, V>*_pright;
	K _key;
	V _value;
	BinarySearchTreeNode(const K& key, const V& value)
		:_pleft(NULL)
		, _pright(NULL)
		, _key(key)
		,_value(value)
	{}
};

template<class K, class V>
class BinarySearchTree
{
	typedef BinarySearchTreeNode<K, V> Node;
public:
	BinarySearchTree()
		:_pRoot(NULL)
	{}

	BinarySearchTree(const BinarySearchTree<K, V>& tree)
		:_pRoot(NULL)
	{
		_pRoot = _CopyBSTree(tree._pRoot);
	}

	Node& operator=(Node& tree)
	{
		if (this != &tree)
		{
			BinarySearchTree<K, V> tmp(tree);
			swap(_pRoot, tmp._pRoot);
		}
		return *this;
	}

	~BinarySearchTree()
	{
		_Destory(_pRoot);
	}  

	//插入(非递归)
	bool Insert(const K& key, const V& value)
	{
		if (_pRoot == NULL)
		{
			_pRoot = new Node(key, value);
			return true;
		}
		Node* pCur = _pRoot;
		Node* pParent = NULL;
		while (pCur)
		{
			pParent = pCur;
			if (key < pCur->_key)
				pCur = pCur->_pleft;
			else if (key > pCur->_key)
				pCur = pCur->_pright;
			else
				return false;
		}
		pCur = new Node(key, value);
		if (key < pParent->_key)
			pParent->_pleft = pCur;
		else
			pParent->_pright = pCur;
		return true;
	}
	//插入(递归)
	bool Insert_R(const K& key, const V& value)
	{
		return _Insert_R(_pRoot, key, value);
	}

	Node* Find(const K& key)
	{
		if(NULL == _pRoot)
			return NULL;
		Node* pCur = _pRoot;
		while (pCur)
		{
			if (key == pCur->_key)
				return pCur;
			if (key < pCur->_key)
				pCur = pCur->_pleft;
			else
				pCur = pCur->_pright;
		}
		return NULL;
	}

	bool Remove(const K& key)
	{
		Node* pCur = _pRoot;
		Node* pParent = NULL;
		while (pCur)
		{
			if (key < pCur->_key)
			{
				pParent = pCur;
				pCur = pCur->_pleft;
			}
			else if (key > pCur->_key)
			{
				pParent = pCur;
				pCur = pCur->_pright;
			}
			else
				break;
		}
		//跳出循环:pCur为空, 找到节点。
		//删除节点pCur: 1、只有左子树、左右子树都没有
		//			    2、只有右子树
		//			    3、左右孩子都有。
		if(NULL == pCur)//空树
			return false;
		if (pCur->_pright == NULL)//只有左子树或左右子树都没有
		{
			if (pCur == _pRoot)
			{
				_pRoot = pCur->_pleft;
			}
			else
			{
				if (pParent->_pleft == pCur)
					pParent->_pleft = pCur->_pleft;
				else
					pParent->_pright = pCur->_pleft;
			}
			delete pCur;
		}
		else if (pParent->_pleft == NULL)//只有右子树
		{
			if (pCur == _pRoot)
			{
				_pRoot = pCur->_pright;
			}
			else
			{
				if (pParent->_pleft == pCur)
					pParent->_pleft = pCur->_pright;
				else
					pParent->_pright = pCur->_pright;
			}
			delete pCur;
		}
		else//左右子树都不为空:找右子树最小节点(中序遍历的第一个节点)把值互换,删除找到的节点。
		{
			Node* firstInNode = pCur->_pright;
			pParent = pCur;
			while(firstInNode->_pleft)
			{
				pParent =  firstInNode;
				firstInNode = firstInNode->_pleft;
			}
			pCur->_key = firstInNode->_key;
			pCur->_value = firstInNode->_value;

			if(firstInNode == pCur->_pright)
				pParent->_pright = firstInNode->_pright;
			else
				pParent->_pleft = firstInNode->_pright;

			delete firstInNode;	
		}
		return true;
	}

	Node* BSTreeToList()  
	{
		if(_pRoot == NULL)  
			return NULL;  
		Node* pHead = _pRoot;
		//找到最左边的结点,即转换后链表的头结点
		while(pHead->_pleft != NULL)
			 pHead = pHead->_pleft; 
		Node* prev = NULL;  
		//进行转换  
		_BSTreeToList(_pRoot, prev);  
		return pHead;  
	}



private:

	Node* _CopyBSTree(Node* pRoot)
	{
		if (pRoot)
		{
			Node* pNewRoot = new Node(pRoot->_key, pRoot->_value);
			pNewRoot->_pleft = _CopyBSTree(pRoot->_pleft);
			pNewRoot->_pright = _CopyBSTree(pRoot->_pright);
			return pNewRoot;
		}
		else
			return NULL;
	}

	void _Insert_R(Node*& pRoot, const K& key, const V& value)
	{
		if (_pRoot == NULL)
		{
			_pRoot = new Node(key, value);
			return true;
		}

		if(key < pRoot->_key)
			return _Insert_R(pRoot->_pleft, key, value);
		else if(key > pRoot->_key)
			return _Insert_R(pRoot->_pright, key, value);
		else
			return false;
	}
	void _Destory(Node* pRoot)
	{
		if (_pRoot == NULL)
			return;
		_Destory(pRoot->_pleft);
		_Destory(pRoot->_pright);
		delete pRoot;
	}

	void _BSTreeToList(Node*& pRoot, Node*& prev)
	{
		if(pRoot)
		{
			_BSTreeToList(pRoot->_pleft, prev);
			
			pRoot->_pleft = prev;//链表的左孩子指向上一个节点

			if(prev && prev->_pright == NULL)
				prev->_pright = pRoot;

			prev = pRoot;
			if(NULL != pRoot->_pright)
				_BSTreeToList(pRoot->_pright, prev);
		}
	}
private:
	BinarySearchTreeNode<K, V>* _pRoot;
};


int main()
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BinarySearchTree<int, int> t;
	t.Insert(5,5);
	t.Insert(3,3);
	t.Insert(4,4);
	t.Insert(1,1);
	t.Insert(7,7);
	t.Insert(8,8);
	t.Insert(2,2);
	t.Insert(6,6);
	t.Insert(0,0);
	t.Insert(9,9);
	BinarySearchTreeNode<int, int>* list = t.BSTreeToList(); 
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值