簡體   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