不带头单向不循环链表是一种数据结构,它由一系列的节点组成,每个节点包含两部分:数据域和指针域。在这种类型的链表中:
这种类型的数据结构被广泛应用于需要顺序访问、插入或删除操作场景中。例如,在编程语言库、操作系统内核以及算法设计等领域都有大量应用案例。
接下来给出不带头单向不循环链表的简单实现ovo
SLTList.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
//定义节点结构体
typedef struct SListNode
{
SLDataType data;
struct SListNode* next;
}SLNode;
//打印链表
void SLPrint(SLNode* phead);
//头部插入
void SLPushFront(SLNode** pphead, SLDataType x);
//尾部插入
void SLPushBack(SLNode** pphead, SLDataType x);
//头部删除
void SLPopFront(SLNode** pphead);
//尾部删除
void SLPopBack(SLNode** pphead);
//查找
SLNode* SLFind(SLNode** pphead, SLDataType x);
//在指定位置之前插入数据
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x);
//指定位置之后插入数据
void SLInsertAfter(SLNode* pos, SLDataType x);
//删除pos节点
void SLErase(SLNode** pphead, SLNode* pos);
//删除pos之后的节点
void SLEraseAfter(SLNode* pos);
//销毁链表
void SLDestroy(SLNode** pphead);
SLTList.c
#include "SLTlist.h"
void SLPrint(SLNode* phead)
{
SLNode* pcur = phead;
while (pcur)
{
printf("%d->", pcur->data);
pcur = pcur->next;
}
printf("\n");
}
//创建新节点的函数
SLNode* SLBuyNode(SLDataType x)
{
SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
newnode->data = x;
newnode->next= NULL;
return newnode;//返回新创建节点的地址
}
//尾插函数
void SLPushBack(SLNode** pphead, SLDataType x)
{
assert(pphead);//一级指针的地址不能为0
SLNode* newnode = SLBuyNode(x);
//链表为空,新节点就作为头节点
if (*pphead == NULL)
{
*pphead = newnode;
return;
}
//链表不为空,要找尾节点
SLNode* ptail = *pphead;//尾节点初始值为头节点
while (ptail->next)
{
ptail = ptail->next;
}
//出了循环后,ptail放的就是尾节点地址
ptail->next = newnode;
}
//头插函数
void SLPushFront(SLNode** pphead, SLDataType x)
{
assert(pphead);//一级指针地址不为空
SLNode* newnode = SLBuyNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
//尾删函数
void SLPopBack(SLNode** pphead)
{
assert(pphead);//一级指针的地址不为空
assert(*pphead);//链表不能为空
//链表只有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
SLNode* ptail = *pphead;
SLNode* prev = NULL;
while(ptail->next)
{
prev = ptail;
ptail = ptail->next;
}//出循环代表找到了尾节点
prev->next = NULL;//销毁尾节点
free(ptail);
ptail = NULL;
}
//头部删除
void SLPopFront(SLNode** pphead)
{
assert(pphead);
assert(*pphead);
SLNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
//查找
SLNode* SLFind(SLNode** pphead, SLDataType x)
{
assert(pphead);
SLNode* pcur = *pphead;
while (pcur)
{
if (pcur->data == x)
{
return pcur;
}
pcur = pcur->next;
}
return NULL;
}
//在指定位置之前插入数据
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x)
{
assert(pphead);
assert(pos);
assert(*pphead);
SLNode* newnode = SLBuyNode(x);
//如果pos刚好是头节点,直接调用头插
if (pos == *pphead)
{
SLPushFront(pphead, x);
return;
}
//pos不是头节点,需要找前序节点
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
//出了循环以后找到了pos的前一个节点
prev->next = newnode;
newnode->next = pos;
}
//指定位置之后插入数据
void SLInsertAfter(SLNode* pos, SLDataType x)
{
assert(pos);
SLNode* newnode = SLBuyNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
//删除pos节点
void SLErase(SLNode** pphead, SLNode* pos)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (*pphead == pos)
{
SLPopFront(pphead);
return;
}
//pos不是头节点,需要去找前序节点
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
//删除pos之后的节点
void SLEraseAfter(SLNode* pos)
{
assert(pos);
assert(pos->next);
SLNode* del = pos->next;
pos->next = pos->next->next;
free(del);
del = NULL;
}
//销毁链表
void SLDestroy(SLNode** pphead)
{
assert(pphead);
assert(*pphead);
SLNode* pcur = *pphead;
while (pcur)
{
SLNode* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL;
}
test.c
#include "SLTlist.h"
int main()
{
SLNode* plist = NULL;
SLPushBack(&plist, 1);
SLPushBack(&plist, 2);
SLPushBack(&plist, 3);
SLPushBack(&plist, 4);
SLPushBack(&plist, 5);
SLPrint(plist);
SLPushFront(&plist, 6);
SLPushFront(&plist, 7);
SLPrint(plist);
SLPopBack(&plist);
SLPopFront(&plist);
SLPrint(plist);
SLNode* ret =SLFind(&plist, 1);
SLInsertAfter(ret, 100);
SLPrint(plist);
SLEraseAfter(ret);
SLPrint(plist);
SLErase(&plist, ret);
SLPrint(plist);
return 0;
}
以上就是该链表的简单实现啦!大家有什么疑惑可以在下方评论或私信我哦~