在C中的单链表中交换位置

Posted

技术标签:

【中文标题】在C中的单链表中交换位置【英文标题】:Swap position in singly linked list in C 【发布时间】:2013-11-29 03:37:53 【问题描述】:

我被分配在 C 语言中为链表创建各种方法。我卡在 swap 方法上,它似乎只是弄乱了整个链表。有人对我哪里出错有任何建议吗?干杯!

这是我的代码。

int main(int argc, char* argv[])

    // A list of  pointers to Reminders 
    const int MAX_ENTRIES = 10;
    int numOfEntries = 0 ;
    reminder_t* pFirst = (reminder_t*) malloc ( sizeof(reminder_t));
    reminder_t* pSecond = (reminder_t*) malloc ( sizeof(reminder_t));
    reminder_t* pThird = (reminder_t*) malloc ( sizeof(reminder_t));
    reminder_t* pStart = NULL;
    if (pFirst != NULL)
    
        strcpy( pFirst->message, "Mikes Birthday");
        pFirst->dateOfEvent.day= 1;
        pFirst->dateOfEvent.month= 1;
        pFirst->dateOfEvent.year= 2013;
        pFirst->pNext = NULL;
    

    if (pSecond != NULL)
       
        strcpy( pSecond->message, "Als Soccer Match");
        pSecond->dateOfEvent.day= 2;
        pSecond->dateOfEvent.month= 2;
        pSecond->dateOfEvent.year= 2013;
        pSecond->pNext = NULL;
    

    if ( pThird != NULL)
    
        strcpy( pThird->message, "School Concert");
        pThird->dateOfEvent.day= 3;
    pThird->dateOfEvent.month= 3;
    pThird->dateOfEvent.year= 2013;
    pThird->pNext = NULL;


pFirst->pNext = pSecond;
pSecond->pNext = pThird;
pThird->pNext = NULL;
pStart = pFirst;

printf("\n------Before------\n");
listEntries(pStart);
swapPositonOf(pFirst,pThird);

printf("\n------After-aa-----\n");
listEntries(pStart);

getchar();
return 0;


void listEntries(reminder_t * pList) 

    printf("\n");
    while (pList != NULL)
    
            printf("%s\n", pList->message);
        pList = pList->pNext;
    


void swapPositonOf(reminder_t* first , reminder_t* second)

    reminder_t* pFirst = (reminder_t*) first;
reminder_t* pSecond = (reminder_t*) second;
reminder_t* temp = second->pNext;

pSecond->pNext = pFirst->pNext;
pFirst->pNext = temp;
temp = pSecond;
pSecond = pFirst;
pFirst = temp;

预期输出:

------Before------

Mikes Birthday
Als Soccer Match
School Concert

------After-aa-----
School Concert
Als Soccer Match    
Mikes Birthday

输出:

------Before------

Mikes Birthday
Als Soccer Match
School Concert

------After-aa-----

Mikes Birthday

【问题讨论】:

请提供更多信息:当您对列表进行排序时会发生什么?输入、输出和预期输出是什么? 除了swap函数和提醒定义之外的代码真的有必要吗? 为什么swapPositionOf开头有多余的演员表? (为什么将first 分配给pFirst 和第二个?) 【参考方案1】:

如果你想交换列表节点的内容,那并不难:你可以对两个节点中的messagedateOfEvent字段进行交换。

但是如果你想交换这些节点的位置(正如函数名所暗示的那样),那么你必须注意pNext数据成员。 事实上,仅仅交换节点指针是不够的。 您需要找到节点 before firstlast 的位置,然后执行以下操作:

/* reminder_t* beforeFirst, reminder_t* beforeSecond */
beforeFirst->pNext = second;
beforeSecond->pNext = first;

并交换 first->pNextsecond->pNext

此外,在这些列表实现中,通常需要注意特殊情况,例如头节点和尾节点。

【讨论】:

我必须交换位置,抱歉,我应该在问题中说明这一点。稍后将需要使用此方法进行排序。 没问题,看交换函数的名字就很清楚了。并且交换指针比交换有效载荷更快;链表节点交换确实有意义。 好吧,我的讲师给出了空函数:void swapPositonOf(reminder_t* first ,reminder_t* second) 或者可能是 int swapPositonOf(reminder_t* first ,reminder_t* second) 那么 LinkedList 如何获得前一个(据我所知,它不能是一个双向链表,我会在周一的课堂上询问以确保)【参考方案2】:

您并未修改 firstsecond 节点之前的节点的 pNext 指针。

您需要将“first节点”之前的节点的pNext指向“second节点”,反之亦然。

假设链表:

Node_A -> Node_B -> Node_C -> Node_D -> Node_E

您必须交换 Node_B 和 Node_D: 断开和形成的链接总数:

    旧链接:Node_A -> Node_B.... 新链接:Node_A -> Node_D 旧链接:Node_B -> Node_C.... 新链接:Node_D -> Node_C 旧链接:Node_C -> Node_D.... 新链接:Node_C -> Node_B 旧链接:Node_D -> Node_E.... 新链接:Node_B -> Node_E

还要记住一些极端情况,如 NULL 指针和连续节点。

【讨论】:

【参考方案3】:

对于单链表,您无法直接定位要交换的元素之前的列表元素。你有first,second,你可以直接操作它们,但是你没有first.prev和second.prev。

您需要遍历您的列表,并找到要交换的两个节点之前的节点(first_previous,second_previous)。然后,您的节点交换还需要交换每个先前节点中的下一个。

reminder_t* first_prev, *second_prev;
first_prev = second_prev = pStart;
reminder_t* iter;
for( iter = pStart; iter; iter=iter->next )

    if( iter->next == first ) first_prev = iter;
    if( iter->next == second ) second_prev = iter;

您需要修复上述问题以处理空列表、一个元素列表以及在列表头部传递第一个或第二个...

【讨论】:

构造单链表的一种方法是让最后一个元素的 next 指针指向第一个元素(循环列表)。然后你可以遍历给定任何一个元素的整个列表。【参考方案4】:

您没有正确交换它,那么第一个节点之前的节点和第二个节点之前的节点呢?

【讨论】:

以上是关于在C中的单链表中交换位置的主要内容,如果未能解决你的问题,请参考以下文章

交换单链表中的节点

数据结构之单链表的增删查改等操作画图详解

c_cpp C中的单链表 - 现在只实现交换

DS单链表--结点交换

单链表~增删查改(附代码)~简单实现

c_cpp 单链表中的替代奇数和偶数节点