您的位置:首页 > 其它

二叉排序树在不借助新节点只修改指针转换为双链表

2011-03-14 11:41 429 查看
本题目来源于网络

题目:把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。

10
/ /
6 14
/ / / /
4 8 12 16

转换成双向链表
4=6=8=10=12=14=16。

头文件如下:

/********************************************************************
1.把二元查找树转变成排序的双向链表
	题目:
	输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
	要求不能创建任何新的结点,只调整指针的指向。
	   10
	  / /
	 6  14
	/ / / /
    4 8 12 16

	转换成双向链表
	4=6=8=10=12=14=16。

首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
	int m_nValue; // value of node
	BSTreeNode *m_pLeft; // left child of node
	BSTreeNode *m_pRight; // right child of node
};
*********************************************************************/
#ifndef _BINARYTREE_TO_DOUBLELINKLIST_H_
#define _BINARYTREE_TO_DOUBLELINKLIST_H_
//////////////////////////////////////////////////////////////////////////
#include <tchar.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
struct BTTDL_Node
{
	int        nValue;  // value of node
	BTTDL_Node *pLeft;  // left child of node
	BTTDL_Node *pRight; // right child of node
};

// 添加一个节点
bool BTTDL_AddBinaryTreeNode(BTTDL_Node* &pRootNode, int nNodeValue);

// 打印二叉排序树
bool BTTDL_PrintBinaryTree(const BTTDL_Node *pRootNode);

// 二叉排序树转换为排序的双链表
BTTDL_Node* BTTDL_BinaryTreeToDoubleLinkList(BTTDL_Node *pRootNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex);

// 添加树中遍历到的一个节点到双链表中
void BTTDL_AddBTreeNodeToDoubleLinkList(BTTDL_Node *pBTreeNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex);

// 打印双链表
void BTTDL_PrintDoubleLinkList(BTTDL_Node *pDoubleListHead);
void BTTDL_PrintDoulbeLinkListFromEnd(BTTDL_Node *pDoubleListEnd);

//////////////////////////////////////////////////////////////////////////
#endif




实现文件如下:

#include "BinaryTreeToDoubleLinkList.h"
//////////////////////////////////////////////////////////////////////////
// 添加一个节点
bool BTTDL_AddBinaryTreeNode(BTTDL_Node* &pRootNode, int nNodeValue)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		// 创建节点
		BTTDL_Node *pNewNode = new BTTDL_Node;
		if (pNewNode == NULL)
		{
			return false;
		}

		// 初始化节点
		pNewNode->nValue = nNodeValue;
		pNewNode->pLeft = NULL;
		pNewNode->pRight = NULL;
		pRootNode = pNewNode;
		return true;		
	}

	// 与根节点比较,小于根节点值则插入左子树,否则插入右子树
	if (nNodeValue < pRootNode->nValue)
	{	
		return BTTDL_AddBinaryTreeNode(pRootNode->pLeft, nNodeValue);		
	}
	else
	{		
		return BTTDL_AddBinaryTreeNode(pRootNode->pRight, nNodeValue);		
	}

	return false;
}

// 打印二叉排序树
bool BTTDL_PrintBinaryTree(const BTTDL_Node *pRootNode)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		return false;
	}

	// 打印左子树
	BTTDL_PrintBinaryTree(pRootNode->pLeft);

	// 打印根节点
	printf("%d, ", pRootNode->nValue);

	// 打印右子树
	BTTDL_PrintBinaryTree(pRootNode->pRight);
	return true;
}

// 二叉排序树转换为排序的双链表
BTTDL_Node* BTTDL_BinaryTreeToDoubleLinkList(BTTDL_Node *pRootNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		return NULL;
	}

	// 中序遍历左子树
	if (pRootNode->pLeft != NULL)
	{
		BTTDL_BinaryTreeToDoubleLinkList(pRootNode->pLeft, pDListHead, pDlistIndex);	
	}	

	// 当前遍历到的节点添加到链表
	BTTDL_AddBTreeNodeToDoubleLinkList(pRootNode, pDListHead, pDlistIndex);	

	// 中序遍历右子树
	if (pRootNode->pRight != NULL)
	{
		BTTDL_BinaryTreeToDoubleLinkList(pRootNode->pRight, pDListHead, pDlistIndex);	
	}	

	return NULL;
}

// 添加树中遍历到的一个节点到双链表中
void BTTDL_AddBTreeNodeToDoubleLinkList(BTTDL_Node *pBTreeNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex)
{
	// 参数有效性
	if (pBTreeNode == NULL)
	{
		return;
	}

	// 节点pBTreeNode是当前遍历到的树的节点	
	if (pBTreeNode->pLeft == NULL)
	{
		// 得到链表头节点
		if (pDListHead == NULL)
		{
			pDListHead = pBTreeNode;
			pDlistIndex = pBTreeNode;
		}		
		// 连接到链表尾部
		else
		{
			pDlistIndex->pRight = pBTreeNode;
			pBTreeNode->pLeft = pDlistIndex;
			pDlistIndex = pBTreeNode;
		}
	}
	// 连接到链表尾部
	else
	{
		pDlistIndex->pRight = pBTreeNode;
		pBTreeNode->pLeft = pDlistIndex;
		pDlistIndex = pBTreeNode;
	}
}

