链表是通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的。为了建立起数据元素之间的关系,对于每个数据元素除了存放数据元素自身的信息外,还必须有包含的指示该元素直接后继元素存储位置的信息,这两部分信息组成一个结点,即每个结点都有至少包括两个域,一个域存储数据元素信息,称为数据域,另一个域存储直接后继的地址,称为指针域。
开始程序之前,先简单了解一下单链表中的一些基本概念
头结点:在开始结点之前的结点(可有可无),其值域不包含任何信息,也可以包含链表长度等信息。 开始结点:第一个元素所在的结点。 头指针:永远指向链表中第一个结点的位置,如果链表有头结点,头指针指向头结点;否则,头指针指向开始结点,即第一个节点。 带有头节点单链表头指针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