1.什么是链表
链表也是线性表的一种,他在逻辑结构上是连续的,但是在物理结构上是非顺序连接的,通过指针连接而在逻辑上成为线性表
那么链表有什么好处呢,首先在顺序表中,删除或者插入一个元素,需要把删除或者插入位置之后的元素往后移动一位,然后再操作,时间复杂度是O(n),但是在链表中,插入或者删除的操作只用断开连接链表就可以了.
链表分为单向,双向 ,带头节点,不带头节点,循环和非循环
下面就来看无头单链表的相关操作
#include<stdio.h>
#include<windows.h>
#include<assert.h>
typedef int SDataType;
//节点结构体
typedef struct SListNode {
SDataType data;
struct SListNode* pNext;
}Node, *PNode;
//链表结构体
typedef struct SList {
PNode pHead;
}SList,*PSList;
//创建一个新节点
PNode BuyNewNode(SDataType data) {
PNode ptr = NULL;
ptr = (PNode)malloc(sizeof(SDataType)+sizeof(PNode));
if (NULL == ptr) {
return NULL;
}
ptr->data = data;
ptr->pNext = NULL;
return ptr;
}
//链表初始化
void SListInit(SList* s) {
assert(s);
s->pHead = NULL;
}
//尾插
void SListPushBack(SList* s, SDataType data){
PNode PCur = NULL;//指向当前节点
assert(s);
//如果链表空,就加入新节点
if (s->pHead == NULL) {
s->pHead = BuyNewNode(data);
return;
}
PCur = s->pHead;
while (PCur->pNext) {
PCur = PCur->pNext;
}
PCur->pNext = BuyNewNode(data);
}
//尾删
void SListPopBack(SList* s) {
assert(s);
PNode PPre;//上一个节点
PNode PCur;//当前节点
PPre = s->pHead;
PCur = s->pHead;
//链表空
if (NULL == s->pHead) {
return;
}
if (PCur->pNext==NULL) {
free(s->pHead);
s->pHead = NULL;
return;
}
//一个以上节点
while (PCur->pNext) {
PPre = PCur;
PCur = PCur->pNext;
}
free(PPre->pNext);
PPre->pNext = NULL;
}
//头插
void SListPushFront(SList* s, SDataType data) {
assert(s);
PNode PCur = NULL;//当前
//链表空
if (NULL == s->pHead) {
s->pHead= BuyNewNode(data);
return;
}
PCur = s->pHead;
s->pHead = BuyNewNode(data);
s->pHead->pNext = PCur;
}
//头删
void SListPopFront(SList* s) {
assert(s);
PNode pre = NULL;
if (NULL == s->pHead) {
return;
}
if (s->pHead->pNext == NULL) {
free(s->pHead);
s->pHead = NULL;
}
pre = s->pHead;
s->pHead = s->pHead->pNext;
free(pre);
}
// 在链表的pos位置后插入值为data的节点
void SListInsert(SList* s,PNode pos, SDataType data) {
assert(s);
if (NULL == s->pHead) {
if (pos == s->pHead) {
s->pHead = BuyNewNode(data);
return;
}
else {
return;
}
}
if (pos = s->pHead) {
SListPushFront(s, data);
}
else {
PNode cur = NULL;
PNode pNewNode = BuyNewNode(data);
if (pos== NULL) {
free(pNewNode);
return;
}
else {
while (cur) {
if (pos==cur)
pos->pNext = pNewNode->pNext;
pos->pNext = pNewNode;
}
cur = cur->pNext;
}
}
return;
}
// 删除链表s中pos位置的节点
void SListErase(SList* s, PNode pos) {
assert(s);
PNode pre = s->pHead;
if (s->pHead == NULL) {
return;
}
if (s->pHead == pos) {
SListPopFront(s);
}
while ( (pre->pNext) != pos ) {
pre = pre->pNext;//pre是pos前一个
}
pre->pNext = pos->pNext;
free(pos);
}
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
PNode SListFind(SList* s, SDataType data) {
assert(s);
PNode cur = s->pHead;
while (cur) {
if (cur->data == data){
return cur;
continue;
}
}
}
// 获取链表中有效节点的个数
size_t SListSize(SList* s) {
assert(s);
size_t count = 0;
if (s->pHead == NULL) {
return 0;
}
while (s->pHead->pNext) {
count += 1;
}
return count;
}
// 检测链表是否为空
int SListEmpty(SList* s) {
assert(s);
if (s->pHead == NULL){
return 1;
}
else{
return 0;
}
}
// 将链表中有效节点清空
void SListClear(SList* s) {
assert(s);
if (s->pHead == NULL) {
return;
}
else {
s->pHead == NULL;
}
}
//销毁链表
void SListDestroy(SList* s) {
assert(s);
s->pHead = NULL;
free(s->pHead);
}