// 打印双链表
void BTTDL_PrintDoubleLinkList(BTTDL_Node *pDoubleListHead)
{
	// 参数有效性
	if (pDoubleListHead == NULL)
	{
		return;
	}

	// 打印
	printf("/n");
	BTTDL_Node *pWork = pDoubleListHead;
	while (pWork != NULL)
	{
		printf("%d, ", pWork->nValue);
		pWork = pWork->pRight;
	}
}

void BTTDL_PrintDoulbeLinkListFromEnd(BTTDL_Node *pDoubleListEnd)
{
	// 参数有效性
	if (pDoubleListEnd == NULL)
	{
		return;
	}

	// 打印
	printf("/n");
	BTTDL_Node *pWork = pDoubleListEnd;
	while (pWork != NULL)
	{
		printf("%d, ", pWork->nValue);
		pWork = pWork->pLeft;
	}
}




----------------------------------------------------------------------------------------------------

下面给出二叉排序树类,在其中实现了上述功能:

头文件如下:

/********************************************************************
    二叉排序树  
*********************************************************************/
#ifndef _CBINARY_SEARCH_TREE_H_
#define _CBINARY_SEARCH_TREE_H_
//////////////////////////////////////////////////////////////////////////
#include <tchar.h>
//////////////////////////////////////////////////////////////////////////
struct BSTree_Node
{
	int          nValue;  // value of node
	BSTree_Node  *pLeft;  // left child of node
	BSTree_Node  *pRight; // right child of node
};
//////////////////////////////////////////////////////////////////////////
class CBinarySearchTree
{
public:
	CBinarySearchTree();
	~CBinarySearchTree();

public:
	// 添加一个结点
	bool AddNode(const BSTree_Node *pNode);

	// 中序遍历
	void InorderTraversal(void);

	// 清除
	void Clear(void);

public:
	// 二叉排序树转换为排序的双链表
	void TransToDbList(BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear);

	// 清除双链表
	void ClearDbList(BSTree_Node* &pDbListHead);

public:
	// 向根结点为pRootNode的二叉排序树中添加一个结点
	static bool AddNode(BSTree_Node* &pRootNode, const BSTree_Node *pNode);

	// 中序遍历根结点为pRootNode的二叉排序树
	static void InorderTraversal(const BSTree_Node *pRootNode);

	// 清除
	static void Clear(BSTree_Node* &pRootNode);

	// 添加树中遍历到的一个节点到双链表中
	static void AddInorderBTreeNodeToDbList(BSTree_Node *pBTreeNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear);

	// 二叉排序树转换为排序的双链表
	static void TransToDbList(BSTree_Node *pRootNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear);

	// 打印双链表
	static void PrintDbListFromHead(BSTree_Node *pDbListHead);
	static void PrintDbListFromRear(BSTree_Node *pDbListRear);

private:
	// 防止使用拷贝构造及赋值函数
	CBinarySearchTree(const CBinarySearchTree &otherBSTree);
	CBinarySearchTree& operator =(const CBinarySearchTree &otherBSTree);

private:
	BSTree_Node *m_pBSTreeRoot;    // 二叉排序树根结点
	bool m_bTransToDbList;         // 记录是否转换为双链表
	
};
//////////////////////////////////////////////////////////////////////////
#endif




实现文件如下:

#include "CBinarySearchTree.h"
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
CBinarySearchTree::CBinarySearchTree()
{
	m_pBSTreeRoot = NULL;
	m_bTransToDbList = false;
}

CBinarySearchTree::~CBinarySearchTree()
{
	Clear();
}

// 添加一个结点
bool CBinarySearchTree::AddNode(const BSTree_Node *pNode)
{
	return AddNode(m_pBSTreeRoot, pNode);
}

// 中序遍历
void CBinarySearchTree::InorderTraversal(void)
{
	InorderTraversal(m_pBSTreeRoot);
}

// 清除
void CBinarySearchTree::Clear(void)
{
	if (m_bTransToDbList)
	{
		ClearDbList(m_pBSTreeRoot);
	}
	else
	{
		Clear(m_pBSTreeRoot);
	}	
}

// 二叉排序树转换为排序的双链表
void CBinarySearchTree::TransToDbList(BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear)
{
	TransToDbList(m_pBSTreeRoot, pDbListHead, pDblistRear);
	m_bTransToDbList = true;
	m_pBSTreeRoot = pDbListHead;
}

