什么是链表?链表的分类?
链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.
分类:
- 单向, 双向
- 不带头单链表, 带头单链表
- 单链表, 循环单链表
带头结点和不带头结点的区别
带头结点: head->p1->p2->p3
不带头结点: p1->p2->p3
带头结点单链表实现
SList.h
#pragma once
typedef int SDataType;
//链表的结点
typedef struct SListNode {
SDataType _data;
struct SListNode* _pNext;
}Node, *PNode;
typedef struct SList {
PNode _pHead; //指向链表中的第一个结点
}SList, *PSList;
//初始化链表
void SListInit(SList *s);
//尾插
void SListPushBack(SList *s, SDataType data);
//尾删
void SListPopBack(SList *s);
//头插
void SListPushFront(SList *s, SDataType data);
//头删
void SListPopFront(SList *s);
//在pos位置插入data
void SListInsert(PNode pos, SDataType data);
//删除pos位置的元素
void SListErase(SList *s, PNode pos);
//查找值为data的结点
PNode SListFind(SList *s, SDataType data);
//链表的有效元素个数
int SListSize(SList *s);
//链表为空则返回NULL
int SListEmpty(SList *s);
//移除第一个值为data的元素
void SListRemove(SList *s, SDataType data);
SList.c
#include "SList.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void SListInit(SList *s) {
assert(s);
s->_pHead = NULL;
}
PNode BuySListNode(SDataType data) {
PNode pNewNode = (PNode)malloc(sizeof(Node));
if (pNewNode == NULL) {
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
void SListPushBack(SList *s, SDataType data) {
assert(s);
PNode pNewNode = BuySListNode(data);
if (s->_pHead == NULL) {
//空链表
s->_pHead = pNewNode;
}
else {
//链表非空
//找链表的最后一个结点
PNode pCur = s->_pHead;
while (pCur->_pNext) {
pCur = pCur->_pNext;
}
pCur->_pNext = pNewNode;
}
}
void SListPopBack(SList *s) {
assert(s);
if (s->_pHead == NULL) {
return;
}
else if (s->_pHead->_pNext == NULL) {
free(s->_pHead);
s->_pHead = NULL;
}
else {
PNode pPre = NULL;
PNode pCur = s->_pHead;
while (pCur->_pNext) {
pPre = pCur;
pCur = pCur->_pNext;
}
free(pCur);
pPre->_pNext = NULL;
}
}
void PrintSList(SList *s) {
assert(s);
PNode pCur = s->_pHead;
while (pCur) {
printf("%d--->", pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
void SListPushFront(SList *s, SDataType data) {
assert(s);
PNode pNewNode = BuySListNode(data);
pNewNode->_pNext = s->_pHead;
s->_pHead = pNewNode;
}
void SListPopFront(SList *s) {
PNode pDelNode = NULL;
assert(s);
if (s->_pHead == NULL) {
return;
}
//找到待删除的结点
pDelNode = s->_pHead;
s->_pHead = pDelNode->_pNext;
free(pDelNode);
}
void SListInsert(PNode pos, SDataType data) {
PNode pNewNode = NULL;
if (pos == NULL) {
return;
}
pNewNode = BuySListNode(data);
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
}
void SListErase(SList *s, PNode pos) {
assert(s);
if (pos == NULL || s->_pHead == NULL) {
return;
}
else {
PNode pPrePos = s->_pHead;
while (pPrePos && pPrePos->_pNext != pos) {
pPrePos = pPrePos->_pNext;
}
if (pPrePos) {
pPrePos->_pNext = pos->_pNext;
}
}
free(pos);
}
PNode SListFind(SList *s, SDataType data) {
assert(s);
PNode pCur = s->_pHead;
while (pCur) {
if (pCur->_data == data) {
return pCur;
}
pCur = pCur->_pNext;
}
return NULL;
}
int SListSize(SList *s) {
assert(s);
PNode pCur = s->_pHead;
size_t count = 0;
while (pCur) {
count++;
pCur = pCur->_pNext;
}
return count;
}
int SListEmpty(SList *s) {
assert(s);
return s->_pHead == NULL;
}
void SListRemove(SList *s, SDataType data) {
assert(s);
if (s->_pHead == NULL) {
return;
}
//找结点
PNode pPre = NULL;
PNode pCur = s->_pHead;
while (pCur) {
if (pCur->_data == data) {
if (pCur == s->_pHead) {
s->_pHead = pCur->_pNext;
}
else {
pPre->_pNext = pCur->_pNext;
}
free(pCur);
return;
}
else {
pPre = pCur;
pCur = pCur->_pNext;
}
}
}