双线链表的实现及代码: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