// 清除双链表
void CBinarySearchTree::ClearDbList(BSTree_Node* &pDbListHead)
{
	// 参数有效性
	if (pDbListHead == NULL)
	{
		return;
	}

	// 释放结点
	BSTree_Node *pWork = pDbListHead;
	BSTree_Node *pDel = NULL;
	while (pWork != NULL)
	{		
		pDel = pWork;
		pWork = pWork->pRight;

		delete pDel;
		pDel = NULL;
	}

	pDbListHead = NULL;
}

// 向根结点为pRootNode的二叉排序树中添加一个结点
bool CBinarySearchTree::AddNode(BSTree_Node* &pRootNode, const BSTree_Node *pNode)
{
	// 参数有效性
	if (pNode == NULL)
	{
		return false;
	}

	// 未创建树的根结点
	if (pRootNode == NULL)
	{
		// 创建节点
		BSTree_Node *pNewNode = new BSTree_Node();
		if (pNewNode == NULL)
		{
			return false;
		}

		// 初始化节点
		pNewNode->nValue = pNode->nValue;
		pNewNode->pLeft = NULL;
		pNewNode->pRight = NULL;
		pRootNode = pNewNode;
		return true;		
	}

	// 与根节点比较,小于根节点值则插入左子树,否则插入右子树
	return (pNode->nValue < pRootNode->nValue) ? AddNode(pRootNode->pLeft, pNode) : AddNode(pRootNode->pRight, pNode);
	
}

// 中序遍历根结点为pRootNode的二叉排序树
void CBinarySearchTree::InorderTraversal(const BSTree_Node *pRootNode)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		return;
	}

	// 打印左子树
	InorderTraversal(pRootNode->pLeft);

	// 打印根节点
	printf("%d, ", pRootNode->nValue);

	// 打印右子树
	InorderTraversal(pRootNode->pRight);
	return;
}

// 清除
void CBinarySearchTree::Clear(BSTree_Node* &pRootNode)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		return;
	}

	// 释放根结点
	BSTree_Node *pLeft = pRootNode->pLeft;
	BSTree_Node *pRight = pRootNode->pRight;
	delete pRootNode;
	pRootNode = NULL;

	// 释放左子树
	Clear(pLeft);

	// 释放右子树
	Clear(pRight);
}

// 添加树中遍历到的一个节点到双链表中
void CBinarySearchTree::AddInorderBTreeNodeToDbList(BSTree_Node *pBTreeNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear)
{
	// 参数有效性
	if (pBTreeNode == NULL)
	{
		return;
	}

	// 节点pBTreeNode是当前遍历到的树的节点	
	if (pBTreeNode->pLeft == NULL)
	{
		// 得到链表头节点
		if (pDbListHead == NULL)
		{
			pDbListHead = pBTreeNode;
			pDblistRear = pBTreeNode;
		}		
		// 连接到链表尾部
		else
		{
			pDblistRear->pRight = pBTreeNode;
			pBTreeNode->pLeft = pDblistRear;
			pDblistRear = pBTreeNode;
		}
	}
	// 连接到链表尾部
	else
	{
		pDblistRear->pRight = pBTreeNode;
		pBTreeNode->pLeft = pDblistRear;
		pDblistRear = pBTreeNode;
	}
}

// 二叉排序树转换为排序的双链表
void CBinarySearchTree::TransToDbList(BSTree_Node *pRootNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear)
{
	// 参数有效性
	if (pRootNode == NULL)
	{
		return;
	}

	// 中序遍历左子树
	if (pRootNode->pLeft != NULL)
	{
		TransToDbList(pRootNode->pLeft, pDbListHead, pDblistRear);	
	}	

	// 当前遍历到的节点添加到链表
	AddInorderBTreeNodeToDbList(pRootNode, pDbListHead, pDblistRear);	

	// 中序遍历右子树
	if (pRootNode->pRight != NULL)
	{
		TransToDbList(pRootNode->pRight, pDbListHead, pDblistRear);	
	}		
}

// 打印双链表
void CBinarySearchTree::PrintDbListFromHead(BSTree_Node *pDbListHead)
{
	// 参数有效性
	if (pDbListHead == NULL)
	{
		return;
	}

	// 打印
	printf("/n");
	BSTree_Node *pWork = pDbListHead;
	while (pWork != NULL)
	{
		printf("%d, ", pWork->nValue);
		pWork = pWork->pRight;
	}
}

// 打印双链表
void CBinarySearchTree::PrintDbListFromRear(BSTree_Node *pDbListRear)
{
	// 参数有效性
	if (pDbListRear == NULL)
	{
		return;
	}

	// 打印
	printf("/n");
	BSTree_Node *pWork = pDbListRear;
	while (pWork != NULL)
	{
		printf("%d, ", pWork->nValue);
		pWork = pWork->pLeft;
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