c - 将非重复条目从两个链表传递到第三个链表的问题
问题描述
我试图创建一个函数,它将两个链表的头作为输入,并创建第三个,它只包含两个列表中的条目,只出现在它们各自的列表中。问题是当我打印第三个列表时,我看到它包含两个列表中的每个条目。
示例列表 1:,1->13->32->4->5
列表 2:2->13->42->5
期望结果:list 3 1->32->4->2->2
,实际结果:1->13->32->4->5->2->13->42->5
每个列表的头部都被声明为一个全局变量。
typedef struct list_path *lp;
struct list_path
{
int row,column;
lp next;
};
lp head_list_1,head_list_2,head_list_3,temp_list,aux_path,temp_union,temp_insert_union,aux_union,aux_path_1,aux_path_2,head_list;
void path_union(lp head_list_1, lp head_list_2)
{
aux_path_1 = head_list_1;
aux_path_2 = head_list_2;
int exist;
while (aux_path_1 != NULL)
{
exist = 0;
while (aux_path_2 != NULL)
{
if (aux_path_1->row == aux_path_2->row && aux_path_1->column == aux_path_2->column)
{
exist=1;
}
aux_path_2 = aux_path_2->next;
}
if (exist == 0)
{
insert_union(head_list_3, aux_path_1->row, aux_path_1->column);
}
aux_path_1 = aux_path_1->next;
}
aux_path_1 = head_list_1;
aux_path_2 = head_list_2;
while (aux_path_2 != NULL)
{
exist = 0;
while (aux_path_1 != NULL)
{
if (aux_path_2->row == aux_path_1->row && aux_path_2->column == aux_path_1->column)
{
exist = 1;
}
aux_path_1 = aux_path_1->next;
}
if (exist == 0)
{
insert_union(head_list_3, aux_path_2->row, aux_path_2->column);
}
aux_path_2 = aux_path_2->next;
}
}
void insert_union(lp head_list_3, int key_a, int key_b)
{
lp union_temp;
lp list_aux = head_list_3;
while (list_aux->next != NULL)
{
list_aux = list_aux->next;
}
union_temp = (lp)malloc(sizeof(struct list_path));
union_temp->row = key_a;
union_temp->column = key_b;
list_aux->next = union_temp;
union_temp->next = NULL;
}
第一个函数使用 2 个嵌套的 while 来查找哪些条目只出现一次,第二个函数将这些键传递给第三个列表。
解决方案
您的代码中有多个问题:
实现是有缺陷的:您应该
aux_path_2 = head_list_2
在第一个循环aux_path_1 = head_list_1
的每次迭代开始时和第二个循环的每次迭代开始时进行初始化。一般的想法是不正确的:您只会插入仅在一个列表中的元素。两个列表共有的元素将在两个循环中被跳过,因此永远不会插入联合列表中。您应该克隆第一个列表并仅在第二个循环中使用测试。
该
insert_union
函数不能从空列表开始。您应该head_list_3
从此函数返回更新后的值并将其存储在调用者中。不需要为此任务使用全局变量:创建或更新的列表指针应该由两个函数返回。
将指针隐藏在 typedef 后面会令人困惑且容易出错。而不是定义
lp
,定义list_path
为 typedefstruct list_path
并用于list_path *
保持指针可见。
这是一个使用辅助函数来检查节点是否已给定坐标的修改版本。使用小的泛型函数和变量名有助于提高代码的可读性:
#include <stdlib.h>
typedef struct list_path list_path;
struct list_path {
int row, column;
list_path *next;
};
int path_find(list_path *head, int row, int column) {
for (list_path *aux = head; aux != NULL; aux = aux->next) {
if (aux->row == row && aux->column == column)
return 1;
}
return 0;
}
list_path *path_insert(list_path *head, int row, int column) {
list_path *temp;
list_path *aux;
temp = malloc(sizeof(*temp));
if (temp == NULL) {
perror("cannot allocate list_path structure");
abort();
}
temp->row = row;
temp->column = column;
temp->next = NULL;
if (head == NULL) {
// empty list: allocated node is the new head
head = temp;
} else {
// otherwise find the last node of the list
for (aux = head; aux->next != NULL; aux = aux->next) {
continue;
}
// and append the newly allocated node
aux->next = temp;
}
return head;
}
list_path *path_union(list_path *list1, list_path *list2) {
list_path *list3 = NULL;
// clone the first list into list3
for (list_path *aux1 = list1; aux1 != NULL; aux1 = aux1->next) {
list3 = path_insert(list3, aux1->row, aux1->column);
}
// append elements only present in list2
for (list_path *aux2 = list2; aux2 != NULL; aux2 = aux2->next) {
if (!path_find(list1, aux2->row, aux2->column)) {
list3 = path_insert(list3, aux2->row, aux2->column);
}
}
// return a pointer to the union list.
return list3;
}
推荐阅读
- android - Tablelayout中的多行文本视图移动文本视图
- xml - 在 XSLT 中插入与子级相同的字段
- r - 如何替换 df 中不满足条件的值
- java - 代码崩溃了,它意味着采用全名,例如 John Cena 并将其输出为 JCena)
- java - 将 windows-1252 输入文件转换为 utf-8 输出文件的字符编码
- asp.net-core - 在控制器中的 db.SaveChangesAsync 之后调用 SignalR SendAsync
- ansible - 有没有办法将 vmware guest.hostName 作为 ansible_host 而不是 IP 地址返回
- java - 如何在java上对某些文本进行编号?
- python - Socket 服务器只接受来自最后连接的客户端的 MSG
- vue.js - Cannot read property 'dispatch' of undefined VueJS