单链表(不带头)
程序员文章站
2024-03-21 14:44:58
...
slist.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//不带头链表
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 SListClear(SList* s);
// 销毁链表
void SListDestroy(SList* s);
slist.c
#include "slist.h"
// 链表的初始化
void SListInit(SList* s) {
assert(s);
s->_pHead = NULL;
}
PNode buyslistnode(SDataType data) {
PNode newnode = (PNode)malloc(sizeof(Node));
if (newnode == NULL) {
return NULL;
}
newnode->_data = data;
newnode->_pNext = NULL;
return newnode;
}
// 在链表s最后一个节点后插入值为data的节点
void SListPushBack(SList* s, SDataType data) {
assert(s);
PNode pnewnode = buyslistnode(data);
if (s->_pHead == NULL) {
s->_pHead = pnewnode;
}
else {
PNode ps;
ps = s->_pHead;
while (ps->_pNext) {
ps = ps->_pNext;
}
ps->_pNext = pnewnode;
}
}
// 删除链表s最后一个节点
void SListPopBack(SList* s) {
assert(s);
if (s->_pHead == NULL) {
printf("链表为空\n");
}
else if (s->_pHead->_pNext == NULL) {//只有一个节点
s->_pHead = NULL;
}
else {//多个节点
PNode ps;
ps = s->_pHead;
while (ps->_pNext) {
ps = ps->_pNext;
}
free(ps);
ps = 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 (s->_pHead == NULL) {
printf("链表为空\n");
}
else {
PNode pdhead=s->_pHead;
s->_pHead = pdhead->_pNext;
free(pdhead);
}
}
// 在链表的pos位置后插入值为data的节点
void SListInsert(PNode pos, SDataType data) {
PNode pnewnode = buyslistnode(data);
pnewnode->_pNext = pos->_pNext;
pos->_pNext = pnewnode;
}
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL
PNode SListFind(SList* s, SDataType data) {
assert(s);
PNode ps3;
ps3 = s->_pHead;
if (ps3->_data == data) {//只有一个节点
return ps3;
}
else {
while (ps3->_pNext != NULL) {
ps3 = ps3->_pNext;
if (ps3->_data == data) {
return ps3;
}
}
}
return NULL;
}
// 删除链表s中pos位置的节点
void SListErase(SList* s,PNode pos){
assert(s);
if (pos == NULL) {
printf("链表为空\n");
}
else if (pos == s->_pHead) {
s->_pHead = s->_pHead->_pNext;
}
else {
PNode pspre;
pspre = s->_pHead;
while (pspre->_pNext != pos) {
pspre = pspre->_pNext;
}
pspre->_pNext = pos->_pNext;
}
}
// 获取链表中有效节点的个数
size_t SListSize(SList* s) {
int count = 0;
PNode pssize = s->_pHead;
while (pssize) {
pssize = pssize->_pNext;
count++;
}
return count;
}
// 将链表中有效节点清空
void SListClear(SList* s) {
assert(s);
s->_pHead = NULL;
}
test.c
#include "slist.h"
int main() {
SList arr;
PSList s = &arr;
SListInit(s);
SListPushBack(s, 1);
SListPushFront(s, 2);
SListPushBack(s, 1);
SListPushBack(s, 3);
SListPushBack(s, 1);
SListPushBack(s, 1);
SListInsert(SListFind(s, 3),5);
SListErase(s, SListFind(s, 3));
if (s->_pHead == NULL) {
printf("链表为空\n");
}
else {
printf("%d\n", s->_pHead->_data);
PNode ps1 = s->_pHead;
while (ps1->_pNext != NULL) {
printf("%d\n", ps1->_pNext->_data);
ps1 = ps1->_pNext;
}
}
system("pause");
}