将一棵二叉树转换为双向链表的俩中算法

要求:输入一棵二叉排序树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点的指针的指向。如下图:

方法一:我们借助一个容器来顺序存储结点的指针,然后改变指针的指向。


 1 //////////////////////二叉搜索树与双向链表(方法一)//////////////////////////////////////////
2
3 void Convertfirst(BinaryTreeNode* pRoot , vector<BinaryTreeNode*>& Vec)
4 {
5 if (pRoot)
6 {
7 Convertfirst(pRoot->m_pLeft , Vec);
8 Vec.push_back(pRoot);
9 Convertfirst(pRoot->m_pRight , Vec);
10 }
11 }
12 BinaryTreeNode* Convert1(BinaryTreeNode* pRoot)
13 {
14 if (!pRoot)
15 {
16 return NULL;
17 }
18 vector<BinaryTreeNode*> Vec ;
19 Convertfirst(pRoot ,Vec);
20 BinaryTreeNode* pHead = Vec[0];
21 vector<BinaryTreeNode*>::iterator it = Vec.begin();
22 for ( ; it != Vec.end()-1;it++)
23 {
24 (*it)->m_pRight = (*(it+1)) ;
25 (*(it+1))->m_pLeft = (*it) ;
26 }
27
28 return pHead ;
29 }

方法二:我们边遍历边改变指针的指向。


 1 //////////////////////二叉搜索树与双向链表(方法二)//////////////////
2 void ConvertNode(BinaryTreeNode* pNode , BinaryTreeNode** pLastNodeList)
3 {
4 if (pNode)
5 {
6 ConvertNode(pNode->m_pLeft , pLastNodeList);
7 pNode->m_pLeft = *pLastNodeList;
8 if (*pLastNodeList != NULL)
9 {
10 (*pLastNodeList)->m_pRight = pNode ;
11 }
12 *pLastNodeList = pNode ;
13 ConvertNode(pNode->m_pRight , pLastNodeList);
14 }
15 }
16
17 BinaryTreeNode* Convert2(BinaryTreeNode* pRoot)
18 {
19 if (!pRoot)
20 {
21 return NULL;
22 }
23 BinaryTreeNode* pLastNodeList = NULL ;
24 ConvertNode(pRoot ,&pLastNodeList);
25 while (pLastNodeList && pLastNodeList->m_pLeft)
26 {
27 pLastNodeList = pLastNodeList->m_pLeft ;
28 }
29
30 return pLastNodeList;
31 }

时间: 2024-07-31 23:11:47

将一棵二叉树转换为双向链表的俩中算法的相关文章

算法题——二叉树转换为双向链表

1 BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight) 2 { 3 if(!pNode) 4 return NULL; 5 6 BSTreeNode *pLeft = NULL; 7 BSTreeNode *pRight = NULL; 8 9 // Convert the left sub-tree 10 if(pNode->m_pLeft) 11 pLeft = ConvertNode(pNode->m_pLeft, false

双向链表(4) - 排序二叉树转换为循环双向链表

构建一个递归函数treeToList(Node root),将一棵已排序的二叉树,调整内部指针,使之从外面看起来,是一个循环双向链表.其中前向指针存储在"small"区域,后向指针存储在"large"区域.链表需要进行调整进行升序排序,并返回链表头指针. 下面的这篇文章详细解释了这个转换的过程. http://cslibrary.stanford.edu/109/TreeListRecursion.html 以下是对这篇文章的翻译: The Great Tree-L

用一棵二叉树的前序遍历结果和中序遍历结果还原这棵二叉树——6

输入某二叉树的前序遍历和中序遍历的结果,重建出这棵二叉树,假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如,输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出这棵满足前序遍历和中序遍历的二叉树并输出它的头结点. 对一棵二叉树前序遍历的顺序是"根结点->左结点->右结点",而中序遍历的顺序是"左结点->根节点->右结点",因此,一般的思路都是酱紫的: 前序遍历列表中,第一个数据

二进制查找树转换为双向链表

完全按照海涛哥剑指offer里边的递归思路来写的,基本一样,仅作学习验证,努力锻炼,努力学习! 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 10 /    \ 6       14 /  \     / \ 4     8  12   16 转换成双向链表 4=6=8=10=12=14=16. code如下: //Change a BSTree to a sorted double linklist struc

C++算法之 二叉搜索树转换为双向链表

题目: 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的节点,只能调整树中节点指针的方向: 分析: 1:由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点.当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可.进而更新当前链表的最后一个结点指针. 2:由于中序遍历过程正好是转换成链表的过程,即可采用递归处理 代码: // BT.cpp : 定义控制台应用程序的

Invert a binary tree 翻转一棵二叉树

假设有如下一棵二叉树: 4  / \   2    7  / \   / \ 1  3 6  9翻转后: 4     /    \    7     2   / \    / \  9  6  3  1 这里采用递归的方法来处理.遍历结点,将每个结点的两个子结点交换位置即可. 从左子树开始,层层深入,由底向上处理结点的左右子结点:然后再处理右子树 全部代码如下: public class InvertBinaryTree { public static void main(String args

019写程序在一棵二叉树中找到两个结点的最近共同祖先(keep it up)

写程序在一棵二叉树中找到两个结点的最近共同祖先. 分两种情况来讨论这个题: 第一种情况结点中没有指向父结点的指针 第二种情况接种有指向父节点的指针 我们先看第一种情况,结点中没有指向父结点的指针. 我们可以采用暴力搜索每一个结点,如果这个结点的子树中 有已知的两个结点,那我们就继续沿着左右子树找,如果左子树 能找到,我们就继续沿着左子树找,如果有子树能找到,我们就 沿着右子树找,不存在两个子树都能够找到. 代码: struct TreeNode {<pre name="code"

判断一棵二叉树是不是平衡二叉树

二叉树中任意左右子树的深度相差不超过1,那么它就是一棵平衡二叉树. 两种解法. 第一种:菜鸟的解法,出现重复遍历,时间复杂度高. 1 bool IsBalanced(BinaryTreeNode* root) 2 { 3 if (root == NULL) 4 { 5 return true ; 6 } 7 int left = TreeDepth(root->m_pLeft);//该函数实现见我上一篇博客"数的深度" 8 int right = TreeDepth(root-&

编程实现判断一棵二叉树是否是平衡二叉树

Balanced Binary Tree Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 思路:遍历这棵二叉树,每访问