C语言基础之链表

                                              链表

链表(Linked list)是一种常见的基础数据结构,它不像数组必须顺序存储,链表中的元素在内存中可以连续也可以不连续。因此,为了表明元素之间的次序关系,除了存储元素本身之外,还要存储元素之间的关系。
链表由节点连接而成,节点的结构又分为两部分。
(1)数据域:用来存储数据本身
(2)指针域:用来存储下一个节点的指针

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构乐意充分利用计算机内存空间,实现灵活的内存动态管理。但由于访问结点必须从前一结点中读取它的位置,因此访问任意结点时必须从表首开始,依次向后逐个结点访问。因此链表只能顺序存取。

1.链表类型定义
typedef struct node          //定义链表结点类型和头指针类型
{
int num;
char name[20];
struct node*next;         //结点的指针域
}Lnode,*Linklist;                 //Lnode为结点类型名, Linklist为头指针类型名

2.链表结点的插入
链表有不带头结点和带头结点两种,以下操作都是带头结点的链表。头结点是在第一个结点之前附加的一个结点,它的数据域内什么都不存,其指针域指向首元结点(第一个数据元素的结点),头结点的地址即为整个链表的起始位置,将其赋给一个指针变量,称为头指针。
假设已存在一个头指针为L的链表,要在其中插入一个学生数据:学号为num,姓名为name,步骤如下。
(1)查找插入位置,使指针变量指向其前一结点
(2)生成新结点,初始化数据域
(3)插入新结点 

插入操作的函数实现
Linklist insert(Linklist L,int num, char name[])
{
Linklist p,s;
p=L;
while(p!=NULL&&num<p->num)                     //NULL宏定义为0
p=p->next;
//当要插入的学号小于当前及诶单心血号时,p指针后移;
s=(Linklist)malloc(sizeof(Lnode));         //生成新结点并初始化
s->num=num;
strcpy(s->name,name);
s->next=p->next;                    //插入到p所指结点之后
p->next=p;
return L;
}

删除操作的函数实现
Linklist delete(Linklist L,int num)
{
Linklist p,q;
p=L;
q=p->next;
while(q!=NULL&&q->num!=num)          //查找学号为num的学生结点
{
p=q;
q=q->next;
}
if(q==NULL)                            //不存在该学生
printf("%d not been found!\n",num);
else
{
p->next=q->next;
free(q);
printf("%d had beendeleted\n",num);
}
return L;
}

建立链表
(1)头插法
Linklist creat_h(Linklist L)
{
int num;
char name[20];
Linklist s;
L=(Linklist)malloc(sizeof(Lnode));             //生成头结点,其指针域为NULL,表示空链表
L->next=NULL;
  scanf("%d%s",&num,name);
while(num>0)
{
s=(Linklist)malloc(sizeof(Lnode));
s->num=num;
strcpy(s->name,name);
s->next=L->next;                             // 将新结点插入在头结点之后
L-nest=s;
scanf("%d%s",&num,name);
}
return L;
}

(2)尾插法
Linklist creat_r(Linklist L)
{
int num;
char name[20];
Linklist s,p;
L=(Linklist)malloc(sizeof(Lnode));             //生成头结点,其指针域为NULL,表示空链表
L->next=NULL;
p=L;
  scanf("%d%s",&num,name);
while(num>0)
{
s=(Linklist)malloc(sizeof(Lnode));
s->num=num;
strcpy(s->name,name);
s->next=p->next;                    //将新结点插入在尾结点p之后
p=s;                                             //s称为新的尾结点,p后移
L-nest=s;
scanf("%d%s",&num,name);
}
return L;
}

链表的输出
void print(Linklist L)
{
Linklist p;
p=L->next;                       //p指向首元结点
while(p!=NULL)
{
printf("%d,%s\n",p->num,p->name);
p=p->next;
}
}



主程序:
void main()
{
  Linklist L;
int num;
char name[20];
L=creat_r(L);
printf("please input a num and a naem to insert:\n");
scanf("%d%s",&num,name);
L=insert(L,num,name);
prinft("please input a num delete:\n");
scanf("%d",&num);
L=delete(L,num);
prinft("all the student are:\n");
print(L);
}


指针的数据类型
定义                                     含义
int *p;                                 p为指向整型数据的指针变量
int *p[n];                            定义指针数组p,它有n个指向整型的指针元素
int (*p)[n];                         p为指向含有n个元素的一维数组的指针变量
int f();                               f为返回整型值的函数
int *p();                            p为返回值为指针的函数,该指针指向整型数据
int (*p)();                          p为指向函数的指针,该函数返回一个整型值


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值