面试题27:二叉搜索树与双向链表转换

来源:互联网 发布:aim软件 编辑:程序博客网 时间:2024/06/07 06:46
1.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,不能创建任何新的结点。只能调整树中结点指针的指向。

例如: 下面的二叉搜索树和对应的双向链表。



分析:在二叉搜索树中,每个节点都有两个指针,在双向链表中,也有两个指针,在二叉搜索树种,做节点的值总是小于父节点的值,右节点的值总是大于父节点的值。为了使得构造的双向链表有序,原先指向左节点的指针调整为指向前一个节点,原先指向右节点的指针指向链表中的下一个结点。而二叉搜索树的中序遍历出来的序列是从小打到排序的。所以采用中序遍历二叉树。当遍历到根节点的时候,如下图:


当遍历到根节点10 的时候,可以将树看成三个部分,根节点为6的左子树的部分和根节点为14 的右子树,按要求,值为10 的节点将和左子树的最大的一个节点8连接起来,同时还要和右子树值为12 的节点连接起来。


源码:

/*** 功能说明:Description* 作者:K0713* 日期:2016-7-20**/#include<iostream>#include<vector>using namespace std;//二叉树结构struct BinaryTreeNode{int                    m_nValue;BinaryTreeNode*        m_pLeft;BinaryTreeNode*        m_pRight;};//创建结点BinaryTreeNode* CreateBinaryTreeNode(int value);//连接结点void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight);//打印树结点void PrintTreeNode(BinaryTreeNode* pNode);//打印二叉树void PrintTree(BinaryTreeNode* pRoot);//销毁二叉树void DestroyTree(BinaryTreeNode* pRoot);//树的深度int TreeDepth(BinaryTreeNode* pRoot);//-----------------////递归转换void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);//二叉树与双向链表转换,并返回链表头节点BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree);//打印双向链表void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList);//销毁链表void DestroyList(BinaryTreeNode* pHeadOfList);int main(){BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);ConnectTreeNodes(pNode10, pNode6, pNode14);ConnectTreeNodes(pNode6, pNode4, pNode8);ConnectTreeNodes(pNode14, pNode12, pNode16);PrintTree(pNode10);BinaryTreeNode* pHeadOfList = Convert(pNode10);PrintDoubleLinkedList(pHeadOfList);DestroyList(pNode4);system("PAUSE");return 0;}//创建树结点BinaryTreeNode* CreateBinaryTreeNode(int value){BinaryTreeNode* pNode = new BinaryTreeNode();pNode->m_nValue = value;pNode->m_pLeft = NULL;pNode->m_pRight = NULL;return pNode;}//连接树结点void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight){if (pParent != NULL){pParent->m_pLeft = pLeft;pParent->m_pRight = pRight;}}//打印void PrintTreeNode(BinaryTreeNode* pNode){if (pNode != NULL){cout << "value of this node is: " << pNode->m_nValue << endl;if (pNode->m_pLeft != NULL)cout << "value of its left child is: " << pNode->m_pLeft->m_nValue << endl;elsecout << "left child is null.\n";if (pNode->m_pRight != NULL)cout << "value of its right child is:" << pNode->m_pRight->m_nValue << endl;elsecout << "right child is null.\n";}else{cout << "this node is null.\n";}cout << endl;}void PrintTree(BinaryTreeNode* pRoot){PrintTreeNode(pRoot);if (pRoot != NULL){if (pRoot->m_pLeft != NULL)PrintTree(pRoot->m_pLeft);if (pRoot->m_pRight != NULL)PrintTree(pRoot->m_pRight);}}//销毁void DestroyTree(BinaryTreeNode* pRoot){if (pRoot != NULL){BinaryTreeNode* pLeft = pRoot->m_pLeft;BinaryTreeNode* pRight = pRoot->m_pRight;delete pRoot;pRoot = NULL;DestroyTree(pLeft);DestroyTree(pRight);}}//树的深度int TreeDepth(BinaryTreeNode* pRoot){if (pRoot == NULL)return 0;int nLeft = TreeDepth(pRoot->m_pLeft);int nRight = TreeDepth(pRoot->m_pRight);return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);}//二叉树与双向链表的转换BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree){BinaryTreeNode *pLastNodeInList = NULL;ConvertNode(pRootOfTree, &pLastNodeInList);// pLastNodeInList指向双向链表的尾结点,// 我们需要返回头结点BinaryTreeNode *pHeadOfList = pLastNodeInList;while (pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL)pHeadOfList = pHeadOfList->m_pLeft;return pHeadOfList;}//递归转换void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList){if (pNode == NULL)return;BinaryTreeNode *pCurrent = pNode;if (pCurrent->m_pLeft != NULL)ConvertNode(pCurrent->m_pLeft, pLastNodeInList);pCurrent->m_pLeft = *pLastNodeInList;if (*pLastNodeInList != NULL)(*pLastNodeInList)->m_pRight = pCurrent;*pLastNodeInList = pCurrent;if (pCurrent->m_pRight != NULL)ConvertNode(pCurrent->m_pRight, pLastNodeInList);}//打印双向链表void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList){BinaryTreeNode* pNode = pHeadOfList;printf("The nodes from left to right are:\n");while (pNode != NULL){printf("%d\t", pNode->m_nValue);if (pNode->m_pRight == NULL)break;pNode = pNode->m_pRight;}printf("\nThe nodes from right to left are:\n");while (pNode != NULL){printf("%d\t", pNode->m_nValue);if (pNode->m_pLeft == NULL)break;pNode = pNode->m_pLeft;}printf("\n");}void DestroyList(BinaryTreeNode* pHeadOfList){BinaryTreeNode* pNode = pHeadOfList;while (pNode != NULL){BinaryTreeNode* pNext = pNode->m_pRight;delete pNode;pNode = pNext;}}

结果:


0 0
原创粉丝点击