《数据结构》-链表

13 篇文章 0 订阅

3.链表

3.1 链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的 。
现实中:
在这里插入图片描述

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:

  1. 单向、双向
  2. 带头、不带头
  3. 循环、非循环
    在这里插入图片描述

常见
在这里插入图片描述

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结
构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向
循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而
简单了,后面我们代码实现了就知道了。

                               3.2链表的实现
// 1、无头单向非循环链表增删查改实现
typedef int SLTDataType;
typedef struct SListNode
{
 SLTDataType _data;
 struct SListNode* _next;
}SListNode;
typedef struct SList
{
 SListNode* _head;
}SList;
void SListInit(SList* plist);
void SListDestory(SList* plist);
SListNode* BuySListNode(SLTDataType x);
void SListPushFront(SList* plist, SLTDataType x);
void SListPopFront(SList* plist);
SListNode* SListFind(SList* plist, SLTDataType x);
// 在pos的后面进行插入
void SListInsertAfter(SListNode* pos, SLTDataType x);
// 在pos的前面进行插入
void SListEraseAfter(SListNode* pos);
void SListRemove(SList* plist, SLTDataType x);
void SListPrint(SList* plist);
void TestSList(); 
// 2、带头双向循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
 LTDataType _data;
 struct ListNode* _next;
 struct ListNode* _prev;
}ListNode;
typedef struct List
{
 ListNode* _head;
}List;
void ListInit(List* plist);
void ListDestory(List* plist);
void ListPushBack(List* plist, LTDataType x);
void ListPushBack(List* plist);
void ListPushFront(List* plist, LTDataType x);
void ListPopFront(List* plist);
ListNode* ListFind(List* plist, LTDataType x);
// 在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 删除pos位置的节点
void ListErase(ListNode* pos);
void ListRemove(List* plist, LTDataType x);
void ListPrint(List* plist);

4.顺序表和链表的区别和联系

顺序表:
优点:空间连续、支持随机访问
1.中间或前面部分的插入删除时间复杂度O(N)
2.增容的代价比较大。

链表:
缺点;以节点为单位存储,不支持随机访问
优点:1.任意位置插入删除时间复杂度为O(1)
2.没有增容问题,插入一个开辟一个空间。

接口实现:

#define _CRT_SECURE_NO_WARNINGS 1

#include "Slist.h"
SlistNode* Slistbyroom(SlistType x)
{
	SlistNode* node = malloc(sizeof(SlistNode));
	node->Date = x;
	node->next = NULL;	
	return node;

}
void Slistpopback(SlistNode** plist)
{
	SlistNode* tail = *plist;
	SlistNode* head = *plist;

	if (*plist == NULL)
	{
		free(*plist);
	}

	while (tail->next!=NULL)
	{
		head = tail;
		tail = tail->next;
	}
	
	free(tail);
	head->next = NULL;


}

void Slistprint(SlistNode** plist)//打印
{
	SlistNode* til = *plist;
	while (til)
	{
		printf("%d->", til->Date);
		til = til->next;
	}
	printf("NULL\n");

}
void SlistpopFront(SlistNode** plist)//头删
{
	SlistNode* tail= *plist;
	SlistNode* head = *plist;



	if (*plist == NULL)
	{
		free(*plist);

	}
	else
	{
		tail = tail->next;
		*plist = tail;
		free(head);
		
	}

}


void SlistpushFront(SlistNode** plist, SlistType x)//头插

{
	SlistNode* newnode = Slistbyroom(x);
	if (*plist == NULL)
	{
		*plist = newnode;
	}
	else
	{

		SlistNode* str = *plist;
		*plist = newnode;
		newnode->next = str;
	}

}
void Slistpushback(SlistNode** plist, SlistType x)//尾插
{
	SlistNode* newnode=Slistbyroom(x);

	if (*plist==NULL)
	{
		*plist = newnode;
	}
	else
	{
		SlistNode* str = *plist;

		while (str->next != NULL)
		{
			str = str->next;
			
		}
		str->next = newnode;
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值