剑指Offer----面试题27:二叉搜索树与双向链表
2016-06-06 18:02
387 查看
题目:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。如下图中的二叉搜索树,则输出转换之后的排序双向链表。分析:
中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每一个结点。当遍历到根节点的时候,可以把树分为三部分:值为10的结点,根节点值为6的左子树,根节点值为14的右子树。根据排序链表的定义,将根节点与左子树最大的一个结点连接起来,同时将该根节点与右子树最小的一个结点连接起来。如下图所示,再用同样的方法处理左子树和右子树(递归)。源代码如下:
BinaryTreeNode *Covert(BinaryTreeNode *pHead) { if (pHead == NULL) return NULL; BinaryTreeNode *pLastNode = NULL; ConvertNode(pHead, &pLastNode); //pLastNode指向双向链表的尾结点 //我们需要返回头结点 BinaryTreeNode *pHeadNode = pLastNode; while (pHeadNode != NULL && pHeadNode->left != NULL) pHeadNode = pHeadNode->left; return pHeadNode; } void ConvertNode(BinaryTreeNode *node, BinaryTreeNode **pLastNode) { if (node == NULL) return; BinaryTreeNode *current = node; if (current->left != NULL) ConvertNode(current->left, pLastNode); current->left = *pLastNode; if (*pLastNode != NULL) (*pLastNode)->right = current; *pLastNode = current; if (current->right != NULL) ConvertNode(current->right, pLastNode); }
官方源代码:
#include"BinaryTree.h" #include<cstdlib> #include<cstdio> using namespace OrdinaryBinaryTreeSpace6; void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList); BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree) { BinaryTreeNode *pLastNodeInList = NULL; ConvertNode(pRootOfTree, &pLastNodeInList); // pLastNodeInList指向双向链表的尾结点, // 我们需要返回头结点 BinaryTreeNode *pHeadOfList = pLastNodeInList; while (pHeadOfList != NULL && pHeadOfList->left != NULL) pHeadOfList = pHeadOfList->left; return pHeadOfList; } void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList) { if (pNode == NULL) return; BinaryTreeNode *pCurrent = pNode; if (pCurrent->left != NULL) ConvertNode(pCurrent->left, pLastNodeInList); pCurrent->left = *pLastNodeInList; if (*pLastNodeInList != NULL) (*pLastNodeInList)->right = pCurrent; *pLastNodeInList = pCurrent; if (pCurrent->right != NULL) ConvertNode(pCurrent->right, pLastNodeInList); } // ====================测试代码==================== void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList) { BinaryTreeNode* pNode = pHeadOfList; printf("The nodes from left to right are:\n"); while (pNode != NULL) { printf("%d\t", pNode->element); if (pNode->right == NULL) break; pNode = pNode->right; } printf("\nThe nodes from right to left are:\n"); while (pNode != NULL) { printf("%d\t", pNode->element); if (pNode->left == NULL) break; pNode = pNode->left; } printf("\n"); } void DestroyList(BinaryTreeNode* pHeadOfList) { BinaryTreeNode* pNode = pHeadOfList; while (pNode != NULL) { BinaryTreeNode* pNext = pNode->right; delete pNode; pNode = pNext; } } void Test(char* testName, BinaryTreeNode* pRootOfTree) { if (testName != NULL) printf("%s begins:\n", testName); PrintTreeMid(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); ConnectBinaryTreeNodes(pNode10, pNode6, pNode14); ConnectBinaryTreeNodes(pNode6, pNode4, pNode8); ConnectBinaryTreeNodes(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); ConnectBinaryTreeNodes(pNode5, pNode4, NULL); ConnectBinaryTreeNodes(pNode4, pNode3, NULL); ConnectBinaryTreeNodes(pNode3, pNode2, NULL); ConnectBinaryTreeNodes(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); ConnectBinaryTreeNodes(pNode1, NULL, pNode2); ConnectBinaryTreeNodes(pNode2, NULL, pNode3); ConnectBinaryTreeNodes(pNode3, NULL, pNode4); ConnectBinaryTreeNodes(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(); system("pause"); return 0; }
运行结果:
Test1 begins: 4 6 8 10 12 14 16 The nodes from left to right are: 4 6 8 10 12 14 16 The nodes from right to left are: 16 14 12 10 8 6 4 Test2 begins: 1 2 3 4 5 The nodes from left to right are: 1 2 3 4 5 The nodes from right to left are: 5 4 3 2 1 Test3 begins: 1 2 3 4 5 The nodes from left to right are: 1 2 3 4 5 The nodes from right to left are: 5 4 3 2 1 Test4 begins: 1 The nodes from left to right are: 1 The nodes from right to left are: 1 Test5 begins: The tree is empty The nodes from left to right are: The nodes from right to left are: 请按任意键继续. . .
相关文章推荐
- 一个关于if else容易迷惑的问题
- 使用C++实现JNI接口需要注意的事项
- [C/C++]反转链表
- 关于指针的一些事情
- AVL树-自平衡二叉查找树(Java实现)
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#实现基于链表的内存记事本实例
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- 一道sql面试题附答案
- C#模拟链表数据结构的实例解析
- C# 超高面试题收集整理
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析