vlambda博客
学习文章列表

如何把二叉树转换为双向链表

猿媛之家

已推送大量原创内容

已出版:

C、java、python、go、php、js、kotlin、scala、c#

等各种语言的面试笔试知识点书籍


已在菜单栏开源持续更新分类整理,干货满满


三步加星,方便阅读

如何把二叉树转换为双向链表如何把二叉树转换为双向链表


【出自迅雷笔试题】

难度系数:★★★★☆ 被考察系数:★★★★☆

题目描述:

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整结点的指向,例如下图。


分析与解答:

由于转换后的双向链表中结点的顺序与二叉树的中序遍历的顺序相同,因此,可以对二叉树的中序遍历算法进行修改。通过在中序遍历的过程中修改结点的指向来转换成一个排序的双向链表。实现思路如下图所示:假设当前遍历的结点为rootroot的左子树已经被转换为双向链表,如下图(1)所示。使用两个变量pHeadpEnd分别指向链表的头结点与尾结点。那么在遍历root结点时,只需要将root结点的lchild指向pEnd,把pEndrchild(右)指向root;此时root结点就被加入到双向链表里了。因此,root变成了双向链表的尾结点。对于所有的结点都可以通过同样的方法来修改结点的指向。因此,可以采用递归的方法来求解,在求解时需要特别注意递归的结束条件和边界情况(例如双向链表为空的时候)。

实现代码如下:

public class Test{ private static BiTNode pHead=null; //双向链表头结点
private static BiTNode pEnd=null; //双向链表尾结点
/* ** 方法功能:把二叉树转换为双向列表 ** 输入参数:root:二叉树根结点 */ public static void inOrderBSTree(BiTNode root){ if (null==root) { return; } //转换root的左子树 inOrderBSTree(root.lchild);
root.lchild=pEnd; //使当前结点的左孩子指向双向链表中最后一个结点 if (null==pEnd){ //双向列表为空,当前遍历的结点为双向链表的头结点 pHead=root; } else{ //使双向链表中最后一个结点的右孩子指向当前结点 pEnd.rchild=root; } pEnd=root; //将当前结点设为双向链表中最后一个结点
//转换root的右子树 inOrderBSTree(root.rchild); }
public static void main(String[] args) { int arr[] = {1,2,3,4,5,6,7}; BiTNode root; root=arraytotree(arr,0,arr.length-1); //3.2节 inOrderBSTree(root); BiTNode cur; System.out.print("转换后双向链表正向遍历:"); for(cur=pHead; cur!=null; cur=cur.rchild) System.out.print(cur.data+" "); System.out.println(); System.out.print("转换后双向链表逆向遍历:"); for(cur=pEnd; cur!=null; cur=cur.lchild) System.out.print(cur.data+" "); }}

程序的运行结果为

转换后双向链表正向遍历:1 2 3 4 5 6 7转换后双向链表逆向遍历:7 6 5 4 3 2 1

算法性能分析:

这种方法与二叉树的中序遍历有着相同的时间复杂度O(N)。此外,这种方法只用了两个额外的变量pHeadpEnd来记录双向链表的首尾结点,因此,空间复杂度为O(1)



感谢您的阅读,有任何问题欢迎评论区留言