首页 > 其他分享 >【剑指Offer】26、二叉搜索树与双向链表

【剑指Offer】26、二叉搜索树与双向链表

时间:2023-08-14 23:55:33浏览次数:39  
标签:pRootOfTree curEndoflink Offer 结点 26 链表 null root

题目描述:

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

解题思路:

首先要理解此题目的含义,在双向链表中,每个结点都有前后两个指针;二叉树中,每个结点都有两个指向子结点的左右指针,同时,二叉搜索树树也是一种排序的数据结构。因此,从结构上看,双向链表的前后指针和二叉搜索树的左右指针结构相似,因此,可以实现互相之间的转换。

首先,根据二叉搜索树的特点,左结点的值<根结点的值<右结点的值,据此不难发现,使用二叉树的中序遍历得到的数据序列就是递增的排序顺序。因此,首先确定应该采用中序遍历方法。

接下来,可以根据下图,将树分为三个部分,值为10的根结点、根为6的左子树和根为14的右子树。不难看出以下规律:根据中序遍历的顺序,当我们遍历到根结点时,它的左子树已经转换为一个排好序的双向链表,并且链表最后一个结点是左子树值最大的结点,我们把这个值最大(8)的结点同根结点链接起来,10就成了最后一个结点,接着遍历右子树,将根结点同右子树中最小的结点链接起来。

很明显,左右子树具有和原问题相同的结构,因此直接利用递归即可实现。

举例:

编程实现(Java):

public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
        //根据中序遍历采用递归依次实现
        if(pRootOfTree==null)
            return null;
        TreeNode curEndoflink=null;
        TreeNode root=pRootOfTree;
        Convert(root,curEndoflink);
        
        while(pRootOfTree!=null && pRootOfTree.left!=null){ //链表头是最左边
            pRootOfTree=pRootOfTree.left;
        }
        return pRootOfTree;
    }
    //curEndoflink保存的是当前已经排好的链表的最后一个节点
    public TreeNode Convert(TreeNode pRootOfTree,TreeNode curEndoflink){
        if(pRootOfTree==null)
            return null;
        TreeNode root=pRootOfTree;
        if(root.left!=null) //将左子树构建为链表
            curEndoflink=Convert(root.left,curEndoflink);
        
        //将根接在左子树的链表之后
        root.left=curEndoflink;
        if(curEndoflink!=null)
            curEndoflink.right=root;
        curEndoflink=root;  //引用改变值,需要return
        
        if(root.right!=null) //将右子树构建为链表
            curEndoflink=Convert(root.right,curEndoflink);
        
        return curEndoflink;
        
    }
}

标签:pRootOfTree,curEndoflink,Offer,结点,26,链表,null,root
From: https://www.cnblogs.com/bujidao1128/p/17630109.html

相关文章

  • 【剑指Offer】23、二叉搜索树的后序遍历序列
    【剑指Offer】23、二叉搜索树的后序遍历序列题目描述:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。解题思路:对于后续遍历序列,序列的最后一个值一定是树的根结点,而由二叉搜索树的性质......
  • Leetcode 206. 反转链表(Reverse linked list)
    题目链接给你单链表的头节点head,请你反转链表,并返回反转后的链表。示例1:输入:head=[1,2,3,4,5]输出:[5,4,3,2,1]示例2:输入:head=[1,2]输出:[2,1]提示:链表中节点的数目范围是[0,5000]-5000<=Node.val<=5000思路迭代法:创建两个指针,分别指向当前节......
  • 剑指 Offer 36. 二叉搜索树与双向链表(中等)
    题目:classSolution{public:Node*head=nullptr;Node*pre=nullptr;voidtraversal(Node*cur){//二叉搜索树中序遍历的顺序就是构建双向链表的顺序if(!cur)return;traversal(cur->left);if(pre){//若前置节点存在,则与当......
  • [ARC126C] Maximize GCD 题解
    题意给定一个序列\(A\),每次操作可以使\(A_i+1\)(\(i\in\left[1,n\right]\),\(K\)次操作的\(i\)可以不同),最多可以做\(K\)次。问\(\gcd{A_1,A_2,...,A_n}\)的最大值。题解首先,如果\(K\)可以把当前序列中所有的数都加到\(A_{\max}\),那就全部加到\(A_{\max}\),在......
  • [ARC126D] Pure Straight 题解
    题意给定一个有\(N\)个正整数的序列\(A=(A_1,A_2,\cdots,A_N)\),且\(A_i\in\left[1,K\right]\)。你可以对这个序列做如下操作若干次。交换两个相邻的元素,也就是选出\(i\)和\(j\)满足\(\lverti-j\rvert=1\)并交换\(A_i\)和\(A_j\)。找到最小的操作数使\(......
  • 单向链表
    1.概念链表就是将结点用链串起来的线性表,链就是结点中的指针域。2.接口实现对比操作顺序表的结构体定义用来操作顺序表的结构体定义structSeqList{  intdata[10]; //顺序表  intlast;}用来操作有头单向链表的结构体定义structLinkListNode{  intdata......
  • list 容器(链表)
    1.list基本概念链表(list)是一种物理存储单元上的非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的;将数据进行链式存储。  是一个双向循环链表;链表由一系列结点组成;结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点的指针域;优......
  • 一文学会链表双指针技巧
    1.合并两个有序链表21.合并两个有序链表将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0]提示:两......
  • day04 - 链表part02
     24. 两两交换链表中的节点/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val(0),next(nullptr){}*ListNode(intx):val(x),next(nullptr){}*ListNode(intx,ListNode......
  • 一文玩转MQTT (ESP8266 DHT11 MQTT MYSQL方案)
    本文我们来聊一聊esp8266利用mqtt协议进行通信。并将数据数据存入数据库的操作。关于MQTTMQTT(消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,MQTT最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。搭建MQTT服务器......