当前位置: 首页 > 知识库问答 >
问题:

双向链表交换

郑西岭
2023-03-14

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

 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-

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

提前谢谢。

共有2个答案

邓正谊
2023-03-14

这可以被压缩,但是如果你有问题,详细地拼写出来会有所帮助。

typedef struct node Node;

void link( Node* a, Node* b )
{
    a->next = b;
    b->prev = a;
}

void swap_nodes( Node* a, Node* b )
{
    if(a==b) return; // don't swap with yourself

    // handle adjacent nodes separately
    if( a->next == b )
    {
        Node* bef = a->prev;
        Node* aft = b->next;
        link( bef, b);    // link bef, b, a, aft
        link( b, a );
        link( a, aft );
    }
    else if( b->next == a )
    {
        Node* bef = b->prev;
        Node* aft = a->next;
        link( bef, a);   // link bef, a, b, aft
        link( a, b );
        link( b, aft );
    }
    else
    {
        Node* a_prv = a->prev;
        Node* a_nxt = a->next;
        Node* b_prv = b->prev;
        Node* b_nxt = b->next;

        link( a_prv, b ); link( b, a_nxt ); // links b in a's old position
        link( b_prv, a ); link( a, b_nxt ); // links a in b's old position
    }
}

还要注意的是,您的head节点永远不应该是null,如果列表为空,它应该是一个链接到自身的sentry节点。这意味着永远不会有第一个节点,也不会有最后一个节点,列表也不会为空。这消除了大量的特殊情况。看这里

龚运乾
2023-03-14

如果ptr1==head(ptr1),代码将失败-

使用指针到节点的指针修复了交换相邻节点的问题。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;
}
 类似资料:
  • 本文向大家介绍双向链表和双向循环链表?相关面试题,主要包含被问及双向链表和双向循环链表?时的应答技巧和注意事项,需要的朋友参考一下 双向链表: 包含两个指针,一个prev指向前一个节点,一个next指向后一个节点。 双向循环链表: 最后一个节点的 next 指向head,而 head 的prev指向最后一个节点,构成一个环。

  • 主要内容:双向链表的创建目前我们所学到的 链表,无论是动态链表还是 静态链表,表中各节点中都只包含一个指针(游标),且都统一指向直接后继节点,通常称这类链表为 单向链表(或 单链表)。 虽然使用单链表能 100% 解决逻辑关系为 "一对一" 数据的存储问题,但在解决某些特殊问题时,单链表并不是效率最优的存储结构。比如说,如果算法中需要大量地找某指定结点的前趋结点,使用单链表无疑是灾难性的,因为单链表更适合 "从前往后"

  • 双向链表 结构体 struct   rt_list_node   双向链表节点 更多...   宏定义 #define  rt_container_of(ptr, type, member)   ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))   获取type结构体中member成员在这个结构体中的偏移   #de

  • 双向链表 Linux 内核自己实现了双向链表,可以在 include/linux/list.h 找到定义。我们将会从双向链表数据结构开始内核的数据结构。为什么?因为它在内核里使用的很广泛,你只需要在 free-electrons.com 检索一下就知道了。 首先让我们看一下在 include/linux/types.h 里的主结构体: struct list_head { struct l

  • 我试图交换链表中节点的位置,然后使用排序函数进行排序。这两个函数中的任何一个都有逻辑错误。当我运行这个程序时,它会无限循环。 更新代码

  • 双向循环链表 在“数据结构”课程中,如果创建某种数据结构的双循环链表,通常采用的办法是在这个数据结构的类型定义中有专门的成员变量 data, 并且加入两个指向该类型的指针next和prev。例如: typedef struct foo { ElemType data; struct foo *prev; struct foo *next; } foo_t; 双向循环链表的