struct cnode
{
int info;
struct cnode *next;
struct cnode *previous;
};
typedef struct cnode cnode;
预先制作的DOUBLY LINKED LIST:1<->2<->3<->4<->5<->6<->7
所以我试图创建一个递归函数来抓取双向链表(root = 4)的中间位置并将其转换成剩余的二进制树。我还不熟悉递归,所以对代码的解释会非常感激!
EX. 4
/ \
2 6
/ \ / \
1 3 5 7
这是我到目前为止的代码(由于递归困难,这个代码并不多)
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;
}
}
几乎只是将头部指针设置为中间信息(4)
答案 0 :(得分:1)
我想我理解;你从 cnodes 制作一个平衡的二叉树,其中上一个和下一个指针被重复用于左右子树。
...这就是你的算法。
将右半边变为二叉树;这是以中间&gt;下一个为首的。将其设为 middle-&gt; next 的新值。
您必须将原始头部保留为指向左侧子树的指针。
这会让你转向解决方案吗?
答案 1 :(得分:0)
首先,您正在尝试将DLL转换为二叉树,假设DLL是按照您必须生成的二叉树的顺序给出的。请注意,只有顺序遍历才能生成唯一的树。即使您必须生成BST,也不能仅通过顺序遍历来实现。我实际上认为你要做的是将其转换为平衡的BST。即便如此,它也不会是独一无二的
这是算法..
1)获取链表的中间部分并将其设为root
2)左半部分和右半部分递归相同
a)获得左半部分的中间部分,使其成为根部的孩子
在步骤1中创建
b)获得右半部分的中间位置并使其成为正确的孩子
在步骤1中创建的root。
时间复杂度:O(nLogn)其中n是链表中的节点数
虽然如果你在BST中以与双链表中出现的顺序相同的顺序插入节点,它可以在O(n)中求解。
答案 2 :(得分:0)
我希望这段代码对您有所帮助。用双向链表的头调用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;
}