剑指offer 面试题27—二叉搜索树与双向链表
2015-05-11 22:19
288 查看
题目:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,要求不能创建任何新节点,只能调整树中结点指针的指向。最后输出排序后双向链表。
基本思想:
二叉树中每个节点都有两个指向子节点的指针。在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点。
二叉搜索树中,左子节点的值总是小于父节点的值,右子节点的值总是大于父节点的值。
在转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
中序遍历树中的每一个节点,中序遍历算法是按照从小到大的顺序遍历二叉树的。
当遍历到根节点时,树看成三部分:值为10的节点、根节点值为6的左子树,根节点值为14的右子树,
值为10的节点将和它的左子树的最大一个节点(8)连接起来,同时它还将和右子树最小的节点(12)连接起来。
按照中序遍历的特点,当遍历转换到根节点(10)时,它的左子树已经转换成一个排序的链表了,并且处在链表中的最后一个节点是8,把8和10连接起来,最后一个节点成为了10,接着我们遍历转换右子树,将10和12连接起来。
至于如何转换左右子树,用递归。
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,要求不能创建任何新节点,只能调整树中结点指针的指向。最后输出排序后双向链表。
基本思想:
二叉树中每个节点都有两个指向子节点的指针。在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点。
二叉搜索树中,左子节点的值总是小于父节点的值,右子节点的值总是大于父节点的值。
在转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
中序遍历树中的每一个节点,中序遍历算法是按照从小到大的顺序遍历二叉树的。
当遍历到根节点时,树看成三部分:值为10的节点、根节点值为6的左子树,根节点值为14的右子树,
值为10的节点将和它的左子树的最大一个节点(8)连接起来,同时它还将和右子树最小的节点(12)连接起来。
按照中序遍历的特点,当遍历转换到根节点(10)时,它的左子树已经转换成一个排序的链表了,并且处在链表中的最后一个节点是8,把8和10连接起来,最后一个节点成为了10,接着我们遍历转换右子树,将10和12连接起来。
至于如何转换左右子树,用递归。
#include <iostream> using namespace std; //二叉树结点定义 typedef struct BiTreeNode{ int data; //左右孩子指针 struct BiTreeNode *lchild; struct BiTreeNode *rchild; }BiTreeNode,*BiTree; //按先序序列创建二叉树 int CreateBiTree(BiTree &T) { int data; //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树 cin>>data; if(data == -1) { T = NULL; } else { T = (BiTree)malloc(sizeof(BiTreeNode)); T->data = data;//生成根结点 CreateBiTree(T->lchild);//构造左子树 CreateBiTree(T->rchild);//构造右子树 } return 0; } void ConvertNode(BiTree pNode, BiTree * pLastNodeInList) { if(pNode == NULL) return; BiTree pCurrent = pNode; //进行左子树的遍历 if (pCurrent->lchild != NULL) ConvertNode(pCurrent->lchild, pLastNodeInList); //做指针指向前面已经排好序的最后一个结点 pCurrent->lchild = *pLastNodeInList; //如果最后一个结点不为空的话,那么就让排序的最后一个结点的右指针指向这棵树 if(*pLastNodeInList != NULL) (*pLastNodeInList)->rchild = pCurrent; //此时这个结点也就加入了排好序的链表中了 *pLastNodeInList = pCurrent; //最后进行右子树的遍历 if (pCurrent->rchild != NULL) ConvertNode(pCurrent->rchild, pLastNodeInList); } BiTree Convert(BiTree pRootOfTree) { BiTree pLastNodeInList = NULL; ConvertNode(pRootOfTree, &pLastNodeInList); // pLastNodeInList指向双向链表的尾结点, // 我们需要返回头结点 BiTree pHeadOfList = pLastNodeInList; while(pHeadOfList != NULL && pHeadOfList->lchild != NULL) pHeadOfList = pHeadOfList->lchild; return pHeadOfList; } //访问函数 void Visit(BiTree T) { if(T->data != -1) cout<<T->data<<" "; } //先序遍历 void PreOrder(BiTree T) { if(T != NULL) { //访问根节点 Visit(T); //访问左子结点 PreOrder(T->lchild); //访问右子结点 PreOrder(T->rchild); } } //输出双向链表 void PrintList(BiTree pRoot) { BiTree pNode = pRoot; while(pNode != NULL) { cout<<pNode->data<<" "; pNode = pNode->rchild; } cout<<endl; } void main() { BiTree T; CreateBiTree(T); cout<<"原二叉树为:"; PreOrder(T); cout<<endl; BiTree listHead = Convert(T); cout<<"双向链表为:"; PrintList(listHead); }
相关文章推荐
- 【剑指Offer学习】【面试题27:二叉搜索树与双向链表】
- 【面试题】剑指Offer-27-将二叉搜索树转换成排序的双向链表
- 剑指Offer面试题27(Java版):二叉搜索树与双向链表
- 剑指offer——面试题27:二叉搜索树与双向链表
- 【剑指offer】4.4分解让复杂问题简单化——面试题27:二叉搜索树与双向链表
- 【剑指Offer学习】【面试题27:二叉搜索树与双向链表】
- [剑指offer]面试题27 二叉搜索树与双向链表
- 剑指offer 面试题27 二叉搜索树与双向链表
- 剑指Offer面试题27(Java版):二叉搜索树与双向链表
- 剑指offer-面试题27-二叉搜索树与双向链表
- 剑指offer之面试题27:二叉搜索树与双向链表
- 剑指offer面试题[27]-二叉搜索树与双向链表
- 剑指offer--面试题27:二叉搜索树与双向链表--Java实现
- 剑指Offer-面试题27:二叉搜索树与双向链表
- 剑指offer 面试题27 二叉搜索树转换为排序双向链表
- 剑指offer(27)——二叉搜索树与双向链表
- 剑指Offer面试题26复杂链表的复制,面试题27二叉搜索树和双向链表(递归)
- 【剑指Offer】:面试题27:二叉搜索树与双链表
- 剑指Offer27:二叉搜索树与双向链表
- 剑指offer解题报告(Java版)——二叉搜索树转换为双向链表 27