单链表
实现基于单链表的以下操作:
- 链表的初始化
- 在链表s最后一个节点后插入值为data的节点
- 删除链表s最后一个节点
- 在链表s第一个节点前插入值为data的节点
- 删除链表s的第一个节点
- 在链表的pos位置后插入值为data的节点
- 删除链表s中pos位置的节点
- 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
- 获取链表中有效节点的个数
- 检测链表是否为空
- 销毁链表
代码如下:
引入头文件,定义单链表
#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);
// 在链表s最后一个节点后插入值为data的节点
void SListPushBack(SList* s, SDataType data);
// 删除链表s最后一个节点
void SListPopBack(SList* s);
// 在链表s第一个节点前插入值为data的节点
void SListPushFront(SList* s, SDataType data);
// 删除链表s的第一个节点
void SListPopFront(SList* s);
// 在链表的pos位置后插入值为data的节点
void SListInsert(PNode pos, SDataType data);
// 删除链表s中pos位置的节点
void SListErase(SList* s, PNode pos);
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
PNode SListFind(SList* s, SDataType data);
// 获取链表中有效节点的个数
size_t SListSize(SList* s);
// 检测链表是否为空
int SListEmpty(SList* s);
// 销毁链表
void SListDestroy(SList* s);
具体功能的实现:
代码如下:
#include"SList.h"
#include<stdio.h>
#include<assert.h>
#include<mallloc.h>
// 链表的初始化
void SListInit(SList* s) {
assert(s);
s->_pHead = NULL;
}
//链表扩容
PNode BuySListNode(SDataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
if (NULL == pNewNode) {
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
// 在链表s最后一个节点后插入值为data的节点
void SListPushBack(SList* s, SDataType data) {
assert(s);
PNode pNewNode = BuySListNode;
if (NULL == s->_pHead) {
s->_pHead = pNewNode;
}
else {
PNode pCur = s->_pHead;
while (pCur->_pNext) {
pCur = pCur->_pNext;
}
pCur->_pNext = pNewNode;
}
}
// 删除链表s最后一个节点
void SListPopBack(SList* s) {
assert(s);
if (NULL == s->_pHead) {
printf("删除失败,链表为空");
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;
}
}
// 在链表s第一个节点前插入值为data的节点
void SListPushFront(SList* s, SDataType data) {
assert(s);
PNode pNewNode = BuySListNode(data);
pNewNode->_pNext = s->_pHead;
s->_pHead = pNewNode;
}
// 删除链表s的第一个节点
void SListPopFront(SList* s) {
assert(s);
if (NULL == s->_pHead) {
printf("删除失败");
return;
}
PNode pCur = s->_pHead;
s->_pHead = pCur->_pNext;
free(pCur);
}
// 在链表的pos位置后插入值为data的节点
void SListInsert(PNode pos, SDataType data) {
PNode pNewNode = NULL;
if (NULL == pos) {
return;
}
pNewNode = BuySListNode(data);
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
}
// 删除链表s中pos位置的节点
void SListErase(SList* s, PNode pos) {
assert(s);
if (NULL == s->_pHead) {
return;
}
else if (pos == s->_pHead) {
s->_pHead = pos->_pNext;
}
else {
PNode pPrepos = s->_pHead;
while (pPrepos && pPrepos->_pNext != pos)
pPrepos = pPrepos->_pNext;
if (pPrepos)
pPrepos->_pNext = pos->_pNext;
}
free(pos);
}
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
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) {
pCur = pCur->_pNext;
count++;
}
return count;
}
// 检测链表是否为空
int SListEmpty(SList* s) {
assert(s);
return NULL == s->_pHead;
}
// 销毁链表
void SListDestroy(SList* s) {
assert(s);
PNode pCur = NULL;
PNode pDel = NULL;
pCur = s->_pHead;
while (pCur) {
pDel = pCur;
pCur = pCur->_pNext;
free(pDel);
pDel = NULL;
}
s->_pHead == NULL;
}