c - 在双向链表中交换

标签 c swap doubly-linked-list

我正在尝试交换双向链表中的两个节点。下面是具有交换功能的程序部分。

 int swap (int x, int y)
{
    struct node *temp = NULL ;
    struct node *ptr1, *ptr2;
    temp = (struct node *)malloc(sizeof(struct node));


    if (head == NULL )
    {
        printf("Null Nodes");

    }
    else
    {
        ptr1 = ptr2 = head;

        int count = 1;
        while (count != x)
        {
            ptr1 = ptr1->next;
            count++;

        }



        int count2 = 1;
        while (count2 != y)
        {
            ptr2 = ptr2->next;
            count2++;   

        }       


        ptr1->next->prev = ptr2;
        ptr1->prev->next = ptr2;
        ptr2->next->prev = ptr1;
        ptr2->prev->next = ptr1;

    temp->prev = ptr1->prev;
    ptr1->prev = ptr2->prev;
    ptr2->prev = temp->prev;

    temp->next = ptr1->next;
    ptr1->next = ptr2->next;
    ptr2->next = temp->next;


    }
    return 0;
}

当我运行这个程序时,在第一个和第二个节点的情况下,它崩溃了。而对于任何其他节点,它会提供无限循环输出。 (例如:- 2->4 2->4 2->4....等等)`。

我知道还有一些关于节点交换的问题,但我没有找到与我的问题类似的问题。请帮帮我..!!

提前致谢。

最佳答案

如果 ptr1 == head (ptr1->prev == NULL) 或 ptr2 == head (ptr2->prev == NULL),代码将失败,因为它最终会尝试使用 head->next,这不会'存在。如果 ptr1->next == NULL 或 ptr2->next == NULL,也需要检查列表的结尾,这可以使用局部尾指针来处理。使用指向节点指针的指针可以简化代码。例如,指向指向 ptr1 的下一个指针的指针可以是 &ptr1->prev->next 或 &head。指向指向 ptr2 的 prev 指针的指针可以是 &ptr2->next->prev 或 &tail(并设置 tail = ptr2)。

使用指向节点指针的指针解决了交换相邻节点的问题。 temp 也可以是指向节点的指针。

使用指向节点(而不是计数)的指针进行交换的示例代码:

typedef struct node NODE;
/* ... */
NODE * SwapNodes(NODE *head, NODE *ptr1, NODE *ptr2)
{
NODE **p1pn;            /* & ptr1->prev->next */
NODE **p1np;            /* & ptr1->next->prev */
NODE **p2pn;            /* & b->prev->next */
NODE **p2np;            /* & b->next->prev */
NODE *tail;             /* only used when x->next == NULL */
NODE *temp;             /* temp */
    if(head == NULL || ptr1 == NULL || ptr2 == NULL || ptr1 == ptr2)
        return head;
    if(head == ptr1)
        p1pn = &head;
    else
        p1pn = &ptr1->prev->next;
    if(head == ptr2)
        p2pn = &head;
    else
        p2pn = &ptr2->prev->next;
    if(ptr1->next == NULL){
        p1np = &tail;
        tail = ptr1;
    } else
        p1np = &ptr1->next->prev;
    if(ptr2->next == NULL){
        p2np = &tail;
        tail = ptr2;
    }else
        p2np = &ptr2->next->prev;
    *p1pn = ptr2;
    *p1np = ptr2;
    *p2pn = ptr1;
    *p2np = ptr1;
    temp = ptr1->prev;
    ptr1->prev = ptr2->prev;
    ptr2->prev = temp;
    temp = ptr1->next;
    ptr1->next = ptr2->next;
    ptr2->next = temp;
    return head;
}

关于c - 在双向链表中交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32578455/

相关文章:

Groovy 交换变量,如 ruby

c - 自动删除双向链表中的元素

c++ - C/C++ 从根位置搜索文件夹并返回绝对路径

c - SIGSEGV 在 C 中运行函数时出错

c - 从 C 中的 argv[i] 检查 fopen 时出错

C++ - 自定义类型的交换功能不起作用

swift - 我如何交换对象属性 Swift

algorithm - 为链表插入伪代码

c++ - 将文本文件读入双向链表并输出 - C++

c++ - 第一学期 CS 学生需要帮助理解 While 循环中的语句