链式存储结构-单链表11个基本操作的实现(C语言)

文章介绍了单链表的基本概念,包括数据域、指针域和结点,并对比了单链表与顺序存储结构的特性。接着详细阐述了单链表的初始化、判断是否为空、求表长、清空、销毁等操作的实现,并提供了插入和删除元素的函数。此外,还讨论了何时选择顺序存储或链式存储的情况。
摘要由CSDN通过智能技术生成

链式存储相关术语

数据域:存储数据元素信息的域。
指针域:存储直接后继位置的域。
结点:数据元素的存储映像,由数据域和指针域组成。
链表:n个结点链结成一个链表。即线性表的链式存储结构。
单链表:结点只有一个指针域的链表。

头指针:指向链表第一个结点的指针。
头结点:单链表第一个结点前附设的一个结点。

头结点是为了操作的统一与方便设立的,如在第一元素结点前插入结点与删除第一结点。

单链表结构与顺序存储结构的比较

注意:顺序表为随机存取结构,链表为顺序存取结构。

顺序存取结构:访问时只能通过头指针进入链表,并通过每个结点的指针域依次向后顺序扫描其余结点,所以寻找第一结点和最后一个结点所耗费时间不同。这种存取元素的方法称为顺序存取。

-顺序存储结构单链表
查找时间复杂度O(1)时间复杂度O(n)
插入和删除平均移动表长一半的元素,时间复杂度为O(n)找出位置的指针后,时间复杂度为O(1)
空间性能需预分配储存空间,易溢出不需分配储存空间,元素个数不受限制

• 若线性表需频繁查找,插入与删除操作少,宜用顺序存储结构
• 线性表元素个数变化大或不知道多大时,最好用单链表结构

基本操作实现

单链表的定义

#include<stdio.h>
#include<stdlib.h>

#define OK 1
#define ERROR 0

typedef int Status;

typedef int ElemType;

typedef struct Lnode {
	ElemType data;    
	struct Lnode *next;  
} Lnode;
typedef struct Lnode *LinkList;  

初始化链表

/* 初始化链表 */
Status InitList(LinkList *L) //二级指针
{
	*L = (LinkList)malloc(sizeof(Lnode));
	(*L)->next = NULL;
	return OK;
}

判断链表是否为空

/* 判断链表是否为空 */
Status ListEmpty(LinkList L)
{
	if (L->next) return 0;  //非空
	else return 1;
}

求表长

/* 求表长 */
Status ListLengh(LinkList L)
{
	LinkList p;
	p = L->next;
	int i = 0;
	while (p)
	{
		p = p->next;
		i++;
	}
	return i;
}

清空链表

/* 清空链表 */
Status ClearList(LinkList* L)
{
	LinkList p, q;
	p = (*L)->next;
	while (p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL;  //头结点指针域为空
	return OK;
}

销毁单链表

/* 销毁单链表 */
Status DestroyList(LinkList* L)
{
	LinkList p = *L;
	while (p)
	{
		*L = (*L)->next;
		free(p);
		p = *L;
	}
	return OK;
}

单链表的取值

/* 单链表的取值 */
Status GetElem(LinkList L, int i, ElemType *e)
{
	LinkList p = L->next; 
	int j = 1;
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i) return ERROR;
	*e = p->data;
	return OK;
}

查找

/* 按值查找 返回地址*/
LinkList LocateELem(LinkList L, ElemType e)
{
	LinkList p = L->next;
	while (p && p->data != e)
		p = p->next;
	if (p) return p;
	else
		return NULL;
}
/* 按值查找  返回位序*/
Status LocateELem_(LinkList L, ElemType e)
{
	LinkList p = L->next;
	int j = 1;
		while (p && p->data != e)
		{
			p = p->next;
			j++;
		}
		if (p) return j;
		else
			return 0;
}

插入 在L中第i个位置之前插入新的数据元素e

/* 插入 在L中第i个位置之前插入新的数据元素e*/
Status Listlnsert(LinkList*L, int i, ElemType e)
{
	int j = 0;
	LinkList p = *L;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1) return ERROR;
	LinkList pnew = (LinkList)malloc(sizeof(Lnode));
	pnew->data = e;
	pnew->next = p->next;
	p->next = pnew;
	return OK;
}

删除第i个元素

/* 删除第i个元素*/
Status ListDelete(LinkList* L, int i, ElemType* e)
{
	int j = 0;
	LinkList p = *L;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1 || !p->next) return ERROR;
	LinkList pfree = p->next;
	*e = pfree->data;
	p->next = pfree->next;
	free(pfree);
	return OK;
}

单链表的建立 头插法

/* 头插法 */
void CreateList(LinkList *L, int i)
{

	int j;
	for (j = 0; j < i; j++)
	{
		LinkList p = (LinkList)malloc(sizeof(Lnode));
		int data;
		scanf("%d", &data);
		p->data = data;
		p->next = (*L)->next;
		(*L)->next = p;
	}

}

单链表的建立 尾插法

/* 尾插法 */
void CreateList_(LinkList *L, int i)
{
	LinkList ptail = *L;
	int j;
	for (j = 0; j < i; j++)
	{
		LinkList pnew = (LinkList)malloc(sizeof(Lnode));
		int data;
		scanf("%d" ,&data);
		pnew->data = data;
		pnew->next = NULL;
		ptail->next = pnew;
		ptail = pnew;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mirror_zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值