【数据结构】顺序表和链表

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。

【数据结构】顺序表和链表_第1张图片

【数据结构】顺序表和链表_第2张图片

2.顺序表

2.1概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存 储。在数组上完成数据的增删查改。

顺序表一般可以分为:

1. 静态顺序表:使用定长数组存储元素。

就是给定长度的数组和有效数据个数。

2. 动态顺序表:使用动态开辟的数组存储。

指的是在堆区开辟出来的动态数组,给定数据个数和容量空间大小。

2.2接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空 间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间 大小,所以下面我们实现动态顺序表。

//顺序表的动态储存
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;	//指向动态开辟的数组
	int size;		//有效数据个数
	int capacity;	//容量空间的大小
}SL;

//基本增删查改接口
void SLInit(SL* ps);	//顺序表初始化

void SLPushBack(SL* ps,SLDataType x);	//顺序表尾插
void SLPushFront(SL* ps,SLDataType x);	//顺序表头插
void SLPopBack(SL* ps);		//顺序表尾删
void SLPopFront(SL* ps);	//顺序表头删

void SLInsert(SL* ps, int pos, SLDataType x);	//顺序表在pos位插入x
void SLErase(SL* ps, int pos);					//顺序表删除pos位的值
int SLFind(SL* psl, SLDataType x);				//顺序表查找
void SLPrint(SL* ps);		//顺序表的打印
void SLDestroy(SL* ps);		//顺序表的销毁

顺序表难度较低,接下来我们主要对链表进行刨析,理解了链表,顺序表就手到擒来了。

3.链表

3.1链表的结构及概念

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。

其实链表就好比作一辆火车,由一条牵引链链接每一节车厢。

现实数据结构如下;

【数据结构】顺序表和链表_第3张图片

注意:

  1. 从上图可知,链式结构逻辑上是连续的,但是在物理上不一定是连续的。
  2. 现实中的节点是从堆区上申请出来的。
  3. 从堆区上申请出来的空间,是按照一定的策略分配的,可能连续,也可能不连续。

3.2链表的分类

链表可以分为8种链表结构:

1.单向或者双向

【数据结构】顺序表和链表_第4张图片

2.带头或者不带头

【数据结构】顺序表和链表_第5张图片

3.循环或不循环

【数据结构】顺序表和链表_第6张图片

还有俩种分别是:无头单向非循环链表、带头双向循环链表

【数据结构】顺序表和链表_第7张图片

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结 构的子结构,如哈希桶、图的邻接表等等。

2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带 来很多优势,实现反而简单了。

 3.3链表的实现

typedef int SLTDataType;
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

SLTNode* BuySLTNode(SLTDataType x);		//动态申请节点
void SListPrint(SLTNode* plist);		//打印单链表

void SListPushBack(SLTNode** pphead, SLTDataType x);	//单链表尾插
void SListPushFront(SLTNode** pphead, SLTDataType x);	//单链表头插
void SListPopBack(SLTNode** pphead);	//单链表尾删
void SListPopFront(SLTNode** pphead);	//单链表头删

SLTNode* SLFind(SLTNode* phead, SLTDataType x);			//单链表查找

3.4双向链表的实现

typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

ListNode* ListCreate();		// 创建返回链表的头结点.
void ListDestroy(ListNode* pHead);		// 双向链表销毁
void ListPrint(ListNode* pHead);		// 双向链表打印
void ListPushBack(ListNode* pHead, LTDataType x);	// 双向链表尾插
void ListPushFront(ListNode* pHead,LTDataType x);	// 双向链表头插
void ListPopBack(ListNode* pHead);		// 双向链表尾删
void ListPopFront(ListNode* pHead);		// 双向链表头删

bool LTEmpty(ListNode* pHead);

ListNode* ListFind(ListNode* pHead, LTDataType x);	// 双向链表查找
void ListErase(ListNode* pos);		// 双向链表删除pos位置的结点
void LTInsert(ListNode* pos, LTDataType x);		// 双向链表在pos的前面进行插入

4.顺序表和链表的区别

【数据结构】顺序表和链表_第8张图片

好啦,本节知识就到这啦,关注博主,让我们一起开码!! 

你可能感兴趣的:(C数据结构,数据结构,链表)