赞
踩
链表是一种常见的采用动态存储分配方式的数据结构。在链表中,有一个头指针变量,用这个指针保存一个地址,头指针指向一个变量,这个变量称为元素。链表中,每一个元素包括两部分:数据部分和指针部分。数据部分用来存放元素中包含的数据,指针部分用来指向下一个元素 。(最后一个元素指向NULL)
在链表中,第一个结点前虚假一个头结点,头指针指向头结点,头结点的指针域指向第一个实际有效结点,该节点可以称为首元结点。
确定一个链表需要一个参数:头指针,通过头指针可以推算出链表其他所有的参数
链表中,每个结点只有一个指针,所有指针都是单线联系,除了末尾结点指针为空外,每个结点的指针都指向下一个结点,一环扣一环。
单链表的特点:
1)有一个head指针变量,存放头结点地址,称为头指针。
2)头结点的指针域head->next,存放首元结点(第一个实际有效结点)的地址。
3)数据域存放用户需要的实际数据,指针域存放下一个结点的地址。
4)链表的使用,可以使程序的内存利用率和时间效率大大提高。
5)链表各结点间顺序由指针域next来确定
由于链表的每个结点都包含数据域和指针域,即每个结点都要包含不同的数据类型,所以结点的数据类型必须选用结构体类型。其中必须有一个成员的类型是指向本结构体的指针类型。
对于这种结构体类型,C语言允许递归递归定义。例如定义一个链表表示一个班级,其中每一个结点表示一位学生,他的结构体类型如下:
- typedef struct node{
- char name[20];//姓名
- int number;//学号
- struct node *next;//next的类型是指向本结构体数据类型的指针类型
- }Node,*LinkList;
Node是结构体类型,LinkList是结构体指针类型。LinkList head 相当于 Node *head,也相当于struct node *head。在 next 成员定义中,引用了本结构体类型,也就是说类型定义中采用了递归。
单链表的初始化就是创建一个头结点,若头结点的指针域为空,表示空单链表。单链表初始化代码如下:
- LinkList InitList()
- {
- LinkList head;//定义头指针变量
- head = (Node*)malloc(sizeof(Node));//头指针指向分配的头结点内存空间
- head->next=NULL;//头指针指针域为空
- return head;//返回头结点地址,即头指针
- }
单链表的建立就是在程序运行过程中,从无到有的建立一个链表,即一个一个分配结点的内存空间,然后输入结点中的数据,并建立结点间的相连关系。单链表的建立分为尾插法和头插法。
1)尾插法建立单链表
从第一个空表开始,重复读入数据,生成新结点,将读入的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表尾,直至读入结束标志为止。由于每次插入的新结点都插入到链表表尾,所以增加一个指针 r 来始终指向链表的最后一个结点,以便新结点的插入。尾插法创建单链表代码如下:
- void CreatByRear(LinkList head)
- {
- Node *r,*s;//s指向新创建的结点
- char name[20];
- int number;
- r = head;//r指向头结点 ,即当前单链表的尾结点
- printf ("请输入学生姓名和学号:\n");
- while(1)
- {
- scanf ("%s",name);
- scanf ("%d",&number);
- if (number==0)
- break;
- s = (Node*)malloc(sizeof(Node));//分配结点的内存空间 ,令s指向新分配的内存
- //分别赋值姓名和学号
- strcpy(s->name ,name);
- s->number = number;
- r->next = s;//原来的结点指向新结点
- r = s;//r指向新结点
- }
- r->next = NULL;//链表的尾结点指针为空
- }
在 while 循环中,用 s 指向新分配的内存,分别赋值姓名和学号,如果学号为 0 ,则结束输入,退出循环,最后将链表的最后一个结点的指针域赋值为NULL,表示链表创建结束。
2)头插法创建单链表
从第一个空表开始,重复读入数据,生成新结点,将读入的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止。尾插法创建单链表代码如下:
- void CreatByHead(LinkList head)
- {
- Node *s;
- char name[20];
- int number;
- printf ("请输入学生姓名和学号:\n");
- while(1)
- {
- scanf ("%s",name);
- scanf ("%d",&number);
- if (number==0)
- break;
- s = (Node*)malloc(sizeof(Node));
- strcpy(s->name ,name);
- s->number = number;
- s->next = head->next ;//新结点指向原来的首元结点
- head->next = s;//链表的头结点指向新结点
- }
-
- }
- void OutPut(LinkList head)
- {
- Node *p;//循环所用的临时指针
- p = head->next ;//p指向链表的首元结点
- while (p)
- {
- printf ("姓名:%s\n",p->name);//输出姓名
- printf ("学号:%d\n",p->number);//输出学号
- p = p->next; //移动临时指针到下一个结点
- }
- }
OutPut函数功能是将链表中的数据进行输出。函数参数中,head表示一个链表的头指针,函数中定义一个临时指针 p 用来进行循环操作,使其指向要输出链表的首元结点。
将链表的初始化,创建和遍历输出操作整合在一起,就编写了一个包含学生信息的链表结构。具体如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- typedef struct node{
- char name[20];//姓名
- int number;//学号
- struct node *next;//next的类型是指向本结构体数据类型的指针类型
- }Node,*LinkList;
-
- //单链表的初始化:就是创建一个头结点
- LinkList InitList()
- {
- LinkList head;//定义头指针变量
- head = (Node*)malloc(sizeof(Node));//头指针指向分配的头结点内存空间
- head->next=NULL;//头指针指针域为空
- return head;//返回头结点地址,即头指针
- }
-
- //尾插法创建单链表
- void CreatByRear(LinkList head)
- {
- Node *r,*s;//s指向新创建的结点
- char name[20];
- int number;
- r = head;//r指向头结点 ,即当前单链表的尾结点
- printf ("请输入学生姓名和学号:\n");
- while(1)
- {
- scanf ("%s",name);
- scanf ("%d",&number);
- if (number==0)
- break;
- s = (Node*)malloc(sizeof(Node));//分配结点的内存空间 ,令s指向新分配的内存
- //分别赋值姓名和学号
- strcpy(s->name ,name);
- s->number = number;
- r->next = s;//原来的结点指向新结点
- r = s;//r指向新结点
- }
- r->next = NULL;//链表的尾结点指针为空
- }
-
- //头插法创建单链表
- void CreatByHead(LinkList head)
- {
- Node *s;
- char name[20];
- int number;
- printf ("请输入学生姓名和学号:\n");
- while(1)
- {
- scanf ("%s",name);
- scanf ("%d",&number);
- if (number==0)
- break;
- s = (Node*)malloc(sizeof(Node));
- strcpy(s->name ,name);
- s->number = number;
- s->next = head->next ;//新结点指向原来的首元结点
- head->next = s;//链表的头结点指向新结点
- }
-
- }
- //单链表的遍历
- void OutPut(LinkList head)
- {
- Node *p;//循环所用的临时指针
- p = head->next ;//p指向链表的首元结点
- while (p)
- {
- printf ("姓名:%s\n",p->name);//输出姓名
- printf ("学号:%d\n",p->number);//输出学号
- p = p->next; //移动临时指针到下一个结点
- }
- }
- int main (void)
- {
- LinkList ha,hb;//定义单链表头指针
- ha = InitList();//初始化单链表
- CreatByRear(ha);//尾插法创建单链表
- OutPut(ha);//输出单链表
- hb = InitList();
- CreatByHead(hb);
- OutPut(hb);
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。