之前写了动态顺序表的实现,但动态顺序表还是存在以下问题
- 中间/头部的插入删除,时间复杂度为O(N)
- 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
- 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,
我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
所以我们有引入一种新的数据结构链表来解决顺序表所存在的问题
** SList.h**
#ifndef __SLIST_H__
#define __SLIST_H__
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int SLDataType;
typedef struct SListNode
{
SLDataType _a;
struct SListNode* _next;
}SListNode;
typedef struct SList
{
SListNode* _head;
}SList;
void SListInit(SList* psl);
void SListDestory(SList* psl);
void SListPushBack(SList* psl, SLDataType x);
void SListPopBack(SList* psl);
void SListPushFront(SList* psl, SLDataType x);
void SListPopFront(SList* psl);
SListNode* SListFind(SList* psl, SLDataType x);
void SListInsertAfter(SListNode* pos, SLDataType x);//在指定位置后面插入
void SListEraseAfter(SListNode* pos);
void SListRemove(SList* psl, SLDataType x);
void SListPrint(SList* psl);
void Test();
#endif //__SLIST_H__
//单链表的头删和尾删都要对只有一个节点进行判断。
//单链表的头插入和尾插入,也要对只有一个节点进行处理;
** SList.h**
#include "SList.h"
void SListInit(SList* psl)
{
assert(psl);
psl->_head = NULL;
}
void SListDestory(SList* psl)
{
SListNode* cur = psl->_head;
SListNode* next = NULL;
assert(psl);
while(cur != NULL)
{
next = cur->_next;
free(cur);
cur = NULL;
cur = next;
}
psl->_head = NULL;
}
SListNode* SListBuyNode(SLDataType x)
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
newnode->_a = x;
newnode->_next = NULL;
return newnode;
}
void SListPushBack(SList* psl, SLDataType x)
{
SListNode* cur = psl->_head;
assert(psl);
if(psl->_head == NULL)
{
psl->_head = SListBuyNode(x);
}
else
{
while(cur->_next != NULL)
{
cur = cur->_next;
}
cur->_next = SListBuyNode(x);
}
}
void SListPopBack(SList* psl)
{
SListNode* prev = NULL;
SListNode* cur = psl->_head;
assert(psl);
//对只有一个节点特殊处理
if(cur->_next == NULL)
{
free(cur);
cur = NULL;
psl->_head = NULL;
}
else
{
//单链表找尾,用指针的next判断
while(cur->_next != NULL)
{
prev = cur;
cur = cur->_next;
}
free(cur);
cur = NULL;
prev->_next = NULL;
}
}
void SListPushFront(SList* psl, SLDataType x)
{
SListNode* node = NULL;
assert(psl);
if(psl->_head == NULL)
{
psl->_head = SListBuyNode(x);
}
else
{
node = SListBuyNode(x);
node->_next = psl->_head;
psl->_head = node;
}
}
void SListPopFront(SList* psl)
{
SListNode* del = psl->_head;
assert(psl);
if(del->_next == NULL)
{
free(del);
del = NULL;
psl->_head = NULL;
}
else
{
psl->_head = del->_next;
free(del);
del = NULL;
}
}
void SListPrint(SList* psl)
{
SListNode* cur = psl->_head;
assert(psl);
while(cur != NULL)
{
printf("%d ", cur->_a);
cur = cur->_next;
}
printf("\n");
}
void SListInsertAfter(SListNode* pos, SLDataType x)
{
SListNode* next = pos->_next;
SListNode* node = NULL;
assert(pos);
node = SListBuyNode(x);
pos->_next = node;
node = next;
}
void SListEraseAfter(SListNode* pos)
{
SListNode* del = pos->_next;
SListNode* next = del->_next;
pos->_next = next;
free(del);
del = NULL;
}
SListNode* SListFind(SList* psl, SLDataType x)
{
SListNode* cur = psl->_head;
assert(psl);
while(cur != NULL)
{
if(cur->_a == x)
{
return cur;
}
else
{
cur = cur->_next;
}
}
return NULL;
}
void SListRemove(SList* psl, SLDataType x)
{
SListNode* prev = NULL;
SListNode* pos = psl->_head;
assert(psl);
while(pos != NULL)
{
prev = pos;
if(pos->_a == x)
{
break;
}
else
{
pos = pos->_next;
}
}
if(pos == NULL)
{
;
}
else
{
prev->_next = pos->_next;
free(pos);
pos = NULL;
}
}
void Test()
{
SList s;
SListInit(&s);
SListPushBack(&s, 1);
SListPushBack(&s, 2);
SListPushBack(&s, 3);
SListPushBack(&s, 4);
SListPrint(&s);
//SListPopBack(&s);
//SListPopBack(&s);
//SListPopBack(&s);
//SListPopBack(&s);
SListPushFront(&s, 10);
/*SListPopBack(&s);
SListPopFront(&s);
SListPopFront(&s);
SListPopFront(&s);*/
SListPrint(&s);
}