如何使用指针更改双链接列表中的2个节点? 13 C

时间:2017-04-12 08:27:18

标签: c pointers structure

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

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

预览列表输出&amp;&amp;调用sortFinale1函数:

enter image description here

输出与交换:

enter image description here

我的猜测是我错过了sortFinale1条件中的某些内容。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

(代表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;

}