如何在不复制数据的情况下使用指针? 我想写一个冒泡排序功能,但我遇到了困难,需要一些帮助,如何交换节点地址而不是值。 我有一个包含城市名称和温度的文件:
我需要按温度对其进行排序,然后将其写入另一个文件。
更新: 好的,现在我想我理解了理论部分:
// p is my node
// p-prev -> p -> p-next -> p-next-next
prev->next = p->next;
p->next = p->next->next;
prev->next->next = p;
这是我需要做的,交换节点,但从语法上来说,我无法使它工作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char name[128];
int id;
struct node *next;
}*head;
void readFile() {
char fnamer[128] = "";
printf("\nEnter the file name to read (delimiter: ,): \n");
scanf("%s",&fnamer);
FILE *inf = fopen(fnamer, "r");
char buffer[1024];
memset(buffer, 0, 1024);
while(fgets(buffer, 1024, inf)){
struct node *temp = malloc(sizeof(struct node));
temp->next = NULL;
if(sscanf(buffer, "%19[^,], %d", temp->name, &temp->id) != 2){
free(temp);
break;
}
if(!head){
head = temp;
} else{
temp->next = head;
head = temp;
}
}
fclose(inf);
}
int main(void) {
// Read a linked list from file
readFile();
//Bubble sort in linked list
struct node *loop1 = head;
while(loop1){
struct node *loop2 = loop1->next;
while(loop2){
if(loop1->id > loop2->id){
// Swap next pointers
// This is not working
struct node *temp = loop1->next;
loop1->next = loop2->next;
loop2->next = temp;
}
loop2 = loop2->next;
}
loop1 = loop1->next;
}
// Print the sorted linked list to file:
char foutname[100]="";
printf("\nPlease Enter the file name to write the result: \n");
scanf("%s",&foutname);
FILE *outf;
outf = fopen(foutname, "w+");
loop1 = head;
while(loop1){
printf("%s %d\n", loop1->name, loop1->id);
fprintf(outf, "%s %d\n", loop1->name, loop1->id);
loop1 = loop1->next;
}
fclose(outf);
return 0;
}
答案 0 :(得分:2)
要在单链表中交换两个节点,您可以使用以下功能
void swap(struct node **current)
{
struct node *tmp = (*current)->next->next;
(*current)->next->next = *current;
*current = (*current)->next;
(*current)->next->next = tmp;
}
例如,要交换头节点和下一个节点,您可以调用函数
swap( &head );
另请参阅此参考文献Bubble sort in c linked list的答案,其中显示了如何为单链表编写冒泡排序算法。
答案 1 :(得分:1)
我们需要交换next
链接,以便重新安排链接链。如果您交换node1
和node2
,则链接链应更改如下:
//change the link chain from
node0 -> node1 -> node2 -> node3
//to
node0 -> node2 -> node1 -> node3
我们把它放在while
循环中,当没有更多交换时循环中断。我们可以通过限制数字比较来改进这个功能。在每个循环之后,应该对最后一个元素进行排序。
要将它们放在一起,我们可以使用typedef
关键字,这样我们就不必在任何地方重复struct
。
typedef struct node_t
{
char name[20];
int id;
struct node_t *next;
} node;
void bubblesort(node **list)
{
if(!(*list)) return;
node *previous_node = NULL;
node *sort_up_to = NULL;
while(1)
{
previous_node = NULL;
node *ptr = *list;
node *last_change = NULL;
while(ptr->next)
{
//the rest of the list is sorted?
if(sort_up_to && ptr == sort_up_to) break;
node *next = ptr->next;
if(ptr->id > next->id)
{
if(previous_node == NULL)
*list = next;
else
previous_node->next = next;
ptr->next = next->next;
next->next = ptr;
last_change = next;
}
previous_node = ptr;
ptr = next;
}
//list is all sorted?
if(!last_change) break;
sort_up_to = last_change;
}
}
int main(void)
{
node* head = NULL;
FILE *fin = fopen("test.txt", "r");
if(!fin)
return 0;
node temp;
while(fscanf(fin, "%19[^,], %d\n", temp.name, &temp.id) == 2)
{
node *n = malloc(sizeof(node));
n->next = NULL;
strcpy(n->name, temp.name);
n->id = temp.id;
if(head)
n->next = head;
head = n;
}
fclose(fin);
bubblesort(&head);
for(node* n = head; n != NULL; n = n->next)
printf("%s %d\n", n->name, n->id);
return 0;
}