面试题 27(*),二叉搜索树与双向链表(二叉搜索树的中序遍历就是有序序列,二叉树和双向链表都是每个结点两个指针)

思路:二叉搜索树的中序遍历就是有序序列,递归实现。递归终止条件是遇到NULL结点。
但是和打印结点不同,我们需要知道当前结点的前一次递归处理了什么结点,前一次递归处理的结点就是当前递归处理结点的prev结点,前一次递归结点的next就是当前结点。为此我们用了一个公共变量BinaryTreeNode **temp,这个指针所指向的地址,专门用来存放当前被处理的结点的地址。
这样,每次递归函数中,先处理左子树,然后从temp中取出上次处理的结点,把当前结点的left指针指向temp,然后将temp的right指针指向当前结点。然后把temp赋值为当前结点,再调用递归函数处理右子树。
边界条件:空树。
代码,核心在treeTransform函数里。
#include "stdafx.h" struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 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) { printf("value of this node is: %d\n", pNode->m_nValue); if(pNode->m_pLeft != NULL) printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue); else printf("left child is null.\n"); if(pNode->m_pRight != NULL) printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue); else printf("right child is null.\n"); } else { printf("this node is null.\n"); } printf("\n"); } 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); } } void *treeTransform(BinaryTreeNode *node, BinaryTreeNode **temp){ if(NULL == node) return NULL; treeTransform(node -> m_pLeft, temp); node -> m_pLeft = *temp; if(*temp != NULL) (*temp) -> m_pRight = node; *temp = node; treeTransform(node -> m_pRight, temp); } BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree) { BinaryTreeNode *pLastNodeInList = NULL; treeTransform(pRootOfTree, &pLastNodeInList); // pLastNodeInList指向双向链表的尾结点, // 我们需要返回头结点 BinaryTreeNode *pHeadOfList = pLastNodeInList; while(pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL) pHeadOfList = pHeadOfList->m_pLeft; return pHeadOfList; } // ====================测试代码==================== 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; } } void Test(char* testName, BinaryTreeNode* pRootOfTree) { if(testName != NULL) printf("%s begins:\n", testName); PrintTree(pRootOfTree); BinaryTreeNode* pHeadOfList = Convert(pRootOfTree); PrintDoubleLinkedList(pHeadOfList); } // 10 // / \ // 6 14 // /\ /\ // 4 8 12 16 void Test1() { 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); Test("Test1", pNode10); DestroyList(pNode4); } // 5 // / // 4 // / // 3 // / // 2 // / // 1 void Test2() { BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); ConnectTreeNodes(pNode5, pNode4, NULL); ConnectTreeNodes(pNode4, pNode3, NULL); ConnectTreeNodes(pNode3, pNode2, NULL); ConnectTreeNodes(pNode2, pNode1, NULL); Test("Test2", pNode5); DestroyList(pNode1); } // 1 // \ // 2 // \ // 3 // \ // 4 // \ // 5 void Test3() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNode1, NULL, pNode2); ConnectTreeNodes(pNode2, NULL, pNode3); ConnectTreeNodes(pNode3, NULL, pNode4); ConnectTreeNodes(pNode4, NULL, pNode5); Test("Test3", pNode1); DestroyList(pNode1); } // 树中只有1个结点 void Test4() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); Test("Test4", pNode1); DestroyList(pNode1); } // 树中没有结点 void Test5() { Test("Test5", NULL); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); return 0; }
书上代码基本上一样,但是多了几个非NULL判断,我没加也通过了,因为递归函数一开始就有判断NULL,应该不需要再额外判断了。
#include "stdafx.h" #include "..\Utilities\BinaryTree.h" void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList); 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); }
------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2014-01-21 11:25 Felix Fang 阅读(276) 评论(0) 收藏 举报
浙公网安备 33010602011771号