链表——单向链表 主要包括:《 单链表的完整接口实现代码 和 执行结果 》

双线链表的实现及代码:https://blog.youkuaiyun.com/dpfxaca6/article/details/89490360
顺序表的接口实现及代码:https://blog.youkuaiyun.com/dpfxaca6/article/details/86717082

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

在这里插入图片描述
在我们的实际链表应用中,有许多的样子的,总结一下就是8中结构:

1. 单向、双向
2. 带头、不带头
3. 循环、非循环

就是 《 二的三次方 》这种算法

虽然我们有八种样子,但是我们主要实现的还是两种比较常见的链表,

《一》 无头,单向,不循环
《二》 带头 ,双向 ,循环

在这里插入图片描述
首先这里我们实现的是第一种,下面的另外一种,我们在后面的一篇博客里面解释说明一下。

第一种链表——无头,单向,不循环

无头,单向,不循环:结构比较简单,一般不会单独用来储存数据,实际中大多是作为其他数据的子结构

下面我们就是实现一下这个链表的代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include<string.h>

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 SListPushBack(SList* plist, SLTDataType x);   //尾插
void SListPushFront(SList* plist, SLTDataType x);  //头插
void SListPopBack(SList* plist);     //尾删
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();

上面为我们实现的接口,如果厉害的同学,可以自己先实现一下,然后再考考虑看我下面的实现。

#include"SListNode.h"

void SListDestory(SList* plist)
{
	assert(plist);
	SListNode* cur = plist->_head;
	while (cur)
	{
		SListNode* next = cur->_next;
		free(cur);
		cur = next;
	}
}
SListNode* BuySListNode(SLTDataType x)
{
	SListNode * node = (SListNode*)malloc(sizeof(SListNode));
	assert(node);
	node->_data = x;
	node->_next = NULL;
	return node;
}
//先构建一个链表
void SListInit(SList* plist)
{
	assert(plist);
	plist->_head = NULL;

}
//尾插
void SListPushBack(SList* plist, SLTDataType x)
{
	SListNode* tail = plist->_head;
	SListNode*newtail;
	assert(plist);
	if (plist->_head == NULL)
	{
		plist->_head = BuySListNode(x);
	}
	else
	{
		while (tail->_next != NULL)
		{
			tail = tail->_next;
		}

		newtail = BuySListNode(x);
		tail->_next = newtail;
	}
}
//头插
void SListPushFront(SList* plist, SLTDataType x)
{
	SListNode * newhead = BuySListNode(x);
	assert(plist);
	newhead->_next = plist->_head;
	plist->_head = newhead;

}
//尾删
void SListPopBack(SList* plist)
{
	SListNode*tail = plist->_head;
	SListNode*prev = NULL;
	assert(plist);
	if (plist->_head->_next == NULL)
	{
		free(plist->_head);
		plist->_head = NULL;
	}
	else
	{
		while (tail->_next != NULL)
		{
			prev = tail;
			tail = tail->_next;
		}
		free(tail);
		prev->_next = NULL;
	}
}
//头删
void SListPopFront(SList* plist)
{
	SListNode*newhead = plist->_head;
	assert(plist);
	if (plist->_head == NULL)
	{
		free(plist->_head);
		plist->_head = NULL;
	}
	else
	{
		plist->_head = newhead->_next;
		free(newhead);
		newhead = NULL;
	}

}
//首先先找到该节点
SListNode* SListFind(SList* plist, SLTDataType x)
{
	SListNode*cur = plist->_head;
	assert(plist);
	while (cur != NULL)
	{
		if (cur->_data == x)
		{
			return cur;
		}
		cur = cur->_next;
	}
	return cur;
}
// 在pos的后面进行插入
void SListInsertAfter(SListNode* pos, SLTDataType x)
{
	SListNode * newnode = BuySListNode(x);
	assert(pos);
	newnode->_next = pos->_next;
	pos->_next = newnode;
}
// 在pos的前面进行插入
void SListEraseAfter(SListNode* pos)
{
	assert(pos && pos->_next);
	SListNode* next = pos->_next;
	SListNode* nextnext = next->_next;
	pos->_next = nextnext;
	free(next);
	next = NULL;

}
void SListPrint(SList* plist)
{
	SListNode* cur;
	assert(plist);
	cur = plist->_head;
	while (cur)
	{
		printf("%d->", cur->_data);
		cur = cur->_next;
	}
	printf("NULL\n");
}

这里就是我们实现的代码

#include"SListNode.h"
     int main()
        {
        	SList s;
        	SListInit(&s);
        	SListPushBack(&s, 1);
        	SListPushBack(&s, 2);
        	SListPushBack(&s, 3);
        	SListPushBack(&s, 4);
        	SListPushBack(&s, 5);
        	SListPrint(&s);
        
	SListPushFront(&s,0);
	   SListPrint(&s);

	SListPopBack(&s);
	   SListPrint(&s);

	SListPopFront(&s);
	   SListPrint(&s);

	SListNode* pos = SListFind(&s, 3);
	SListInsertAfter(pos, 30);
	SListPrint(&s);


	SListEraseAfter(pos);
	SListPrint(&s);
	SListDestory(&s);
}

这里就是我们实现的总体代码,大家就是参考一下,有好的思想,可以在我下面评论,写上你的链接,我会去看的。

下来我们就看一下程序执行的结果

在这里插入图片描述

这里就是我们总的实现单链表的实现代码,双向链表的实现,我放在下一篇的博客,然后再把他们区别放在下一篇博客里面,到时候我们把链接放在下面的,给大家提供方便

双线链表的实现及代码:https://blog.youkuaiyun.com/dpfxaca6/article/details/89490360
顺序表的接口实现及代码:https://blog.youkuaiyun.com/dpfxaca6/article/details/86717082

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值