单链表在数据结构里十分常见,是一种常见的线性表,下面介绍其性质并用代码实现相关功能
单链表以链接方式存储数据
1、链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址。
2、链表的结点结构
┌──┬──┐
│data│next│
└──┴──┘
data域–存放结点值的数据域,一般为同一种类型
next域–存放结点的直接后继的地址(位置)的指针域(链域)
注意:
①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
②每个结点只有一个链域的链表称为单链表(Single Linked List)。
3、链表的描述方法
链表一般用一个头指针来表示,头指针指向下一个节点的地址,链表最后一个节点没有后继,因此其next指针为NULL;一般的头指针也是带有数据的。
下面利用C代码定义了链表结构及些运算操作函数:
#include <stdio.h>
#include <stdlib.h>
#define N 8
//结构定义
typedef struct node
{
int data; //链表数据
struct node *next;//链表指针
}LinkList;
//创建链表,以头指针表示
LinkList *CreatList(void) //返回的是链表的头指针
{
LinkList *head,*s;
int i = 0, a[N] = {1,5,6,7,4,3,9,0};
head = NULL; //链表为空
for(i = N-1; i >=0; i-- )
{
s = (LinkList *)malloc(sizeof(LinkList)); //分配内存空间
s->data = a[i];
s->next = head;
head = s; //头节点也是有存放值的
}
return head;
}
//读list值,把list中值按序输出,并获取个数
void ReadList(LinkList *head)
{
LinkList *p;
int len = 0;
p = head;
printf("\nThe value of the list is:\n");
while(head != NULL)
{
printf("\t%d",head->data); //输出值
head = head->next;
}
len = ListLength(p); //计算值个数
printf("\nThe length of the list is: %d\n", len);
}
//对链表L,在i处插入x
void *InsertList(LinkList *L,int x, int i)
{
int j = 1;
LinkList *p,*s;
p = L;
s = (LinkList *)malloc(sizeof(LinkList)); //分配新的空间
for(j = 1;j < i; j++) //找到插入位置,更改指针赋值
p = p->next;
s->data = x;
s->next = p->next;
p->next= s;
}
//删除链表i处的值
void *DeleteList(LinkList *L, int i)
{
int j;
LinkList *p,*s;
p = L;
for(j = 1; j<i-1; j++ ) //找到删除位置
p = p->next;
s = p->next;
p->next = (p->next)->next;
free(s); //释放删除的节点
}
//计算链表长度
int ListLength(LinkList *L)
{
LinkList *p;
int j = 1;
p = L;
while(p->next != NULL) //遍历求值
{
p = p->next;
j++;
}
return j;
}
//链接两个链表
LinkList *ListLink(LinkList *L1, LinkList *L2)
{
LinkList *p;
p = L2; //假设L2较短,便于减少计算量
while(p->next)
p = p->next;
p->next = L1; //L1即链表第一个地址
return L2;
}
int main()
{
LinkList *List, *List1, *LList;
List = CreatList(); //创建单链表List
List1 = CreatList(); //创建单链表List1
ReadList(List);
InsertList(List,14,6); //在List第六个位置插入14
ReadList(List);
DeleteList(List,2); //删除List第二个位置的值
ReadList(List);
LList = ListLink(List,List1); //List和List1连接为一个新的单链表
ReadList(LList);
return 0;
}
直接运行则可以看到实际结果