C语言创建一个单链表实现键盘输入数据以及增删查

C语言创建一个单链表实现键盘输入数据以及增删查

作为一个编程小白,在这里发表自己的第一篇博客,心里还是有点紧张。

写博客的目的主要还是在于让自己对所学的知识进行充分的掌握,企图在写分析的过程当中可以达到“柳暗花明又一村”的境界,当然如果可以帮助到别人的话自己心里也肯定有辣么一点点成就感。

因为刚接触到链表,所以今天就想和大家一起探讨一下链表。想弄清楚链表,对指针的概念一定要很清楚。我们都知道,链表是由一个又一个节点构成,每个节点又分为数据域和指针域(eg:p->data/p->next)。

举一个简单的例子来描述节点:

这是一个简单的线性表的节点(无序的),当我们把它整理成一个又一个的节点是它是这样的:

画的不是很好看,但应该很好理解吧。图一中数据域就相当于p->data,指针域相当于p->next。

假设p是指向线性表中的第i个数据元素(a(i))的指针,那么p->next就是指向第i+1个数据元素,即a(i+1)。也就是说,p->data=a(i),p->next->data=a(i+1)

简单搞清楚指针的用法后我们来完成一个动态单链表的创建(键盘输入)。如果还是没有搞懂的同学一定要多画几次图来理解,因为博主也是一个小白,可能讲的不是很清楚。

我们先来分析一下,第一步,我们先写头文件,然后定义结构体变量

#include

#include

typedef struct node{

int data;

node *next;

}node;

接下来就可以写创建单链表的函数了,我用的是尾插法

node *create(){//尾插法创建链表

node *p,*q,*head;//定义三个指针,其中p类似一个辅助指针吧,用来存放所输入的链表数据

int n;//表示想要输入的链表数据个数

int i = 0;//表示已经输入的链表数据个数

head = (node*)malloc(sizeof(node));//创建头节点

head->next = NULL;//可以理解为初始化链表,让它为空表

q = head;//q始终指向尾节点,开始时头节点和尾节点时同一个

printf("你想要输入多少个数据:");

scanf("%d",&n);

printf("请输入数字:");

for(i = 0;i < n;i++){

p = (node*)malloc(sizeof(node));//创建数据节点,让输入的数据先存放在p里面

scanf("%d",&p->data);// 输入链表数据

p->next = q->next;

q->next = p;

q = p;

}

return head;

}

创建了单链表,当然得让它输出了,接下来写一个输出函数

void print(node *head){//输出链表

node *p;

p = (node*)malloc(sizeof(node));//给p分配内存空间,使它可以存放数据

p = head->next;//让p指向开始节点

printf("输出单链表里的所有元素:");

while(p != NULL){//当p不是空表时执行下面语句

printf("%d ",p->data);

p = p->next;

}

}

计算单链表的长度

int ListLength(node *head){//计算单链表的长度

printf("\n");

node *p = head;//让p指向头节点

int i = 0;

while(p->next != NULL){//当p的后继节点不为空时执行下面语句

p = p->next;

i++;//执行一次循环加1,直到p的后继节点为空时跳出循环

}

printf("单链表的长度:%d",i);

return 0;

}

按照数据值查找(数据n所在的位置是第几个)

int LoacteElem(node *head){//按元素值查找

printf("\n");

node *p = head;//让p指向头节点

int j = 0,e;

printf("输入要查找的数据值:");

scanf("%d",&e);

while(p->next != NULL && p->data != e){

p = p->next;

j++;

}

printf("查找的数据的位置:%d",j);

return 0;

}

按照数据的位置查找(第n个位置的数据为)

int GetElem(node *head){//查找元素

printf("\n");

int i,e,m;//i的作用相当于指针遍历到第几个节点、e表示想要查找第几个位置的元素、m表示找到想要查找的数据的值)

node *p = head;//同样的套路

printf("请输入要查找数据的位置:");

scanf("%d",&e);

for(i=0;i

p = p->next;

}

m = p->data;

printf("位置为%d的数据是%d",e,m);

return 0;

}

接下来是插入函数

node *Insert(node *head){//插入元素

printf("\n");

node *p = head;

node *q;

int j = 0,i,e;//同样,j表示指针p遍历到链表数据的位置,i、e表示要在第i个位置插入数据e)

printf("输入要插入的元素的位置:");

scanf("%d",&i);

printf("输入要插入的元素的值:");

scanf("%d",&e);

for(j = 0;j < i-1;j++){

p = p->next;

}

q = (node*)malloc(sizeof(node));

q->data = e;//最后几步大家如果理解不了可以试着画图,多画几次,搞清楚数据域和指针域到底指的是什么就变得很简单了

q->next = p->next;

p->next = q;

return head;

}

然后是删除函数

node *Delete(node *head){//删除元素

printf("\n");

node *p = head;//老套路

node *q,*r;

int j = 0,i;//j表示指针p遍历到链表的第几个数据,i表示删除第i个位置的数据

printf("请输入删除数据的位置:");

scanf("%d",&i);

for(j = 0;j < i-1;j++){

p = p->next;

}

q = (node *)malloc(sizeof(node));

q = p;

r=q->next;

p->next=r->next;

return head;

}

然后是主函数

int main(){

node *head;

head = create();//调用创建链表函数(尾插法)

print(head);//调用输出函数,输出链表的所有数据

ListLength(head);//求链表的长度

LoacteElem(head);//按数据值查找(第n个数据的位置是第m个)

GetElem(head);//查找数据(第n个位置的数据是第m个)

Insert(head);//调用插入函数

print(head);//输出插入后的链表

Delete(head);//调用删除函数

print(head);//输出删除后的链表

printf("\n");

return 0;

}

最后,总结部分:以上函数按顺序添加至编译器(Dev-C++和vs2019)中可以正常运行,但是根据vs2019编译器的规则需将(”scanf“改为”scanf_s“),而且会出现警告(不是错误是警告)(eg:取消NULL指针对p的应用),该解决方法是在出现问题的函数中添加

if(p == NULL){

return 0;

}

该警告的出现是基于vs编译器的严谨,如果不添加该代码块那么万一p为空表的话运行将会出现问题(vs知道p是空表,它不知道应该运行出什么样的结果)但是我们知道我们运行的时候一定会输入数据,所以它不会为空。(ps:vs好严谨)

不足之处:不能实现删除重复项以及排序问题

自我评价:个人感觉代码没有讲的很清楚,因为插入和删除应该再仔细讲讲,但是由于自身也是一个小白,很多东西可以用嘴说出来,写却不知道怎么写,如果大家把开头的两幅图搞明白的话,写这些函数的时候多画图理解,根据自己的想法写代码,不要按照书上或者网上的代码按部就班,多练习几次就会很熟悉了。

个人心得:这次写博客让我自己对指针的理解确实是提升了一个档次(不是瞎说),写之前脑海里有画图的概念,却不知道怎么画。在写的过程中因为要将这些东西清楚的说明出来,那么自己一定要很熟悉。于是就多看书,查资料,在上传每一段代码前自己又在本子上过了一遍,确认无误后才复制上去。所以还是建议大家对于自己不会的东西一定要持之以恒,花时间搞清楚它,当自己真的从朦胧到熟悉,那种感觉真的很舒服。

最后,就希望路过的大佬可以提一点建议,也希望许多和我一样的小萌新可以共同努力,一起在编程这条路”走到黑“

相关推荐

为什么有的猎头和HR很喜欢加求职者的微信?原因可能有三方面
java gc横向测评,如何选择合适的GC策略?
365跑腿客服电话号码

java gc横向测评,如何选择合适的GC策略?

📅 08-06 👁️ 7646
解决QQ安装失败的技巧(终结QQ安装问题,快速解决的方法)
365跑腿客服电话号码

解决QQ安装失败的技巧(终结QQ安装问题,快速解决的方法)

📅 09-11 👁️ 6674