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

题目要求:


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


解题思路:

本题的本质即输出二叉搜索树的中序遍历,二叉搜索树的中序遍历就为一个排序好队列。

因此目前的问题转化为:如何进行二叉搜索树的中序遍历,并将其转换为双链表

分为三步:

(1)找到最底层的左叶子节点,并作为双向链表的头节点。

(2)对于不是头结点的点,调整链表指针,

          调整为:当前节点的左节点为上一个节点;上一个节点的右节点为当前节点;上一个节点指向本节点;

(3)跳转到当前节点的右节点


public class Solution {
   TreeNode head = null;
   TreeNode realhead = null;
   public TreeNode Convert(TreeNode root){
       ConverSub(root);
       return realhead;
   }
   private void ConverSub(TreeNode root){
       if(root == null){
           return;
       }
       ConverSub(root.left);
       if(head==null){
           head = root;
           realhead = root;
       }else{
           head.right = root;
           root.left = head;
           head = root;
       }
       ConverSub(root.right);
   }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 这道题目要求将二搜索转换一个排序双向链表,而且不能创建的节点,只能调整节点指针指向。具体实现可以按照以下步骤: 1. 定义一个全局变量prev,用来记录当前节点的前一个节点。 2. 递归遍历二搜索,对于每个节点,先递归处理其左子,然后将当前节点的左指针指向prev,如果prev不为空,则将prev的右指针指向当前节点。然后更prev为当前节点,最后递归处理右子。 3. 最后返回双向链表的头节点,即二搜索中最左边的节点。 代码如下: ``` TreeNode* prev = NULL; TreeNode* Convert(TreeNode* pRootOfTree) { if (pRootOfTree == NULL) { return NULL; } Convert(pRootOfTree->left); pRootOfTree->left = prev; if (prev != NULL) { prev->right = pRootOfTree; } prev = pRootOfTree; Convert(pRootOfTree->right); while (pRootOfTree->left != NULL) { pRootOfTree = pRootOfTree->left; } return pRootOfTree; } ``` ### 回答2: 题目要求我们将一棵二搜索转换一个排序双向链表,而且不能创建的节点,只能调整节点的指针指向。根据二搜索的性质,左子的所有节点的值都比根节点小,右子的所有节点的值都比根节点大。因此,我们可以采用中序遍历二的方式,将二搜索转换一个升序的节点序列。 具体的转换过程如下: 1. 采用中序遍历二,遍历过程中记录上一个节点指针pre和当前节点指针cur。 2. 对于第一个节点,将其指向左子中最后一个节点或者是NULL; 3. 对于中间的节点,将其前驱节点pre的right指针指向cur,后继节点cur的left指针指向pre; 4. 对于最后一个节点,将其指向右子中最先的节点或者是NULL。 转换后,根节点指向列表头部,右子中最后的节点指向列表尾部。这样就完了二搜索双向链表转换。 需要注意的是,如果原始的二搜索为空或者只有一个节点,那么转换得到的双向链表也为空或者只有一个节点。 总的来说,这道题目的关键在于使用中序遍历,由于是二搜索,所以遍历的果是一个有序的序列。在遍历的过程中,我们需要记录上一个节点和当前节点,以便进行后续指针操作。这样就可以避免创建的节点,而是直接调整原来节点的指针指向,将二搜索转换为一个双向链表。 ### 回答3: 该问题需要用到二的中序遍历,即先遍历节点的左子,再遍历根节点,最后遍历右子。因为二搜索的中序遍历是有序的,所以我们可以在中序遍历时将节点之间连接起来,形双向链表。 具体操作如下: 1. 定义一个全局变量pLastNodeInList,用于记录当前已经处理好的双向链表的最后一个节点。 2. 实现递归函数ConvertNode(TreeNode* pNode),该函数输一个节点,将它的子节点连接双向链表,并返回该双向链表的头节点。 3. 在ConvertNode函数中,如果左子节点不为空,则递归处理左子节点,将它所连接的双向链表的最后一个节点指向当前节点,更pLastNodeInList。 4. 如果pLastNodeInList为空,则说明当前节点是整个双向链表的头节点,直接将它赋值给pLastNodeInList。 5. 如果pLastNodeInList不为空,则将其指向当前节点,同时将当前节点的左指针指向pLastNodeInList。 6. 处理当前节点的右子节点,同样递归处理,并返回右子所连接的双向链表的头节点。 7. 如果右子所连接的双向链表的头节点不为空,则将当前节点的右指针指向该头节点。 8. 最后返回当前节点或双向链表的头节点。 实现后,我们可以遍历该双向链表,从头到尾输出各个节点,验证它们的顺序是否符合二搜索的中序遍历。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值