SList.c
#include"singlist.h"
SLTNode* BuyListNode(SLDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//扩容
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;//把插入的元素赋值newnode
newnode->next = NULL;//把插入的数的next至NULL
return newnode;
}
void SListPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur != NULL)
{
printf("%d->",cur->data);
cur = cur->next;//打印完让其指向下一个元素,直到找到NULL,打印完
}
printf("NULL\n");
}
void SListPushBack(SLTNode** pphead, SLDataType x)//因为要改变pphead的值因此要传二级指针
{
assert(pphead);
SLTNode* newnode=BuyListNode(x);
if (*pphead == NULL)//头为空
{
*pphead = newnode;//只有头为空时,才需要改变
}
else//头不为空,则找到尾节点
{
//找到尾节点
SLTNode* tail = *pphead;
while (tail->next != NULL)//找到NULL,即找到最后一个数据
{
tail = tail->next;//把第一个next给下一个tail
}
tail->next = newnode;//把尾元素的next指向插入元素的data
}
}
void SListPushFront(SLTNode** pphead, SLDataType x)//因为要改变pphead的值因此要传二级指针
{
assert(pphead);
SLTNode* newnode = BuyListNode(x);//创建一个新的节点
newnode->next = *pphead;//把新节点的next指向旧头节点
*pphead = newnode;//把头节点指向新的头节点
}
void SListPopFront(SLTNode** pphead)//头删
{
assert(pphead);
assert(*pphead != NULL);
SLTNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
void SListPophBack(SLTNode** pphead)//尾删
{
assert(pphead);
assert(*pphead != NULL);//1.一个节点
if ((*pphead)->next == NULL)//2.二个节点
{
free(*pphead);
*pphead = NULL;
}
else //3.二个以上的节点
{
SLTNode* prev = NULL;//记录上一个节点,为了防止无法找到上一个节点
SLTNode* tail = *pphead;//记录第二个节点
while (tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail->next);//释放最后一个节点
tail = NULL;//最后一个节点至NULL
prev->next = NULL;//最后一个节点的上一个节点也至NULL
}
}
SLTNode* SListFind(SLTNode* phead, SLDataType x)//找到了也可以修改其值, 这就是为什么要传址
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
else
{
cur = cur->next;
}
}
return NULL;
}
void SListInsertAfter(SLTNode* pos, SLDataType x)//在pos后插入,更适合单链表
{
assert(pos);
SLTNode* newnode = BuyListNode(x);
newnode->next = pos->next;//先把下一个节点记录,为了防止找不到
pos->next = newnode;
}
void SListInsert(SLTNode** pphead, SLTNode* pos, SLDataType x)
{
assert(pphead);
assert(pos);
SLTNode* newnode = BuyListNode(x);
if (*pphead == pos)//如果插入的为头节点
{
newnode->next = *pphead;
*pphead = newnode;
}
else//插入不是头节点
{
SLTNode* posPrev = *pphead;//posPrev记录前一个节点
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = newnode;
newnode->next = pos;
}
}
void SListEraseAfter(SLTNode* pos)//删除pos后一个位置
{
assert(pos->next!=NULL);
SLTNode* next = pos->next;
pos->next = next->next;
free(next);
next = NULL;//至空不至空都行
}
void SListErase(SLTNode** pphead, SLTNode* pos)//删除前一个位置
{
assert(pphead);
assert(pos);
if (*pphead == pos)//如果删除的为头节点
{
SListPopFront(pphead);
}
else//删除不是头节点
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
//void SListErase(SLTNode** pphead, SLTNode* pos)//删除前一个位置
//{
// assert(pphead);
// assert(pos);
//
// SLTNode* cur = *pphead;
// if (*pphead == pos)//如果删除的为头节点
// {
// cur = (*pphead)->next;
// free(*pphead);
// *pphead = cur;
// }
// else//删除不是头节点
// {
// SLTNode* posPrev = *pphead;
// while (posPrev->next != pos)
// {
// posPrev = posPrev->next;
// }
// posPrev->next = posPrev->next->next;
// free(pos);
// }
//}
void SListDestory(SLTNode** pphead)
{
assert(pphead);
SLTNode* cur = *pphead;
while (cur)
{
SLTNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
SList.h
#pragma once
#include<stdio.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SListNode
{
SLDataType data;//数据
struct SListNode* next;//指向下一个数的结点
}SLTNode;
void SListPrint(SLTNode* phead);
void SListPushBack(SLTNode** pphead,SLDataType x);//尾插
void SListPushFront(SLTNode** pphead, SLDataType x);//头插
void SListPopFront(SLTNode** pphead);//头删
void SListPophBack(SLTNode** pphead);//尾删
SLTNode* SListFind(SLTNode* phead, SLDataType x);//查找
void SListInsertAfter(SLTNode* pos, SLDataType x);//在pos后位置插入
void SListInsert(SLTNode** pphead,SLTNode* pos,SLDataType x);//在pos前插入
void SListEraseAfter(SLTNode* pos);//把pos后删除
void SListErase(SLTNode** pphead, SLTNode* pos);//把pos前删除
void SListDestory(SLTNode** pphead);//销毁表
main.c
#include"singlist.h"
void TestList1()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);//尾插
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPrint(plist);
//SListPophBack(&plist);
//SListPophBack(&plist);
//SListPophBack(&plist);
//SListPophBack(&plist);
//SListPrint(plist);
//SListPushFront(&plist, 1);//头插
//SListPushFront(&plist, 2);
//SListPushFront(&plist, 3);
//SListPrint(plist);
SListPopFront(&plist);
SListPopFront(&plist);
SListPopFront(&plist);
SListPrint(plist);
}
void TestList2()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);//尾插
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPrint(plist);
//找到有几个x
SLTNode* pos = SListFind(plist,2);
int i = 1;
while (pos)
{
printf("第%d个节点:%p->%d\n",i++,pos,pos->data);
pos = SListFind(pos->next,2);
}
//找到了也可以修改其值,这就是为什么要传址
pos = SListFind(plist,3);
if (pos)
{
pos->data = 30;
}
SListPrint(plist);
}
void TestList3()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);//尾插
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPrint(plist);
//找到了,在3的位置前插入30
SLTNode* pos = SListFind(plist,3);
if (pos)
{
SListInsert(&plist,pos,30);
}
SListPrint(plist);
pos = SListFind(plist, 1);//在头节点插入
if (pos)
{
SListInsert(&plist, pos, 40);
}
SListPrint(plist);
}
void TestList4()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);//尾插
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPrint(plist);
//找到了,在3的位置前插入30
SLTNode* pos = SListFind(plist, 2);
if (pos)
{
SListErase(&plist, pos);
}
SListPrint(plist);
}
int main()//单链表
{
//TestList1();
//TestList2();
//TestList3();
TestList4();
return 0;
}