合并排序双向链表

时间:2018-05-24 11:28:40

标签: algorithm

链接列表伪代码可以在CLRS的算法介绍中找到 但如果你非常想要我可以将其重写为链表的演示

//node structure
 struct node
 {
    int key;
    struct node *next;
    struct node *prev;        
 };
 typedef struct node node;

void split(node *head,node **front,node **back)
{
    node *slow,*fast;

    if(head == NULL || head->next == NULL)
    {
        (*front) = head;
        (*back) = NULL;
    }
    else
    {
        slow = head;
        fast = head->next;
        while(fast != NULL)
        {
            fast = fast->next;
            if(fast != NULL)
            {
                slow = slow->next;
                fast = fast->next;
            }
        }
        (*front) = head;
        (*back) = slow->next;
        slow->next = NULL;
    }
}

void merge(node **head,node *l1,node *l2)
{
    node *newHead, *curr;

    if(l1 == NULL)
        newHead = l2;
    else if(l2 == NULL)
            newHead = l1;
         else
         {
             if(l2->key < l1->key)
             {
                 newHead = l2;
                 l2 = l2->next;
             }
             else
             {
                newHead = l1;
                l1 = l1->next; 
             }
             curr = newHead;
             while(l1 != NULL && l2 != NULL)
             {
                 if(l2->key < l1->key)
                 {
                     curr->next = l2;
                     l2 = l2->next;
                 }
                 else
                 {
                     curr->next = l1;
                     l1 = l1->next;
                 }
                 curr = curr->next;
             }
             if(l1 == NULL)
                curr->next = l2;
            else
                curr->next = l1;
         }
         (*head) = newHead;
}

void mergeSort(node **head)
{
    node *h1 = NULL;
    node *h2 = NULL;

    if((*head) != NULL && (*head)->next != NULL)
    {
        split((*head),&h1,&h2);
        mergeSort(&h1);
        mergeSort(&h2);
        merge(head,h1,h2);
    }
}

如何正确设置prev指针?

我尝试在分割函数中将第二个头的prev指针设置为NULL    prev [back]&lt; - NULL

我看到了极客们的递归合并功能,并尝试设置这样的上传指针

prev [next [l2]]&lt; - l2
prev [l2]&lt; - NULL;

上一页[下一页[l1]]&lt; - l1
prev [l1]&lt; - NULL;

这并没有正确设置上限指针 这里我用了CLRS风格的伪代码

1 个答案:

答案 0 :(得分:0)

我想我是靠自己做的 由于prev指针的原因,我不得不逐节点地追加列表的其余部分

void split(node *head,node **front,node **back)
{
    node *slow, *fast;
    if(head == NULL || head->next == NULL)
    {
        (*front) = head;
        (*back) = NULL;
    }
    else
    {
        slow = head;
        fast = head->next;
        while(fast != NULL)
        {
            fast = fast->next;
            if(fast != NULL)
            {
                slow = slow->next;
                fast = fast->next;
            }
        }
        (*front) = head;
        (*back) = slow->next;
        (*back)->prev = NULL;
        slow->next = NULL;
    }
}

void merge(node **head,node *l1,node *l2)
{
    node *newHead,*curr;
    if(l1 == NULL)
        newHead = l2;
    else if(l2 == NULL)
        newHead = l1;
    else
    {
        if(l2->key < l1->key)
        {
            newHead = l2;
            l2 = l2->next;
        }
        else
        {
            newHead = l1;
            l1 = l1->next;
        }
        newHead->prev = NULL;
        curr = newHead;
        while(l1 != NULL && l2 != NULL)
        {
            if(l2->key < l1->key)
            {
                curr->next = l2;
                l2->prev = curr;
                l2 = l2->next;
            }
            else
            {
                curr->next = l1;
                l1->prev = curr;
                l1 = l1->next;
            }
            curr = curr->next;
        }
        while(l1 != NULL)
        {
            curr->next = l1;
            l1->prev = curr;
            l1 = l1->next;
            curr = curr->next;
        }
        while(l2 != NULL)
        {
            curr->next = l2;
            l2->prev = curr;
            l2 = l2->next;
            curr = curr->next;
        }
    }
    (*head) = newHead;
}

void mergeSort(node **head)
{
    node *h1 = NULL;
    node *h2 = NULL;
    if((*head) != NULL && (*head)->next != NULL)
    {
        split((*head),&h1,&h2);
        mergeSort(&h1);
        mergeSort(&h2);
        merge(head,h1,h2);
    }
}