如何在不使用C语言交换数据的情况下交换链表中的节点?

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

标签: c linked-list nodes swap doubly-linked-list

我使用这种排序功能,但我不知道如何交换节点地址而不是值。我使用双向链表。

谢谢

void sort(LISTnode **h) {
    LISTnode * start, * min, * temp;
    int num;
    start = *h;
    while (start->next != NULL) {
        temp = start;
        min = temp;
        temp = temp->next;

        while (temp != NULL) {
            if (temp->number < min->number)
                min = temp;
                temp = temp->next;
        }

        // This part of the code
        num = min->number;
        min->number = start->number;
        start->number = num;

        start = start->next;
    }    
}

2 个答案:

答案 0 :(得分:1)

交换两个节点(编辑:不相邻的节点! - 需要特殊处理,因为下面的代码会将所涉及的next / prev指针的一部分设置回相邻节点上的自己的对象! !):

x->prev->next = y;
x->next->prev = y;

y->prev->next = x;
y->next->prev = x;

现在节点改变了它们在列表中的位置,需要自己调整节点:

tmp = x->prev;
x->prev = y->prev;
y->prev = tmp;

tmp = x->next;
x->next = y->next;
y->next = tmp;

最后:调整头指针:

if(list->head == x)
{
    list->head = y;
}
else if(list->head == y)
{
    list->head = x;
}

完成...

嗯,只有一半:上面适用于双重和循环链接列表(您可以通过list->head->previous获取尾部)。如果您没有循环链接列表,请将相应的空指针检查添加到第一个代码部分(第二个您不需要的部分,假设x和y都不为空...)并对尾部进行头部调整也是。

旁注:由于必须调整头部(和尾部,如果需要),如果没有节点的父列表,则无法安全交换......

但是,必须进行相当多的指针调整。我宁愿考虑在节点内交换数据(尽管在你的问题中被明确排除!)。如果由于数据较大而不想这样做,则考虑将数据与节点分开存储,并让节点具有指向数据的指针。交换然后只是交换两个指针,你甚至不需要父母列表对象......

答案 1 :(得分:0)

替代方法..
而不是使用指针进行操作,使用双指针交换指针更容易..

void swap(Node* &a,Node* &b){
    Node* c=a,a=b,b=c;
}

void swapNodes(Node** head_ref, int x, int y)
{
    Node**a=NULL,**b=NULL;
    Node* head=*head_ref;
    while(head!=NULL){
        if(head->data==x)   *a=head;
        else if(head->data==y)  *b=head;
    }  
    if(a&&b){
        swap(*a,*b);
        swap((*a)->next,(*b)->next);
    }
}