繁体   English   中英

交换反转c中的链表

[英]Swap reversing a linked list in c

给定一个列表,我想通过将第一个与最后一个交换,第二个与第二个倒数交换,以反转列表,依此类推。

我写了这个函数来交换每对,其中pos1pos2是要交换的两个位置。

maxPos是两个位置中最大的一个, node1node2是遍历列表后找到的两个节点。

int swap(struct node *list, int pos1, int pos2) {

    if (node1 != NULL && node2 != NULL) {
        if (prev1 != NULL)
            prev1->next = node2;
        if (prev2 != NULL)
            prev2->next = node1;
        temp        = node1->next;
        node1->next = node2->next;
        node2->next = temp;
        if (prev1 == NULL)
            head = node2;
        else if (prev2 == NULL)
            head = node1;
    }
    return 1;
}

而不是为每个对递归调用它,即。 (1,n-1)(2,n-2)(3,n-3)每次都必须遍历该列表,我想知道是否有办法迭代地解决它。

您真的要交换节点内容吗?

您可以使用一个非常简单的函数来迭代地反转列表:

struct node {
    // whatever payload fields...
    struct node *next;
};

struct node *reverse_list(struct node *list) {
    struct node *last = NULL;
    while (list != NULL) {
        struct node *next = list->next;
        list->next = last;
        last = list;
        list = next;
    }
    return last;
}

当使用带有锚元素的列表(例如,第一个元素是节点但不用于存储数据)时,可以使用

struct node **list_nth(struct node *node, size_t idx)
{
    for (;idx > 0 && node; --idx)
        node = node->next;

    return node ? &(node->next) : NULL;
}

void list_swap(struct node *head, size_t idx_a, size_t idx_b)
{
    struct node **a = list_nth(head, min(idx_a, idx_b));
    struct node **b = list_nth(head, max(idx_a, idx_b));
    struct node *tmp;

    if (idx_a == idx_b)
        return;

    if (!a || !b)
        abort();

    if ((*a)->next == *b) {
        tmp = *a;

        *a  = *b;
        tmp->next = (*b)->next;
        (*a)->next = tmp;
    } else {
        tmp        = (*a)->next;
        (*a)->next = (*b)->next;
        (*b)->next = tmp;

        tmp = *a;
        *a  = *b;
        *b  = tmp;
    }
}

用于交换操作。 但是对于单个链表,由于昂贵的节点查找,您的反向操作的复杂度为O(n ^ 2)。

如其他地方所述,要反转列表:

  • 使用双链接的
  • 用O(n)反向迭代
  • 删除元素(O(1))
  • 将元素附加到新的头(O(1))
  • 将新列表合并到旧列表中(O(1))

您必须声明一个新方法来反转整个列表,该方法将仅被调用一次。 同样,您最好使用双链表来解决此问题。

节点结构:

struct node {
    int data;
    struct node *next;
    struct node *prev;
};

方法:

void reverse() {

    struct node *temp = head; // assuming you have the head node as a global variable.
    struct node *lastPtr = head;

    for (int i = 0; i < len; i++) { // assuming you have length as a global variable.
        lastPtr = lastPtr->next;
    }

    for (int i = 0; i < len / 2; i++) {
        temp->data += lastPtr->data;
        lastPtr->data = temp->data - lastPtr->data;
        temp->data -= lastPtr->data;
        temp = temp->next;
        lastPtr = lastPtr->prev;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM