直接上代码吧

#include<stdio.h>
#include<malloc.h>
/*
单链表特点:
它是一种动态的储存结构,链表中每个节点占用的储存空间不是预先分配的,而是运行时系统根据需求生成的
*/
typedef struct lnode
{
int data;
struct lnode *next;
}lnode,*linklist;
//结点定义
/*
关于头指针的一点说明:
linklist L;
外面用头指针来标识一个单链表,如单链表L,单链表H等,是指链表的第一个节点的地址被记录在指针变量L,H中,头指针为NULL
时,表示一个空的单链表,需要进一步指出的是:上面定义的lnode是节点的类型,linklist是指向lnode节点的指针的类型,
为了增强程序的可读性,通常将标识一个链表的头指针说明为linklist类型的变量
*/
linklist creat_linklist_insert_head_nohead()
{
linklist l=NULL;//定义头指针变量l
lnode *s;//新建一个节点
int flag=-;//输入停止标志位
printf("输入整型数据,数据以空格隔开,输入数据为-1的时候表示输入截止\n");
while()
{
int x;
scanf("%d",&x);
if(x==flag)
break;
s=(lnode*)malloc(sizeof(lnode));//对s节点申请储存空间
s->data=x;//赋值
s->next=l;//s节点的next指向头指针
l=s;//头指针指向新建立的s节点,因为这是在单链表的头部插入数据
}
return l;
}//创建一个单链表,通过在头部插入数据,不含空的头节点
//-------------------------------------------------------------------------------------------------------------//
/*在单链表的表头插入,只要x!=flag,就是一直申请s结点,从而可以一直在表头插入,
其中l=s是最重要的,因为这是将s插入到l的表头,因为是在头部插入,所以只要一个头指针就可以,
若是在单链表的尾部插入,那么就需要尾部指针
关于此函数使用的一点说明:
我们输入数据 1 2 3 4 5的时候,输出的是 5 4 3 2 1,因为我们是在头部插入数据的
*/
//-------------------------------------------------------------------------------------------------------------//
linklist creat_linklist_insert_end_yeshead()
{
linklist l=NULL,r=NULL;//定义头指针变量和尾指针变量
lnode *s;//定义新建节点
int flag=-;//输入结束标志位
printf("输入整型数据,数据以空格隔开,输入数据为-1的时候表示输入截止\n");
while()
{
int x;
scanf("%d",&x);
if(x==flag)//输入数据等于输入结束标志位则跳出循环
break;
s=(lnode*)malloc(sizeof(lnode));//申请内存空间
s->data=x;//赋值
if(l==NULL)//单链表为空
l=s;//则将头指针指向新建节点
else
r->next=s;//不空的话则将尾指针的next指向s,因为如果不空的话,尾指针指向的肯定是一个数据节点,尾指针的next指向s是为了将两个数据节点连接起来
r=s;//尾指针移动到新插入的节点上
}
if(r!=NULL)//有数据
r->next=NULL;//尾指针的next指向空,说明尾指针后面没有数据了,目的的为了保证单链表尾指针逻辑的合理性
return l;
}//建立单链表且在链表尾部插入数据,含空的头节点
//-----------------------------------------------------------------------------------------------------------------------//
/*在单链表的尾部插入,只要没有输入结束的标志,就一直申请s结点,然后把x赋给s结点的data域,
l=s是为了第一个结点的结点的处理,因为在此之前l是一个空表,然后因为不断有新的结点生成,所以就是不断把新的s结点赋给r的next,
这样就不断有s结点加入到了单链表中间,然后最重要的是每次新的结点加入到单链表中后要把r尾指针向后面移动,就是文中的r=s;
关于此函数的一点说明:
输入数据 1 2 3 4 5,输出还是 1 2 3 4 5,而不是 5 4 3 2 1,因为我们插入数据是在链表尾部插入的
*/
//-----------------------------------------------------------------------------------------------------------------------//
int length_linklist_yeshead(linklist l)
{
linklist p=l;
int j=;
while(p->next)
{
j++;
p=p->next;
}
return j;
}//求单链表的表长,针对含有空的头节点的单链表
int length_linklist_nohead(linklist l)
{
lnode *p=l;
int j=;
while(p)
{
j++;
p=p->next;
}
return j;
}//求链表的表长,针对不含空的头节点的单链表
lnode *get_linklist(linklist l,int i)
{
lnode *p=l;
int j=;
while(p!=NULL&&j<i)
{
p=p->next;
j++;
}
if(j==i)
return p;
else
return NULL;
}//单链表的查找第i个元素结点,*p=l就是使p指针指向l链表;
lnode *locate_linklist(linklist l,int x)
{
lnode *p=l->next;//l为头节点
while(p!=NULL&&p->data!=x)
p=p->next;
return p;
}//单链表查找值为x的结点,找到后返回指向这个结点的指针;以后时刻要记得l为头指针,因为定义了头指针比没有定义头指针要方便许多;
int insert_linklist(linklist l,int i,int x)
{
lnode *p,*s;
p=get_linklist(l,i-);//找到第i-1个结点
if(p==NULL)
{printf("i错误");return ;}
else
s=(lnode*)malloc(sizeof(lnode));
s->data=x;
s->next=p->next;
p->next=s;
return ;
}//单链表的第i个结点后面的插入,重要的是申请,封装s结点,
int del_linklist(linklist l,int i)
{
i--;
linklist p,s;
p=get_linklist(l,i-);
if(p==NULL)
{
printf("该i-1节点不存在");
return -;
}
else if(p->next==NULL)
{
printf("第i个结点不存在");
return ;
}
else
{
s=p->next;
p->next=s->next;
free(s);
return ;
}
}//单链表中删除第i个结点,那么就先要找到i个结点的前驱,也就是第i-1个结点,同理单链表中的插入也要知道其前驱结点,所以单链表中的头节点的重要性就可想而知了
void printf_linklist(lnode *plisthead)
{
lnode *ptemp=plisthead;
while(ptemp)
{
printf("%d\t",ptemp->data);
ptemp=ptemp->next;
}
printf("\n");
}//链表打印函数
int main()
{
/*
linklist l=creat_linklist_insert_end_yeshead();
printf("%d\n",length_linklist_yeshead(l));
insert_linklist(l,2,100);//第二个结点的后面插入100
printf_linklist(l);
del_linklist(l,4);//删除第四个结点
printf_linklist(l);
*/
/*
linklist l=creat_linklist_insert_head_nohead();
printf("%d\n",length_linklist_nohead(l));
insert_linklist(l,2,100);
printf_linklist(l);
del_linklist(l,4);
printf_linklist(l);
*/
return ;
}

单链表(c语言实现)贼详细的更多相关文章

  1. 单链表 C语言 学习记录

    概念 链接方式存储 链接方式存储的线性表简称为链表(Linked List). 链表的具体存储表示为: 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的). 链表中 ...

  2. 带头结点的循环单链表----------C语言

    /***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...

  3. 带头节点的单链表-------C语言实现

    /***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...

  4. 不带头结点的单链表------C语言实现

    File name:no_head_link.c Author:SimonKly Version:0.1 Date: 2017.5.20 Description:不带头节点的单链表 Funcion L ...

  5. 单链表c语言实现的形式

    包括初始化,创建,查询,长度,删除,清空,销毁等操作 代码如下: #include<stdio.h> #include<stdlib.h> //定义单链表的数据类型 typed ...

  6. 数据结构-多级指针单链表(C语言)

    偶尔看到大一时候写了一个多级链表,听起来好有趣,稍微整理一下. 稍微注意一下两点: 1.指针是一个地址,他自己也是有一个地址.一级指针(带一个*号)表示一级地址,他自身地址为二级地址.二级指针(带两个 ...

  7. 一起talk C栗子吧(第十二回:C语言实例--单链表一)

    各位看官们,大家好.从今天開始,我们讲大型章回体科技小说 :C栗子.也就是C语言实例.闲话休提, 言归正转. 让我们一起talk C栗子吧! 看官们,上一回中咱们没有说详细的样例,并且是说了样例中的文 ...

  8. 单链表创建、删除、查找、插入之C语言实现

    本文将详细的介绍C语言单链表的创建.删除.查找.插入以及输出功能 一.创建 #include<stdio.h> #include<stdlib.h> typedef int E ...

  9. 数据结构—单链表(类C语言描写叙述)

    单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...

随机推荐

  1. 今年新鲜出炉的30个流行Android库,你一定需要

    作者|Michal Bialas 2017年快过去了,你年初的定的目标都快完成了吗?总结过去三个月内发布的 最新的30 个 Android 库和项目.你一定需要,建议收藏!让你事半功倍 1.Mater ...

  2. OpenStreetMap、googleMap等经纬度和行列号之间相互转化(python,JavaScript,php,Java,C#等)

    python: # OpenStreetMap经纬度转行列号 def deg2num(lat_deg, lon_deg, zoom): lat_rad = math.radians(lat_deg) ...

  3. Nginx 配置多站点vhost

    假设你想在Linux Nginx中用不同的域名访问不同的目录,这时就要配置多个vhost,具体配置如下,假设网站根目录设定在/var/www/ 1.在/var/www/下新建两个目录 /var/www ...

  4. java web项目中引入spring

    自己动手实践了一次,发生中间出了一下问题,现整理出来,供参考. Step1: 新建一个java web项目 Step2:下载spring的jar包http://repo.spring.io/libs- ...

  5. IIS 中托管基于TCP绑定的WCF服务

    IIS 中托管基于TCP绑定的WCF服务 一.创建一个基于TCP绑定的WCF服务 1.创建一个的简单的服务具体代码如下 服务契约定义 namespace SimpleService { // 注意: ...

  6. ASP.NET中母版页引用外部js或css文件无效,提示对象未定义解决方法

    最近做网站用了一个js+css实现的带有二级菜单的导航条,在母版页创建好后,子页面调用出现了许多奇怪的问题,多方查证后的最终解决方案和大家分享下.... 1.路径问题 如果是一个单独的aspx页面调用 ...

  7. Executors相关的类(线程池)

    一.概述 Java是天生就支持并发的语言,支持并发意味着多线程,线程的频繁创建在高并发及大数据量是非常消耗资源的,因为java提供了线程池.在jdk1.5以前的版本中,线程池的使用是及其简陋的,但是在 ...

  8. Eclipse 控制台视图和服务器视图中停止Web服务器的差别

    Eclipse 控制台视图和服务器视图中停止Web服务器的差别 (1)console视图里面, "红色方形图标" 是terminate, 也会关闭web服务器!!!!!!!!这个, ...

  9. windows多线程同步

    概述 任何单个应用程序都不能完全使该处理器达到满负荷.当一个线程遇到较长等待时间事件时,同步多线程还允许另一线程中的指令使用所有执行单元.例如,当一个线程发生高速缓存不命中,另一个线程可以继续执行.同 ...

  10. iOS7中UIView的animateKeyframesWithDuration方法讲解

    iOS7中UIView的animateKeyframesWithDuration方法讲解 在iOS7中,给UIView添加了一个方法用来直接使用关键帧动画而不用借助CoreAnimation来实现,那 ...