链表是通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的。为了建立起数据元素之间的关系,对于每个数据元素除了存放数据元素自身的信息外,还必须有包含的指示该元素直接后继元素存储位置的信息,这两部分信息组成一个结点,即每个结点都有至少包括两个域,一个域存储数据元素信息,称为数据域,另一个域存储直接后继的地址,称为指针域。
	开始程序之前,先简单了解一下单链表中的一些基本概念

头结点:在开始结点之前的结点(可有可无),其值域不包含任何信息,也可以包含链表长度等信息。 开始结点:第一个元素所在的结点。 头指针:永远指向链表中第一个结点的位置,如果链表有头结点,头指针指向头结点;否则,头指针指向开始结点,即第一个节点。 带有头节点单链表头指针head指向头结点。头指针head始终不等于NULL,head->next等于NULL的时候链表为空。 不带头结点的单链表头指针head指向开始结点,当head等于NULL时链表为空。 头结点和头指针的区别:头指针是一个指针,头指针指向链表的第一个结点(如果链表有头结点,头指针指向头结点;否则,头指针指向开始结点);头结点是一个实际存在的点,它包含有数据域和指针域。头指针什么时候都应该存在,而头节点可有可无。

#include<stdio.h>
#include<stdlib.h>
typedef int elemtype;
typedef struct Node								//定义一个结构体
{
	elemtype data;
	struct Node *next;
}Node;
typedef struct Node *LinkList;

int InitList(LinkList *L)							//带有头节点的单链表的初始化
{
	(*L) = (LinkList)malloc(sizeof(Node));
	if (!L)
	{
		printf("分配内存失败!\n");
		exit(0);
	}
	(*L)->next = NULL;
	return 0;
}

void CreateListHead(LinkList *L)			//头插法创建一个单链表,n为要插入的元素个数
{
	int i, n;
	LinkList p;
	(*L) = (LinkList)malloc(sizeof(Node));
	(*L)->next = NULL;
	printf("请输入您要插入元素的个数:");
	scanf("%d", &n);
	printf("请输入你要插入的元素值(用空格隔开):");
	for (i = 0; i < n; i++)
	{
		p = (LinkList)malloc(sizeof(Node));
		scanf("%d", &p->data);
		p->next = (*L)->next;
		(*L)->next = p;
	}
}

void CreateListTail(LinkList *L)			//尾插法创建一个单链表,n为要插入的元素个数
{
	int i, n;
	LinkList p,r;
	(*L) = (LinkList)malloc(sizeof(Node));
	r = *L;
	printf("请输入您要插入元素的个数:");
	scanf("%d", &n);
	printf("请输入你要插入的元素值(用空格隔开):");
	for (i = 0; i < n; i++)
	{
		p = (LinkList)malloc(sizeof(Node));
		scanf("%d", &p->data);
		r->next = p;
		r = p;
	}
	r->next = NULL;
}

int LengthList(LinkList *L)					//计算链表长度
{
	int length = 0;
	LinkList p;
	p = (*L)->next;
	while (p)
	{
		length++;
		p = p->next;
	}
	return length;
}

int GetElem(LinkList L, int i, elemtype *e)			//用e返回L中第i个元素值
{
	int j = 1;
	LinkList p;
	p = L->next;
	while (p && j < i)
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
	{
		printf("查询不到该元素!\n");
		return 0;
	}
	*e = p->data;
	return 0;
}

int InsertList(LinkList *L, int i, elemtype e)			//在L中第i个位置插入元素e
{
	LinkList p, s;
	int j = 1;
	p = *L;
	while (p && j < i)
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
	{
		printf("插入元素失败!\n");
		return 0;
	}
	s = (LinkList)malloc(sizeof(Node));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 0;
}

int DeleteList(LinkList *L, int i, elemtype *e)				//删除L中第i个元素,并用e返回其值
{
	LinkList p, q;
	int j = 1;
	p = *L;
	while (p->next && j < i)
	{
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i)
	{
		printf("删除元素失败!\n");
		return 0;
	}
	q = p->next;
	p->next = q->next;
	*e = q->data;
	free(q);
	return 0;
}

int ClearList(LinkList *L)					//单链表的整表删除
{
	LinkList p, q;
	p = (*L)->next;
	while (p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL;
	return 0;
}

void ShowList(LinkList *L)					//打印整个链表
{
	LinkList p;
	p = (*L)->next;
	if (p == NULL)
	{
		printf("这是一个空链表!\n");
	}
	printf("单链表");
	while (p)
	{
		printf(" -> %d", p->data);
		p = p->next;
	}
	printf("\n");
}

int main()
{
	LinkList L;
	InitList(&L);
	int k,i;
	elemtype m ;
	CreateListHead(&L);
	ShowList(&L);
	printf("单链表的长度为%d\n", LengthList(&L));
	CreateListTail(&L);
	ShowList(&L);
	printf("单链表的长度为%d\n",LengthList(&L));
	GetElem(L, 5, &m);
	printf("得到的元素值为:%d\n", m);
	InsertList(&L, 4, 25);
	printf("插入元素后的");
	ShowList(&L);
	DeleteList(&L, 3, &m);
	printf("删除元素后的");
	ShowList(&L);
	printf("删除的元素值为:%d\n", m);
	ClearList(&L);
	system("pause");
	return 0;
}
————————————————
版权声明:本文为CSDN博主「找之余」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/z1410880957/article/details/90317597