簡體   English   中英

如何通過使用指針更改雙鏈表中的2個節點? C

[英]How to change 2 nodes in a double Linked List by using pointers? C

問題是這樣的:我必須通過更改節點(沒有其中的值)來對雙鏈表進行排序。 因此,可以說我有以下列表:

struct DataNode {
    char* name;
    int number;
};

struct QSNode {
    DataNode* data;
    QSNode* prev;
    QSNode* next;
};

我用數據創建3個節點:(A 1,B 2,C 3)。

現在,我想做的是將A 1與C 3互換,這樣看起來像這樣(C 3,B 2,A 1),但不更改值,而是更改實際節點。 現在,我通過使用以下功能來做到這一點:

QSNode* interchangeNodes(QSNode* list, QSNode* first, QSNode* second) {
    QSNode* mark1 = first;
    QSNode* mark2 = second;

    first->next = second->next;
    second->next = first;
    first->prev->next = second;
    second->prev = first->prev;
    second->next->prev = first;
    first->prev = second;
    QSNode* mark3 = second;
        second = first;
        first = mark3;


    if (mark1 == list)
         return first;
    else
    if (mark2 == list)
        return second;
    else 
    if (mark2 == list->prev){
        list->prev = second;
        return list;
    }
    else
        return list;    
}

為什么看起來像這樣? 因為即使我更改了節點,也說:C 3,B 2,A 1,所以我希望C 3成為我的標頭。 因此,當我調用該函數預覽列表中的數據時,C 3將是第一個。

void previewList(QSNode* list) {

    QSNode* marker = list;  
    while (list->next != marker) {
        cout << "Name: " << list->data->name << " Number: " << list->data->number << endl;
        list = list->next;
    }
    cout << "Name: " << list->data->name << " Number: " << list->data->number << endl;
}

好的,現在是問題所在。 當我嘗試對它進行排序時(不是要破壞列表並重新排列它,而是要更改節點的指針。)

好的,問題是我嘗試了很多選擇,此時我不關心復雜性,因此冒泡排序可以工作。 問題在這里:

QSNode* sortFinale1(QSNode* list){
    int count = 1;
    QSNode * tmp = list;
    while (tmp->next != list) {
        if (tmp->data->number > tmp->next->data->number){
            list = interchangeNodes(list, tmp, tmp->next);
        }
        tmp = tmp->next;
    }
    return list;
}

注意:此函數僅是一個測試函數,它表明一次迭代后未指向一個節點。

我嘗試制作一個tmp,以便我的列表保持不變並表現為數組。 但是問題是我失去了聯系。 輸入:

Name4 3
Name3 4
Name2 1
Name1 2

預覽列表輸出&&調用sortFinale1函數:

在此處輸入圖片說明

輸出與互換:

在此處輸入圖片說明

我的猜測是我在sortFinale1條件下丟失了一些東西。

這是用C語言快速解決您的問題的方法。

包括:交換和排序(合並排序)。

希望能幫助到你 :)

#include <stdlib.h>
#include <stdio.h>

typedef struct      DataNode {
    char*           name;
    int             number;
}                   DataNode;

typedef struct      QSNode {
    DataNode*       data;
    struct QSNode*  prev;
    struct QSNode*  next;
}                   QSNode;

void            node_swap(QSNode **head, QSNode *first, QSNode *second)
{
    QSNode  *tmp;

    if (first->next != NULL)
        first->next->prev = second;
    if (first->prev != NULL)
        first->prev->next = second;

    if (second->next != NULL)
        second->next->prev = first;
    if (second->prev != NULL)
        second->prev->next = first;
    tmp = first->next;
    first->next = second->next;
    second->next = tmp;

    tmp = first->prev;
    first->prev = second->prev;
    second->prev = tmp;
    if (first == *head)
        *head = second;
}

DataNode        *new_data(char *name, int nr)
{
    DataNode    *result;

    result = (DataNode*)malloc(sizeof(DataNode));
    result->name = name;
    result->number = nr;
    return (result);
}

QSNode          *new_node(DataNode *data)
{
    QSNode  *result;

    result = (QSNode*)malloc(sizeof(QSNode));
    result->next = NULL;
    result->prev = NULL;
    result->data = data;
    return (result);
}

void            add_node(QSNode **head, QSNode *new_node, QSNode *prev)
{
    if (*head == NULL)
    {
        *head = new_node;
        new_node->prev = prev;
    }
    else
        add_node(&((*head)->next), new_node, *head);
}

void            print_list(QSNode *head)
{
    if (head)
    {
        printf("%d\n", head->data->number);
        if (head->prev)
            printf("\tprev: %d\n", head->prev->data->number);
        else
            printf("\tprev: NULL\n");
        printf("\n");
        print_list(head->next);
    }
}

/*
** Merge sort
*/

static void     arrange_prev_vals(QSNode *head, QSNode *prev)
{
    if (head != NULL)
    {
        head->prev = prev;
        arrange_prev_vals(head->next, head);
    }
}

static void     front_back_split(
                    QSNode *source,
                    QSNode **front_ref,
                    QSNode **back_ref)
{
    QSNode  *fast;
    QSNode  *slow;

    if (source == NULL || source->next == NULL)
    {
        *front_ref = source;
        *back_ref = NULL;
    }
    else
    {
        slow = source;
        fast = source->next;
        while (fast != NULL)
        {
            fast = fast->next;
            if (fast != NULL)
            {
                slow = slow->next;
                fast = fast->next;
            }
        }
        *front_ref = source;
        *back_ref = slow->next;
        slow->next = NULL;
    }
}

static QSNode   *sorted_merge(QSNode *a, QSNode *b, int (*cmp)(DataNode*, DataNode*))
{
    QSNode  *result;

    if (a == NULL)
        return (b);
    else if (b == NULL)
        return (a);
    if (cmp(a->data, b->data) > 0)
    {
        result = a;
        result->next = sorted_merge(a->next, b, cmp);
    }
    else
    {
        result = b;
        result->next = sorted_merge(a, b->next, cmp);
    }
    return (result);
}

void            ft_lst_merge_sort(QSNode **head_ref, int (*cmp)(DataNode*, DataNode*))
{
    QSNode  *head;
    QSNode  *a;
    QSNode  *b;

    head = *head_ref;
    if (head == NULL || head->next == NULL)
        return ;
    front_back_split(head, &a, &b);
    ft_lst_merge_sort(&a, cmp);
    ft_lst_merge_sort(&b, cmp);
    *head_ref = sorted_merge(a, b, cmp);
    arrange_prev_vals(*head_ref, NULL);
}

/*
** A function used to compare nodes
*/

int     cmp_numbers(DataNode *data1, DataNode *data2)
{
    return (data2->number - data1->number);
}

int     cmp_rev_numbers(DataNode *data1, DataNode *data2)
{
    return (data1->number - data2->number);
}


int     main()
{
    QSNode *head;
    QSNode  *swap1;
    QSNode  *swap2;

    head = NULL;
    add_node(&head, new_node(new_data("1", 1)), NULL);
    add_node(&head, new_node(new_data("2", 2)), NULL);
    add_node(&head, new_node(new_data("3", 3)), NULL);
    add_node(&head, new_node(new_data("4", 4)), NULL);
    add_node(&head, new_node(new_data("5", 5)), NULL);

    /*
    ** Swap demonstration
    */

    swap1 = head;                           //node 1
    swap2 = head->next->next->next->next;   //node 5

    printf("Swaping: %d with %d\n", swap1->data->number, swap2->data->number);
    node_swap(&head, swap1, swap2);
    print_list(head);

    /*
    ** Sort demonstration
    */

    printf("Sorting ascending:\n");
    ft_lst_merge_sort(&head, &cmp_numbers);

    print_list(head);
    printf("Sorting descending:\n");
    ft_lst_merge_sort(&head, &cmp_rev_numbers);

    print_list(head);
}

結果:

Swaping: 1 with 5
5
    prev: NULL

2
    prev: 5

3
    prev: 2

4
    prev: 3

1
    prev: 4

Sorting ascending:
1
    prev: NULL

2
    prev: 1

3
    prev: 2

4
    prev: 3

5
    prev: 4

Sorting descending:
5
    prev: NULL

4
    prev: 5

3
    prev: 4

2
    prev: 3

1
    prev: 2

(代表OP張貼)

問題出在交換功能上

正確的功能:

QSNode* test123(QSNode* list, QSNode* first, QSNode* second) {
QSNode* mark1 = first;
QSNode* mark2 = second;
first->prev->next = second;
second->next->prev = first;

first->next = second->next;
second->next = first;
second->prev = first->prev;
first->prev = second;

if (mark1 == list)
    return second;
else
if (mark2 == list)
    return first;
else
    return list;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM