我在C中的链接列表的插入方法遇到了一些问题。看起来我所做的每个插入只替换了前一个插入。所以最后列表总是只包含一个单元格。我认为问题始于“insertToEndList”函数。你有没有看到它失败的原因?
#include <stdio.h>
#include <stdlib.h>
typedef struct listNode{
int* dataPtr;
struct listNode* next;
}ListNode;
typedef struct list
{
ListNode* head;
ListNode* tail;
}List;
void deleteFromBeginnigOfList (List *list);
void deallocateListCell (ListNode *cell);
void freeList (List *list);
void printList (List *list);
void insertDataToBeginningList (List *list, int num);
void addToBeginningList (List *list, ListNode *cell);
List merge (List list1, List list2);
ListNode *createCell (int num);
void addToEmtyList(List *list, ListNode *cell);
void addToEndList(List *list, ListNode *cell);
void insertDataToEndList(List *list, int num);
void makeEmptyList(List *list);
List getList();
void main()
{
List lst1, lst2, mergedList;
lst1 = getList();
lst2 = getList();
mergedList = merge(lst1,lst2);
printf("Merged list:\n");
printList(&mergedList);
freeList(&lst1);
freeList(&lst2);
freeList(&mergedList);
}
List getList()
{
List res;
int size, num, i;
makeEmptyList(&res);
printf("Please enter the number of items to be entered:\n");
scanf("%d", &size);
printf("Please enter the numbers:\n");
for(i = 0; i < size; i++)
{
scanf("%d", &num);
insertDataToEndList(&res, num);
}
return res;
}
void makeEmptyList(List *list){
list->head=list->tail=NULL;
}
void insertDataToEndList(List *list, int num){
ListNode *cell_to_add= createCell (num);
if (list->head==NULL)
addToEmtyList(list, cell_to_add);
else
addToEndList(list, cell_to_add);
}
ListNode *createCell (int num){
ListNode *cell=(ListNode*)malloc(sizeof(ListNode));
if (!cell)
{
printf("memory allocation failed\n");
exit(1);
}
cell->dataPtr=#
cell->next=NULL;
return cell;
}
void addToEmtyList(List *list, ListNode *cell){
list->head=list->tail=cell;
}
void addToEndList(List *list, ListNode *cell){
list->tail->next=cell;
list->tail=cell;
}
List merge (List list1, List list2){
List merge_res;
ListNode *curr_cell1=list1.head, *curr_cell2=list2.head;
ListNode *cell_to_add;
makeEmptyList (&merge_res);
while (curr_cell1 && curr_cell2)
{
if (*(curr_cell1->dataPtr)>*(curr_cell2->dataPtr))
{
insertDataToEndList(&merge_res, *(curr_cell1->dataPtr));
curr_cell1=curr_cell1->next;
}
else
{
insertDataToEndList(&merge_res, *(curr_cell2->dataPtr));
curr_cell2=curr_cell1->next;
}
}
while (curr_cell1)
{
insertDataToEndList(&merge_res, *(curr_cell1->dataPtr));
curr_cell1=curr_cell1->next;
}
while (curr_cell2)
{
insertDataToEndList(&merge_res, *(curr_cell2->dataPtr));
curr_cell2=curr_cell2->next;
}
return merge_res;
}
void printList (List *list){
ListNode *curr_cell=list->head;
while (curr_cell)
{
printf("%d, ", *(curr_cell->dataPtr));
curr_cell=curr_cell->next;
}
}
void freeList (List *list){
while (list->head)
deleteFromBeginnigOfList(list);
}
void deleteFromBeginnigOfList (List *list){
ListNode *cell_to_delete=list->head;
list->head=list->head->next;
if (list->head==NULL)
list->tail=NULL;
deallocateListCell (cell_to_delete);
}
void deallocateListCell (ListNode *cell){
free(cell->dataPtr);
free (cell);
}
答案 0 :(得分:1)
在此功能中,您可以访问list-&gt; head-&gt; next,但在第一个 insertDataToEndList,list-&gt; head == NULL,因为你使用了makeEmptyList 结果将是一个分段错误。此外,你想检查是否 list是空的,所以请列出 - > head == NULL。
void insertDataToEndList(List *list, int num)
{
ListNode *cell_to_add= createCell (num);
if (list->head->next==NULL)
addToEmtyList(list, cell_to_add);
else
addToEndList(list, cell_to_add);
}
在此方法中,您必须设置列表的第一个和最后一个节点, 不是下一个所以替换为list-&gt; head和list-&gt; tail而不是lis-&gt; head-&gt; nest。 和list-&gt; tail-&gt; next。
void addToEmtyList(List *list, ListNode *cell)
{
list->head->next=list->tail->next=cell;
}
你可以这样做:
ListNode *createCell (int num)
{
ListNode *cell=(ListNode*)malloc(sizeof(ListNode));
if (!cell)
{
printf("memory allocation failed\n");
exit(1);
}
int *temp = (int*)malloc(sizeof(int));
*temp = num;
cell->dataPtr=temp;
cell->next=NULL;
return cell;
}
否则,我建议你按行进行一次分配,以便更加隐蔽。
答案 1 :(得分:1)
这里有一些错误。大多数都是相对简单的指针错误:
在一个地方你有
curr_cell2=curr_cell1->next;
应该在哪里
curr_cell2 = curr_cell2->next;
在addToEmtyList
中,您有
list->head->next=list->tail->next=cell
但如果列表为空,则head
和tail
都为空。类似地,insertDataToEndList
中的条件应该检查list->head
而不是list->head->next
。
更加严重的错误是您正在获取本地变量(num
)的地址并将其保存在每个单元格中。保存局部变量的地址是你几乎从不做的事情,因为一旦离开其范围(在这种情况下,当你离开createCell
时)指针将变为无效。
如果你真的想拥有一个指向数据的指针,你应该做的是为它分别分配内存。即:
ListNode *createCell (int num){
ListNode *cell=(ListNode*)malloc(sizeof(ListNode));
int *data = malloc(sizeof(*data));
if (!cell || !data)
{
printf("memory allocation failed\n");
exit(1);
}
*data = num;
cell->dataPtr=data;
cell->next=NULL;
return cell;
}
另一种选择是将listNode
更改为包含int
而不是int*
。那你就
typedef struct listNode{
int data;
struct listNode* next;
}ListNode;
并在createCell
中
cell->data = num;