栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

初级数据结构--单链表和双链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

初级数据结构--单链表和双链表

文章目录
  • 编者前言
  • 单链表的创建,申请,销毁,打印
    • 单边表的尾插,头插,尾删,头删
    • 单链表的查找,pos之后的插入,删除,之前的插入
    • 是否空链表,链表元素个数
  • 双向链表的申请,空否,销毁,打印
    • 双向链表的尾插,头插,尾删,头删
    • pos前的插入,删除pos节点
  • 编者寄语

编者前言

链表的题多用双指针,三指针,快慢指针,头指针等解决。画图,写一项调试一项。

单链表的创建,申请,销毁,打印

创建,申请

#pragma once
#include
#include
#include
#include

typedef int DaT;

typedef struct SListNode
{
	struct SListNode* next;
	DaT data;
}SL;

申请
SL* BuyNode(DaT x)
{
	SL* node = (SL*)malloc(sizeof(SL));
	if (node == NULL)
	{
		printf("malloc failedn");
		exit(-1);
	}
	node->data = x;
	node->next = NULL;
	return node;
}

打印,销毁

void SLPrint(SL* phead)
{
	SL* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULLn");
}

void DestorySL(SL** phead)
{
	assert(phead);
	SL* cur = *phead;
	while (cur)
	{
		SL* next = cur->next;
		free(cur);
		cur = next;
	}
	*phead = NULL;
}
单边表的尾插,头插,尾删,头删

尾部插入,头部插入

void SLPushBcak(SL** phead, DaT x)
{
	assert(phead);
	if (*phead == NULL) 如果为空,则申请开辟一个结点
	{
		SL* newnode = BuyNode(x);
		*phead = newnode;
	}
	else 不为空,则找尾
	{
		SL* cur = *phead;
		while (cur->next!=NULL)
		{
			cur = cur->next;
		}
		SL* newn = BuyNode(x);
		cur->next = newn;
	}
}

头插
void SLPushFront(SL** phead, DaT x)
{
	assert(phead);
	SL* newnode = BuyNode(x);
	newnode->next = *phead;
	*phead = newnode;  始终指向第一个结点
}

尾删,头删

void SLPopBcak(SL** phead)
{
	assert(phead);
	assert(*phead); 为空调用尾删->向标准错误设备写入一条消息并调用abort,终止程序的执行。

	 一个结点时,
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		SL* cur = *phead;
		SL* prev = NULL;
		while (cur->next != NULL)
		{
			prev = cur;
			cur = cur->next;
		}
		free(cur);
		prev->next = NULL;
	}
}

头删
void SLPopFront(SL** phead)
{
	assert(phead);
	 一个结点时,
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		SL* cur = *phead;
		*phead = cur->next;
		free(cur);
	}
}
单链表的查找,pos之后的插入,删除,之前的插入

查找

SL* SLFind(SL* phead, DaT x)
{
	assert(phead);
	SL* cur = phead;
	while (cur->data != x && cur)
	{
		cur = cur->next;
	}
	return cur;
}

pos之后的插入,删除

void SLInsertAft(SL* pos, DaT x)
{
	assert(pos);
	SL* newn = BuyNode(x);
	newn->next = pos->next;
	pos->next = newn;
}

删除
void SLEarse(SL** phead, SL* pos)
{
	assert(phead);
	assert(pos);
	如果pos是指向第一个节点,就调头删
	if (pos == *phead)
	{
		SLPopFront(phead);
	}
	else
	{
		SL* del = *phead;
		while (del->next != pos)
		{
			del = del->next;
		}
		del->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

pos之前的插入
void SLInsert(SL** phead, SL* pos, DaT x)
{
	assert(phead);
	assert(pos);
	if (pos == *phead)
	{
		SLPushFront(phead,x); 如果pos是指向第一个节点,则调用头插
	}
	else
	{
		SL* cur = *phead;
		while (cur->next != pos)
		{
			cur = cur->next;
		}
		SL* newnode = BuyNode(x);
		newnode->next = pos;
		cur->next = newnode;
	}
}
是否空链表,链表元素个数

外部调用

SL* pl = NULL;
printf("几个元素:%dn", SLsize(pl));
printf("是否为空:%d", SLEmpty(pl));

空链表,链表元素个数

 个数
int SLsize(SL* phead)
{
	int count = 0;
	SL* cur = phead;
	while (cur)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
 
  空判定
  bool SLEmpty(SL* phead)
{
	return phead == NULL ? true : false;
}
双向链表的申请,空否,销毁,打印

双向链表头节点不存储数据。

申请

typedef struct DListN
{
	struct DListN* prev;
	struct DListN* next;
	DaT data;
}DL;

DL* DListCreat()
{
	DL* phead = (DL*)malloc(sizeof(DL));
	phead->next = phead->prev = phead;
	return phead;
}

 空否
bool DListEmpty(DL* pdl)
{
	assert(pdl);
	return pdl->next == pdl ? true : false;
}

销毁

void DListDestory(DL* pdl)
{
	DL* del = pdl->next;
	while (del != pdl)
	{
		DL* next = del->next;
		free(del);
		del = next;
	}
	free(pdl);
}

 打印
 void DListPrint(DL* pdl)
{
	assert(pdl);
	DL* cur = pdl->next;
	while (cur != pdl)
	{
		printf("%d<->", cur->data);
		cur = cur->next;
	}
	printf("NULLn");
}
双向链表的尾插,头插,尾删,头删

尾插,头插

void DListPushBack(DL* pdl, DaT x)
{
	assert(pdl);
	DL* newn = DListBuy(x);
	一个节点都没有
	if (pdl->next == NULL)
	{
		pdl->next = pdl->prev = newn;
		newn->next = newn->prev = pdl;
	}
	else
	{
		(pdl)->prev->next = newn;
		newn->prev = (pdl)->prev;
		(pdl)->prev = newn;
		newn->next = (pdl);
	}
}

尾删,头删

void DListPopBack(DL* pdl)
{
	assert(pdl);
	assert(!DListEmpty(pdl));
	DL* del = pdl->prev;
	del->prev->next = pdl;
	pdl->prev = del->prev;
	free(del);
}

头删
void DListPopFront(DL* pdl)
{
	assert(pdl);
	assert(!DListEmpty(pdl));
	DL* cur = pdl->next;
	pdl->next = cur->next;
	cur->next->prev = pdl;
	free(cur);
}
pos前的插入,删除pos节点

  pos之前插入
void DListInterpos(DL* pos, DaT x)
{
	assert(pos);
	DL* posprev = pos->prev;
	DL* newn = DListBuy(x);
	posprev->next = newn;
	newn->prev = posprev;
	newn->next = pos;
	pos->prev = newn;
}


  删除pos位置的节点
void DListOmit(DL* pos)
{
	assert(pos);
	/记住它的前指针后指针
	DL* posprev = pos->prev;
	DL* posnext = pos->next;
	free(pos);
	posprev->next = posnext;
	posnext->prev = posprev;
}
编者寄语

奶奶常说,学无止境,总有你没见过的错误…Don’t panic !

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/938176.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号