二叉搜索树转化为双向链表

题目描述:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:
在这里插入图片描述
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
在这里插入图片描述
当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

分析:

按照题目要求,我们将题中给的二叉树变为双向链表,由于所给的二叉树是一棵二叉搜索树,所以我们根据节点值的大小来改变指向,如下图所示:

在这里插入图片描述
因此,整体的思路就是通过中序遍历来改变每个节点的左右指针域,具体题解步骤如下:

  • 树为空:直接返回root
  • 树不为空:改变每个节点的指向(中序遍历
    • 通过中序遍历先做到最左下角节点,然后从最左下节点开始改变指向:让其(cur)left指向pre;pre的后继(right)指向cur.
    • 接着通过递归改变左子树的指向
    • 通过递归改变右子树的指向。

注意:

  • 题目要求最后返回head,这个head是链表中的第一个节点的指针,也就是上图中的节点1,`因此我们还需要让节点1的前驱指向最后一个节点(节点5),让最后一个节点的后继指向第一个节点,这就需要在中序遍历之后将第一个节点和最后一个节点保存起来,然后改变它两的前驱和后继。
  • 由于一开始我们没办法让第一个节点的前驱指向最后一个节点,我们只能先令pre=null

代码:

class Solution {
	Node pre=null;
	//中序遍历改变指向
	public void changePtr(Node cur)
    {
    	if(cur==null)
    	{
    		return;
    	}
    	//先改变左子树
    	changePtr(cur.left);
    	cur.left=pre;//当前节点前驱指向pre
    	
    	if(pre!=null)
    	{pre.right=cur;}//pre的后继指向当前节点
    	
    	pre=cur;//更新pre
    	//再改变右子树
    	changePtr(cur.right);    
    }
    public Node treeToDoublyList(Node root) {
    	if(root == null)
    	{
    		return root;
    	}
    	//改变指向
    	changePtr(root);
    	//找到第一个节点保存到head中
    	Node head=root;
    	while(head!=null)
    	{
    		head=head.left;
    	}
    	//找到最后一个节点保存到last中
    	Node last=root;
    	while(last!=null)
    	{
    		last=last.right;
    	}
    	//改变第一个前驱和最后一个的后继
    	head.left=last;
    	last.right=head;
    	return head;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值