问题是这样的:我必须通过更改节点(不是其中的值)对双链表进行排序。 所以,让我说我有这个清单:
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函数:
输出与交换:
我的猜测是我错过了sortFinale1条件中的某些内容。
答案 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;
}