c语言单向链表的一个小结

李财日记 2018-07-30 05:49:28
/*第一版
代码实现功能:
创建任意长度链表,然后再将链表打印出来。没有做输入参数检查*/
#include <stdio.h>
#include <stdlib.h>

/*********创建新的链表**************/
node_list creat_list(int len)
{
node_list head, p;

p = (struct my_node *)malloc(sizeof (node));
head = p;
if (p == NULL)
exit(0);

if (len ==0)
head = NULL;

int i = 1; //计数方便显示
while (len != 0) //循环创建链表
{
printf("请输入链表的第%d个节点的predata和nextdata!\n", i);
scanf("%d%d", &(p->predata), &(p->nextdata));

p = p->next; //循环出去要释放这片内存
p->next = (struct my_node *)malloc(sizeof (node));

len = len-1;
i++;
}
free(p); //释放多申请的那片内存
p = NULL; //设置链表尾部

return head;
}

/******显示函数********/
void printf_list(node_list struct_head)
{
int i = 1;
node_list my_struct_head = struct_head; //保持输入参数不变

if (my_struct_head == NULL)
{
printf("空链表\n");
return;
}

while (my_struct_head != NULL)
{
printf("链表第%d个节点 %d %d\n", i, my_struct_head->predata, my_struct_head->nextdata);

my_struct_head = my_struct_head->next;
i++;
}


return;
}

int main(void)
{
node_list input_listA, input_listB;
node_list output_listC;


unsigned lenA, lenB;
printf("请输入链表 A 的长度:");
scanf("%d", &lenA);
printf("\n");
input_listA = creat_list(lenA);



printf("请输入链表 B 的长度:");
scanf("%d", &lenB);
printf("\n");
input_listB = creat_list(lenB);


printf_list(input_listA);
printf("\n");
printf_list(input_listB);

return 0;
}

第一版出现的问题:链表只能存储一个节点
出现原因:未给 p->next 分配内存便让 p 指向它,导致给 p->next 分配完内存 p 的指向不会是 p->next
而是未知内存。我的编译器是将没有初始化的指针指向 NULL 的,使用只会有一个节点出现。
造成的后果:1、链表不能成功的创建。2、申请的内存不会有释放,会造成内存泄漏。3、如果编译器没有将为初始化
的指针指向 NULL ,那么将会导致指针指向未知内存,给系统带来一定的风险。
/*第二版:
因为问题代码都是链表创建函数的问题,故只对这部分代码做修改*/
node_list creat_list(int len)
{
node_list head, p;

p = (struct my_node *)malloc(sizeof (node));
head = p;
if (p == NULL)
exit(0);

if (len ==0)
head = NULL;

int i = 1; //计数方便显示
while (len != 0) //循环创建链表
{
printf("请输入链表的第%d个节点的predata和nextdata!\n", i);
scanf("%d%d", &(p->predata), &(p->nextdata));

//p = p->next; //循环出去要释放这片内存
p->next = (struct my_node *)malloc(sizeof (node));
p = p->next; //循环出去要释放这片内存 这里有改动

len = len-1;
i++;

}
free(p); //释放多申请的那片内存
p = NULL; //设置链表尾部

return head;
}

出现问题:链表创建后会始终有一片多分配出来的内存。
例如输入一个节点数据为 1 2 而输出为 1 2 和 0 0,创建多个链表时还会出现链表
重叠
出现原因:链表尾部设置有问题,p 已经指向 p->next 故p与上一个节点的next无关,
故链表尾部没有被设置,会出现以上情况是因为我的编译器会将没有初始化的指针指向
NULL ,并且将数据清零,就是说我并没有设置链表尾部,而是编译器碰巧给我设置了
链表尾部。
造成后果:1、链表不能成功按要求创建。2、编译器如果没有将为初始化指针指向 NULL
那么对未知内存操作会给系统带来风险。3、因为严格释放了内存,所以不会出现内存泄漏。
/*第三版:
因为问题代码都是链表创建函数的问题,故只对这部分代码做修改*/
node_list creat_list(int len)
{
node_list head, p, tmp;

p = (struct my_node *)malloc(sizeof (node));
head = p;
if (len ==0)
head = NULL;

int i = 1; //计数方便显示
while (len != 0) //循环创建链表
{
printf("请输入链表的第%d个节点的predata和nextdata!\n", i);
scanf("%d%d", &(p->predata), &(p->nextdata));

tmp = p; //相对第二版的改动
p->next = (struct my_node *)malloc(sizeof (node));
p = p->next;
len = len-1;
i++;
}
free(p); //释放多申请的那片内存
tmp->next = NULL; //设置链表尾部

return head;
}

成功创建一个len长度的链表,但代码太绕不便理解。还有一部分的内存管理问题,出现bug的机会会比较大




/* 第四版:基于Linux内核单向链表创建
*/
#include <stdio.h>
#include <stdlib.h>

typedef int datatype;

typedef struct node
{
datatype data;
struct node *next;
}listnode, *singly_list;


singly_list init_list(void) //初始化链表,拿到尾部节点
{
singly_list mylist = malloc(sizeof (listnode));
if (mylist != NULL)
{
mylist->next = NULL;
}
else
{
printf("分配内存失败!!!\n");
exit(1);
}

return mylist;
}

singly_list new_node(datatype data, singly_list next) //新的节点放在前面,完美,因为初始化的时候创建的是
{ //尾部节点,故链表的尾部不会出现问题。妙啊
singly_list new = malloc(sizeof (listnode));
if (new != NULL)
{
new->data = data;
new->next = next;
}
else
{
printf("分配内存失败!!!\n");
exit(1);
}

return new;
}


...全文
219 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-08-01
  • 打赏
  • 举报
回复
数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633
李财日记 2018-07-30
  • 打赏
  • 举报
回复
引用 1 楼 colinfang2006 的回复:
数据结构存下当前链表尾节点指针不就好了,实现简单代码也会简洁很多
node = malloc(...);
if (node != NULL)
{
node->data =data;
tail->next = node;
node->next = NULL;
tail = node;
}

你这样写很简洁而且满足了需求。谢谢指教
636f6c696e 2018-07-30
  • 打赏
  • 举报
回复
数据结构存下当前链表尾节点指针不就好了,实现简单代码也会简洁很多
node = malloc(...);
if (node != NULL)
{
node->data =data;
tail->next = node;
node->next = NULL;
tail = node;
}

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