繁体   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