简体   繁体   English

如何将双链表转换为二叉树

[英]How to convert Doubly linked list to Binary tree

    struct cnode
{
  int info;
  struct cnode *next;
  struct cnode *previous;
};
typedef struct cnode cnode;

pre-made DOUBLY LINKED LIST: 1<->2<->3<->4<->5<->6<->7 预制双链表: 1<->2<->3<->4<->5<->6<->7

So I'm trying to make a recursive function that grabs the mid of the doubly linked list (root = 4) and convert it into a the remaining into a binary tree. 因此,我试图创建一个递归函数,以获取双向链表的中间部分(根= 4)并将其转换为剩余的二进制树。 I'm still new to recursion so an explanation along with code would be GREATLY appreciated! 我仍然是递归的新手,因此非常感谢您提供解释和代码!

EX.     4
      /  \
     2    6
    / \  / \
   1   3 5  7

This is the code I have thus far (which isn't much due to difficulties with recursion) 这是我到目前为止的代码(由于递归方面的困难,使用该代码不会太多)

void *convert(cnode *head){
  if(head == NULL)
    return;
  int count = 0;
  cnode *tempHead = head;
  while(tempHead != NULL){
    count++;
    tempHead = tempHead->next;
  }
  int move = (count/2) + (count%2);
  int i;
  for(i=1; i<move; i++){
    head = head->next;
  }
}

Pretty much just sets the head pointer to the mid info (4) 几乎只是将头指针设置为中间信息(4)

I think I understand; 我想我明白; you're making a balanced binary tree from cnodes with the previous and next pointers being reused for the left and right sub-trees. 您正在通过cnodes创建一个平衡的二叉树,并且前一个下一个指针被重复用于左子树和右子树。

... so that's your algorithm. ...这就是您的算法。

  • Find the middle node of the binary tree (which you've already done). 找到二叉树的中间节点(您已经完成)。
  • Turn the left half into a binary tree. 将左半部分变成二叉树。 The left half is the original head, with the last element (middle->previous) now having a next pointer of NULL. 左半部分是原始头,最后一个元素(中间->上一个)现在具有下一个指针NULL。
  • Link this left half to middle->previous (hijacked as the left sub-tree). 将此左半部分链接到“ 中间”->“上一个” (劫持为左子树)。
  • Turn the right half into a binary tree; 将右半部分变成二叉树; this is headed by middle->next . 这是由middle-> next领导的。 Make it the new value of middle->next . 使其成为middle-> next的新值。

  • You have to keep the original head as the pointer to the left sub-tree. 您必须保留原始头部作为指向左侧子树的指针。

  • You'll want your routine to return the binary tree's root, so the previous call can link it into the level above. 您将希望例程返回二叉树的根,因此上一次调用可以将其链接到上面的级别。
  • You still have to pick a termination condition, such as the head pointer being NULL . 您仍然必须选择终止条件,例如头指针为NULL

Does that get you moving to a solution? 这会让您转向解决方案吗?

I hope this code will help you. 希望这段代码对您有所帮助。 call the DLL2BT method with head of the doubly linked list which return the root node of the tree created. 用双向链表的头调用DLL2BT方法,该方法返回创建的树的根节点。

class box
{
    int data;
    box left=null,right=null;
    box(int a)
    {
        data=a;
    }
}

public static box DLL2BT(box head)// head = linked list head
{       
    if(head!=null)
    {
        box node=null;
        try 
        {
            node = findMid(head);
            node.left.right=null;
            node.left=DLL2BT(head);
            node.right.left=null;
            node.right=DLL2BT(node.right);
        }
        catch( Exception e){ }
        return node;
    }
    return null;
}

public static box findMid(box head)
{
    box slow=head,fast=head.right;
    try
    {
        while(fast!=null)
        {
            slow=slow.right;
            fast=fast.right.right;
        }
    }
    catch(Exception e){ }
    return slow;
}

Firstly, You are trying to convert DLL to binary tree assuming the DLL is given as in-order of the binary tree you have to make. 首先,您要假定DLL是按必须生成的二叉树的顺序给出的,因此您尝试将DLL转换为二叉树。 Note that there isn't a unique tree you can make from only inorder traversal.Even if you have to make BST, you can't make it with only inorder traversal. 请注意,没有唯一的树可以仅通过顺序遍历来制作,即使必须进行BST也不能仅通过顺序遍历来制作。 What I actually think you are trying to do is to convert it into a balanced BST. 我实际上认为您正在尝试将其转换为平衡的BST。 Even though, it will also not be unique. 即使如此,它也不是唯一的。
Here's the algorithm.. 这是算法。
1) Get the Middle of the linked list and make it root. 1)获取链接列表的中间位置并使其成为根。
2) Recursively do same for left half and right half. 2)递归地对左半部分和右半部分进行相同的操作。
a) Get the middle of left half and make it left child of the root created in step 1. a)获取左半部分的中间位置,并将其设为在步骤1中创建的根的左子级。
b) Get the middle of right half and make it right child of the root created in step 1. b)获取右半部分的中间部分,并将其作为在步骤1中创建的根的正确子代。
Time complexity: O(nLogn) where n is the number of nodes in Linked List. 时间复杂度:O(nLogn)其中n是链表中的节点数。
Although,it can be solved in O(n) if you insert nodes in BST in the same order as the appear in Doubly Linked List. 但是,如果以与“双链表”中出现的顺序相同的顺序在BST中插入节点,则可以在O(n)中解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM