【问题标题】:How to change 2 nodes in a double Linked List by using pointers? C如何使用指针更改双链表中的 2 个节点? C
【发布时间】:2017-04-12 08:27:18
【问题描述】:

问题是这样的:我必须通过更改节点(不是其中的值)来对双链表进行排序。 所以,假设我有这个列表:

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 3, B 2, C 3”而不是“C 3, B 2, A 1”吗?如果你想排序你通常 swap “元素”(在你的情况下是节点),并且名称“交换”也意味着节点相互交换位置。
  • 并且在双链表中交换节点其实很简单:跟踪两个节点的前一个节点和后一个节点,并让它们的前一个/下一个链接指向到交换中的另一个节点,最后更新您交换的节点以将它们的上一个/下一个链接指向正确的节点。先试着写在纸上,当你认为你做对了,试着写代码。
  • 是的,抱歉,我编辑了它。应该是 C 3, B 2, A 1。交换功能正常工作。我的问题是当我尝试使用 QSNode* tmp 对其进行排序时。我也将发布与交换的打印。
  • 我没有看到任何 typedef 声明。不应该是“struct DataNode *”而不是“DataNode *”吗?

标签: c pointers structure


【解决方案1】:

这是您的问题在 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

【讨论】:

    【解决方案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;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 2017-01-04
      • 2021-12-27
      相关资源
      最近更新 更多