链表的基本操作
链表的定义
链表是一种物理地址非连续,存储位置不连续,存储结构是由每一个链表指针连接起来的一种存储结构。
存储结构:
链表还有很多形式,不过常见的有如下几种:
1.带头
2.不带头
3.单向
4.双向
3.循环
非循环
但我们一般常用的就两种:1.无头单链表 2.带头双向循环链表
1.无头单链表的的基本操作的实现
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType _data;
struct SListNode* _next;
}SListNode;
typedef struct SList
{
SListNode* _head;
}SList;
void SListInit(SList* plist)
{
assert(plist);
plist->_head = NULL;
}
void SListDestory(SList* plist)
{
assert(plist);
SListNode* cur = plist->_head;
while (cur != NULL)
{
SListNode* next = cur->_next;
free(cur);
cur = next;
}
}
SListNode* BuySListNode(SLTDataType x)
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
newnode->_data = x;
newnode->_next = NULL;
return newnode;
}
void SListPushFront(SList* plist, SLTDataType x)
{
/*assert(plist);
SListNode* head = plist->_head;
SListNode* newnode = BuySListNode(x);
newnode->_next = head;
head = newnode;*/
assert(plist);
SListNode* newnode = BuySListNode(x);
newnode->_next = plist->_head;
plist->_head = newnode;
}
void SListPopFront(SList* plist)
{
assert(plist);
SListNode* cur = plist->_head->_next;
free(plist->_head);
plist->_head = cur;
}
SListNode* SListFind(SList* plist, SLTDataType x)
{
assert(plist);
SListNode* cur = plist->_head;
while (cur!=NULL)
{
if (cur->_data == x)
{
return cur;
}
cur=cur->_next;
}
return NULL;
}
void SListPushBack(SList* plist, SLTDataType x)
{
assert(plist);
SListNode* newnode = BuySListNode(x);
SListNode* end = plist->_head;
while (end->_next != NULL)
{
end = end->_next;
}
end->_next = newnode;
newnode->_next = NULL;
}
void SListPopBack(SList* plist)
{
assert(plist);
SListNode* head = plist->_head;
SListNode* prev = NULL;
while (head->_next != NULL)
{
prev = head;
head = head->_next;
}
free(head);
prev->_next = NULL;
}
// 在pos的后面进行插入
void SListInsertAfter(SListNode* pos, SLTDataType x)
{
assert(pos);
SListNode* newnode = BuySListNode(x);
SListNode* next = pos->_next;
pos->_next = newnode;
newnode->_next = next;
}
void SListEraseAfter(SListNode* pos)
{
SListNode* nextnext = pos->_next->_next;
SListNode* next = pos->_next;
free(next);
pos->_next = nextnext;
}
void SListRemove(SList* plist, SLTDataType x)
{
assert(plist);
SListNode* cur = plist->_head;
while (cur->_next != NULL)
{
if (cur->_next->_data == x)
{
SListNode* pos = SListFind(plist, 3);
SListEraseAfter(pos);
}
cur = cur->_next;
}
}
void SListPrint(SList* plist)
{
assert(plist);
SListNode* cur = plist->_head;
while (cur)
{
printf("%d ", cur->_data);
cur = cur->_next;
}
}
单向链表我们通过接口实现可以发现它对于找到它前面一个数比较困难,但是相较于顺序表,在插入和删除上效率提高了不少。