4、线性表的链式存储结构(单链表)

线性表的链式存储结构称为链表。线性表采用链式存储时,最简单,最常用的方法是在每个结点中设置一个指针域用于指向其后继结点,这样构成的链表称为单链表;另一种采用的方法是在每个结点中设置两个指针域,分别用于指向其前驱结点和后继结点,这样构成的链表称为双链表。
 在链表中通常每个链表都带有一个头结点,并通过头结点的指针唯一表识该链表,称为头指针,指向尾结点的指针称为尾指针。
 在单链表中,由于每个结点只包含一个指向后继结点的指针,所有当访问一个结点后只能访问它的后继结点,而无法访问他的前驱结点。
在这里插入图片描述
单链表的实现:
1.声明单链表类型

typedef int ElemType;		//元素类型
typedef struct LNode
{
	ElemType data;			//存放元素值
	struct LNode * next;	//指向后继结点
} LinkNode;					//单链表结点类型

2.初始化链表

void InitList(LinkNode * &L)
{
	L = (LinkNode*)malloc(sizeof(LinkNode));
	L->next = NULL;			//创建头节点,其next域置为NULL
}

3.销毁链表

void DestoryList(LinkNode * &L)
{
	LinkNode *pre = L, *p = L->next;//pre指向结点p的前驱结点
	while (p != NULL)				//扫描单链表L
	{
		free(pre);					//释放pre结点
		pre = p;
		p = p->next;				//pre, p同步后移一个结点
	}
	free(pre);						//循环结束时p为NULL,pre指向尾结点,释放它
}

4.头插法建立单链表
在这里插入图片描述

void CreateListF(LinkNode * &L, ElemType a[], int n)
{
	LinkNode * s;
	L = (LinkNode*)malloc(sizeof(LinkNode));
	L->next = NULL;							//创建头节点,其next域置为NULL
	for (int i = 0; i < n; i++)				//循环建立数据结点s
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));
		s->data = a[i];						//创建数据结点s
		s->next = L->next;					//将结点s插入到首结点之间,头节点之后
		L->next = s;
	}
}

5.尾插法创建单链表
在这里插入图片描述

void CreateListR(LinkNode * &L, ElemType a[], int n)
{
	LinkNode * s,*r;
	L = (LinkNode*)malloc(sizeof(LinkNode));//创建头节点
	r = L;									//r始终指向尾结点,初始化时指向头节点
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));
		s->data = a[i];						//创建数据结点s
		r->next = s;						//将结点s插入结点r之后
		r= s;
	}
	r->next = NULL;							//尾结点的next域置为NULL
}

6.打印单链表

void DispList(LinkNode *L)
{
	LinkNode *p = L->next;					//指向首结点
	while (p != NULL);						//p不为NULL时,输出p的结点的data域
	{
		printf("%d ", p->data);
		p = p->next;						//p指向下一个结点
	}
	printf("\n");
}

7.判断单链表是否为空表

bool ListEmpty(LinkNode * L)
{
	return (L -> next == NULL);
}

8.求单链表的长度

int ListLength(LinkNode * L)
{
	int n = 0;
	LinkNode * p = L;
	while (p->next != NULL)
	{
		n++;
		p = p->next;
	}
	return n;
}

9.求单链表中某元素值

bool GetElem(LinkNode *L, int i, ElemType &e)
{
	int j = 0;
	LinkNode *p = L;				//p指向头节点,j置为0(头节点序号为0)
	if (i <= 0)return false;		//i错误返回false
	while (j < i&&p != NULL)		//找到第i个结点p
	{
		j++;
		p = p->next;
	}
	if (p == NULL) return false;	//不存在第i个数据节点,返回false
	else							//存在第i个数据节点,返回true
	{
		e = p->data;
		return true;
	}
}

10.按元素查找

int LocateElem(LinkNode *L, ElemType e) {
	int i = 1;
	LinkNode *p = L->next;				//p指向头节点,i置为1(首节点序号为1)
	while (p != NULL && p->data != e)	//查找data值为e的结点,其序号为i
	{
		p = p->next;
		i++;
	}
	if (p == NULL) 
		return 0;						//不存在值为e的结点,返回0
	else 
		return i;						//存在值为e的结点,返回i
}

11.插入数据元素

bool ListInsert(LinkNode * &L, int i, ElemType e)
{
	int j = 0;
	LinkNode *p = L, *s;				//p指向头节点,j置为0(头节点序号为0)
	if (i <= 0) return false;			//i错误返回false
	while (j < i - 1 && p != NULL)		//查找第i-1个结点p
	{
		j++;
		p = p->next;
	}
	if (p == NULL) return false;		//未找到第i-1个结点,返回false
	else								//找到第i-1个结点,插入新结点并返回false
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));
		s->data = e;					//创建新结点s,其data域置为e
		s->next = p->next;				//将结点s插入到结点p之后
		p->next = s;
		return true;
	}
}

12.删除数据元素

bool ListDelete(LinkNode * &L, int i, ElemType &e)
{
	int j = 0;
	LinkNode *p = L, *q;				//p指向头节点,j置为0(头节点序号为0)
	if (i <= 0) return false;			//i错误返回false
	while (j < i - 1 && p != NULL)		//查找第i-1个结点p
	{
		j++;
		p = p->next;
	}
	if (p == NULL) return false;		//未找到第i-1个结点,返回false
	else								//找到第i-1个结点
	{
		q = p->next;					//q指向第i个结点
		if (q == NULL)return false;		//若不存在第i个结点,返回false
		e = q->data;
		p->next = q->next;				//从单链表中删除q结点
		free(q);						//释放q结点
		return true;					//返回true表示成功删除第i个结点
	}
}

13.主函数

int main()
{
	LinkNode *LN;
	ElemType data[] = { 1,23,4,5,6,5,7657 },a;
	InitList(LN);
	CreateListF(LN, data,7);
	printf("按头插法插入链表为:");
	DispList(LN);
	CreateListR(LN, data, 7);
	printf("按尾插法插入链表为:");
	DispList(LN);
	printf("链表是否为空:%s\n",ListEmpty(LN) ? "true" : "false");
	printf("链表长度为:%d\n",ListLength(LN));
	GetElem(LN, 2, a);
	printf("第 2 个元素为:%d\n", a);
	printf("元素值为 23 的元素在第 %d 个\n", LocateElem(LN, 23));
	ListInsert(LN,3,88);
	printf("在第 3 个插入元素 88 后链表为:");
	DispList(LN);
	ListDelete(LN,4,a);
	printf("删除第 4 个元素后链表为:");
	DispList(LN);
	DestoryList(LN);
	getchar();
	return 0;
}

运行结果为:

按头插法插入链表为:7657 5 6 5 4 23 1
按尾插法插入链表为:1 23 4 5 6 5 7657
链表是否为空:false
链表长度为:7
第 2 个元素为:23
元素值为 23 的元素在第 2 个
在第 3 个插入元素 88 后链表为:1 23 88 4 5 6 5 7657
删除第 4 个元素后链表为:1 23 88 5 6 5 7657

下一篇:5、线性表的链式存储结构(双链表)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值