【数据结构】CH2 线性表的链式存储结构

本文详细介绍了线性表的链式存储结构,包括链表的相关定义,单链表的插入、删除操作及应用,单链表和双链表的基本运算实现,以及循环链表的概念和应用。讨论了如何初始化、销毁线性表,判断线性表是否为空,获取线性表长度,以及如何插入、删除元素等操作。同时,提供了具体的链表应用举例,如单链表和双链表的建立、元素查找、排序等。
摘要由CSDN通过智能技术生成

目录

一、链表概述

1.相关定义

 二、单链表

1.插入和删除节点的操作

(1)插入结点

(2)删除结点

2.建立单链表

(1)头插法

 (2)尾插法

3.线性表基本运算在单链表中的实现

(1)初始化线性表InitList(&L)

(2)销毁线性表DestroyList(&L)

(3)判断线性表是否为空集ListEmpty(L)

(4)求线性表的长度ListLength(L)

(5)输出线性表DispList(L)

(6)求线性表中某个数据元素值GetElem(L,i,e)

(7)按元素值查找LocateElem(L,e)

(8)插入数据元素ListInsert(&L,i,e)

(9)删除数据元素LinkDelete(&L,i,e)

4.单链表应用举例

三、双链表

1.建立双链表

(1)头插法

(2)尾插法

2.线性表基本运算在双链表中的实现

(1)插入结点

(2)删除结点

3.双链表应用举例

四、循环链表


一、链表概述

1.相关定义

  • 链表:线性表的链式存储结构称为链表
  • 单链表:在每个结点中除包含有数据域以外只设置一个指针域,用于指向其后继结点,这样构成的链表称为线性单向链接表,简称为单链表。
  • 双链表:在每个节点中除包含有数值域以外设置两个指针域,分别用于指向其前驱结点和后继结点,这样构成的链表称为线性双向链表,简称为双链表。
  • 头指针:在线性表的链式存储中,通常每个链表带有一个头结点,并通过头结点的指针唯一标识该链表,称之为头指针。
  • 首指针:指向首结点或者开始结点的指针称为首指针。
  • 尾指针:指向尾结点的指针称为尾指针

 二、单链表

        在单链表中,假设每个结点的类型用LinkNode表示,它应包括存储元素的数据域,这里用data表示,其类型用通用类型标识符ElemType表示,还包括存储后继结点位置的指针域,这里用next表示。LinkNode类型的声明如下:

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

        为了简单,假设ElemType为int类型,使用以下自定义类型语句:

typedef int ElemType;

1.插入和删除节点的操作

(1)插入结点

s->next=p->next;
p->next=s;

(2)删除结点

p->next=p->next->next;

         一般情况下,在删除一个结点后还需要释放其存储空间,实现删除上述b结点并释放其存储空间的语句描述如下 :

q=p->next;    //q临时保存被删结点
p->next=q->next;    //从链表中删除结点q
free(q);    //释放结点q的空间

2.建立单链表

(1)头插法

void CreatList(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;
	}
}

 (2)尾插法

void CreatListR(LinkNode *&L,ElemType a[],int n)
{
	LinkNode *s,*r;
	L=(LinNode *)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
}

3.线性表基本运算在单链表中的实现

(1)初始化线性表InitList(&L)

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

(2)销毁线性表DestroyList(&L)

        该运算释放单链表L占用的内存空间,即逐一释放全部结点空间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值