交换链表中的节点

时间:2017-07-04 11:21:05

标签: c data-structures linked-list swap singly-linked-list

我尝试使用函数(swapNodes)来交换链表中的节点。 在这里,我存储了要交换的节点的上一个和下一个地址。 但我的代码陷入无限循环。

这段代码可以作为工作代码制作,还是错误的方法?

#include<stdio.h>
#include<stdlib.h>
 struct Node
{
    int data;
    struct Node *next;
};
void push(struct Node** head_ref, int new_data)
{
    struct Node* new_node =
        (struct Node*) malloc(sizeof(struct Node));

    new_node->data  = new_data;
    new_node->next = (*head_ref);
    (*head_ref)    = new_node;
}


void printList(struct Node *node)
{
    while(node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
}

void swapNodes(struct Node** headr,int key1,int key2)
{
    struct Node* temp1 = *headr;
    struct Node* temp2 = *headr;

    if(key1 == key2)
    return;

    struct Node* prev1 =NULL;
    struct Node* next1 =temp1;
    while(temp1->data !=key1 && next1 !=NULL)
    {
    prev1 =temp1;
    temp1 =temp1->next;
    next1 =temp1->next;
    }
    struct Node* prev2 =NULL;
    struct Node* next2 =temp2;
    while(temp2->data !=key2 && next2 !=NULL)
    {
    prev2 =temp2;
    temp2 =temp2->next;
    next2 =temp2->next;
    }
    if(next1 == NULL||next2 == NULL)
    return;

    prev1->next =temp2;
    temp2->next =next1;
    prev2->next =temp1;
    temp1->next =next2;
}
int main()
{
    struct Node *start = NULL;

    push(&start, 7);
    push(&start, 6);
    push(&start, 5);
    push(&start, 4);
    push(&start, 3);
    push(&start, 2);
    push(&start, 1);

    printf("\n Linked list before calling swapNodes() ");
    printList(start);

    swapNodes(&start, 4, 3);

    printf("\n Linked list after calling swapNodes() ");
    printList(start);

    return 0;
}

2 个答案:

答案 0 :(得分:2)

该函数具有未定义的行为,因为它没有考虑到例如headr可以等于NULLprev1prev2可以等于{{ 1}}。

再写一个函数来查找与给定数据相对应的节点会更好。

然而,函数NULL可以通过以下方式编写。它找到要交换的节点,然后将指针交换到节点及其数据成员swapNodes

你在这里

next

这是一个示范程序。

void swap( struct Node **first, struct Node **second )
{
    struct Node *tmp = *first;
    *first = *second;
    *second = tmp;
}

void swapNodes( struct Node **headr, int key1, int key2 )
{
    if ( key1 == key2 ) return;

    struct Node **first = headr;

    while ( *first && ( *first )->data != key1 ) first = &( *first )->next;

    if ( *first == NULL ) return;

    struct Node **second = headr;

    while ( *second && ( *second )->data != key2 ) second = &( *second )->next;

    if ( *second == NULL ) return;

    swap( first, second );
    swap( &( *first )->next, &( *second )->next );
}

它的输出是

#include <stdio.h>
#include <stdlib.h>

struct Node
{
    int data;
    struct Node *next;
};

void push(struct Node** head_ref, int new_data)
{
    struct Node* new_node =
        (struct Node*) malloc(sizeof(struct Node));

    new_node->data  = new_data;
    new_node->next = (*head_ref);
    (*head_ref)    = new_node;
}

void printList(struct Node *node)
{
    while(node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
}

void swap( struct Node **first, struct Node **second )
{
    struct Node *tmp = *first;
    *first = *second;
    *second = tmp;
}

void swapNodes( struct Node **headr, int key1, int key2 )
{
    if ( key1 == key2 ) return;

    struct Node **first = headr;

    while ( *first && ( *first )->data != key1 ) first = &( *first )->next;

    if ( *first == NULL ) return;

    struct Node **second = headr;

    while ( *second && ( *second )->data != key2 ) second = &( *second )->next;

    if ( *second == NULL ) return;

    swap( first, second );
    swap( &( *first )->next, &( *second )->next );
}

int main( void ) 
{
    struct Node *start = NULL;

    push(&start, 7);
    push(&start, 6);
    push(&start, 5);
    push(&start, 4);
    push(&start, 3);
    push(&start, 2);
    push(&start, 1);

    printf("\n Linked list before calling swapNodes() ");
    printList(start);

    swapNodes(&start, 4, 3);

    printf("\n Linked list after  calling swapNodes() ");
    printList(start);

    return 0;
}

事实上,函数 Linked list before calling swapNodes() 1 2 3 4 5 6 7 Linked list after calling swapNodes() 1 2 4 3 5 6 7 在编写时(没有单独的函数来查找给定数据的节点)做了两件事:1)找到两个节点,然后2)交换它们。搜索节点可能不成功。因此该函数应该向用户报告节点是否被交换。在这种情况下,希望将函数声明为具有返回类型swapNodes

例如

int

如果要编写一个单独的函数来搜索上面提到的节点,那么交换节点的函数看起来会更清晰,更简单。

例如

int swapNodes( struct Node **headr, int key1, int key2 )
{
    int success = key1 != key2;

    if ( success )
    {        
        struct Node **first  = headr;
        struct Node **second = headr;

        while ( *first && ( *first )->data != key1 ) first = &( *first )->next;

        success = *first != NULL;

        if ( success )
        {            
            while ( *second && ( *second )->data != key2 ) second = &( *second )->next;

            success = *second != NULL;
        }

        if ( success )
        {            
            swap( first, second );
            swap( &( *first )->next, &( *second )->next );
        }
    }

    return success;
}

答案 1 :(得分:1)

你应该稍微改写一下{ ["98f13708210194c475687be6106a3b84"]=> array(10) { ["product_id"]=> int(20) ["variation_id"]=> int(0) ["variation"]=> array(0) { } ["quantity"]=> int(2) ["line_total"]=> float(3001.98) ["line_subtotal"]=> float(3001.98) ["line_tax"]=> int(0) ["line_subtotal_tax"]=> int(0) ["line_tax_data"]=> array(2) { ["total"]=> array(0) { } ["subtotal"]=> array(0) { } } ["data"]=> array(0) { } } }` 函数:

swapNodes

正如您所看到的,您不需要void swapNodes(struct Node** headr, int key1, int key2) { struct Node* temp1 = *headr; struct Node* temp2 = *headr; if(key1==key2) return; struct Node* prev1=NULL; while(temp1 && temp1->data!=key1) { prev1=temp1; temp1=temp1->next; } struct Node* prev2=NULL; while(temp2 && temp2->data!=key2) { prev2=temp2; temp2=temp2->next; } if(temp1==NULL || temp1==NULL) return; // temp1 is a head if (prev1 == NULL) { *headr = temp2; } else { prev1->next = temp2; } // temp2 is a head if (prev2 == NULL) { *headr = temp1; } else { prev2->next = temp1; } struct Node *buff = temp2->next; temp2->next = temp1->next; temp1->next = buff; } next1指针。但是您必须检查next2temp1是否是头部:当您需要将头部替换为另一个节点时,这是一种特殊情况。其余的都是微不足道的 - 只需通过缓冲节点交换节点。