反转链表的每个k个节点

时间:2015-12-25 20:41:31

标签: c

我有两个反转链表的实现。第一个定义为Node * Reverse(Node * head,int k)方法。此方法会反转链表的每个k个备用子组。

Example: Inputs: 1->2->3->4->5->6->7->8->NULL and k = 3
Output: 3->2->1->6->5->4->8->7->NULL

另一个实现定义为kAltReverse(Node * head,int k)。此函数反转每个k节点,但随后跳过下一个k节点,并对下一个k节点执行相同操作。

 Example Input: 1->2->3->4->5->6->7->8->9->NULL and k = 3
 Output: 3->2->1->4->5->6->9->8->7->NULL 

这是我的代码,它定义了Node结构和两个函数Reverse和kAltReverse

// This is the definition of node structure
typedef struct container{
    int data;
    struct container *next;
} Node;


 Node *reverse(Node *head, int k){
    Node *temp = head;
    Node *curr = head;
    Node *prev = NULL;
    Node *next = NULL;
    int count = 0;

    // Reverses the first k nodes iteratively
    while (curr != NULL && count < k){
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
            count++;
    }

    // Recursively linking the head of the list to next reversed list.
    if (next != NULL) temp->next = reverse(next,k);
    return prev;
}


Node *kAltReverse(Node *head, int k){
    Node *temp = head;
    Node *curr = head;
    Node *prev = NULL;
    Node *next = NULL;
    int count = 0;

    // Reverse the first k node of the linked list
    while (curr != NULL && count < k){
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
            count++;
    }

    // Now head points to the kth node. So change next of head to (k+1)th node
    if (head != NULL) temp->next = curr;
    count = 0;

    //Move the pointer node so as to skip next k nodes.
    while(curr != NULL && count < k-1){
            curr = curr->next;
            count++;
    }

    // Recursively call for the list starting from curr->next.
    // And make rest of the list as next of first node.
    if (curr != NULL) curr->next = kAltReverse(curr->next,k);


    return prev;
}

int main(){
    Node *head1 = NULL;
    /* Insert function is a function for pushing the element in stack 
       like fashion on to the list*/
    insertFirst(&head1, 6);
    insertFirst(&head1, 4);
    insertFirst(&head1, 3);
    insertFirst(&head1, 2);
    insertFirst(&head1, 1);
    insertFirst(&head1, 5);
    // So the list will be 5->1->2->3->4->6->NULL

    // Now when I call the functions Reverse and kAltReverse I get undesired 
    // output.
    printlist(head1);
    Node *Reverse = reverse(head1, 2);
    printlist(Reverse);
    Node *kAlt1 = kAltReverse(head1,2);
    printlist(kAlt1);
    return 0;
}

我得到的输出是:

  5 1 2 3 4 6  // This is the original list 

  1 5 3 2 6 4  // This is the output given by Reverse method

  3 5 2 6 4    // This is the output given by kAltReverse method

但是,如果我单独调用它们并注释掉另一种方法,我得到所需的输出,即

Output from reverse: 1 5 3 2 6 4 // This is correct

Output form kAltReverse as: 1 5 2 3 6 4 // This is correct too.

所以他们分开工作,但不能一起工作。

我无法弄清楚为什么在同时调用它们时会发生这种情况。另一方面,当这些方法彼此独立地调用时,它们给出适当的输出。请帮忙。

1 个答案:

答案 0 :(得分:1)

您不会更改head,但您会更改(重新排序)列表中的内部节点。在致电printlist(head1)后尝试拨打reverse,您就会看到它。                      - 一些程序员老兄

按值使用调用不会创建整个链接链表的副本。它只适用于头节点的副本。在函数reverse(head1, 2);的框架中,head1的副本用于函数的上下文中,head1保持不变。我们称这个副本为head1f。如果调用head1f.data=42,则head1.data保持不变。但如果使用head1f.next->data=42head1.next->data现在为42:head1f.nexthead1.next指向相同的Node。                      - 弗朗西斯