下面是上章的代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType date;
struct SListNode* next;
}SLTNode;
void SLNInit(SLTNode* a)
{
SLTNode* ps = a;
for (ps;ps != NULL;ps=ps->next) {
ps->date = 1;
}
}
void SLPrint(SLTNode* b)
{
SLTNode* phead = b;
while (phead != NULL)
{
printf("%d ", phead->date);
phead = phead->next;
}
printf("\n");
}
//尾插
void SLPushBack(SLTNode** phead, SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
if (*phead == NULL)
*phead = newnode;
else
{
SLTNode* crr = *phead;
while (crr->next != NULL)
{
crr = crr->next;
}
crr->next = newnode;
}
}
//头插
void SLPushFront(SLTNode** pphead, SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
if (*pphead == NULL)
*pphead = newnode;
else
{
newnode->next = *pphead;
*pphead = newnode;
}
}
//头删
void SLPopFront(SLTNode** pphead)
{
//没有结点:
assert(*pphead);
//只有一个结点时
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//多个结点时:
else
{
SLTNode* first = *pphead;
*pphead = first->next;
free(first);
first = NULL;
}
}
//尾删:
void SLPopBack(SLTNode* phead)
{
//没有结点时:
assert(phead);
//只有一个结点时:
if (phead->next == NULL)
{
free(phead);
phead = NULL;
}
//有多个结点时:
SLTNode* end = phead;
SLTNode* pre = NULL;
//找到尾结点:
while (end->next != NULL)
{
pre = end;
end = end->next;
}
free(end);
pre->next = NULL;
}
//测试尾插
void TextSListNode()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
}
//测试尾插和头删
void TextSListNode1()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
}
//测试头插和尾删
void TextSListNode2()
{
SListNode* phead = NULL;
SLPushFront(&phead, 5);
SLPushFront(&phead, 4);
SLPushFront(&phead, 3);
SLPushFront(&phead, 2);
SLPushFront(&phead, 1);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
}
int main()
{
return 0;
}
接下来实现链表的查找和在任意位置增加和删除结点:
//查找
SLTNode* SListFind(SLTNode* plist, SLTDateType x)
{
SLTNode* cur = plist;
while (cur)
{
if (cur->date == x)
return cur;
else
cur = cur->next;
}
return NULL;
}
紧接着实现链表的在任意位置增加和删除结点:
首先定义一个动态开辟一个新结点的函数,方便之后代码的实现:
SLTNode* BuySListNode(SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
return newnode;
}
先实现在任意结点前面插入结点:
void SListInsert(SLTNode* phead, SLTNode* pos, SLTDateType x)
{
if (pos == phead)
{
SLPushFront(&phead, x);
}
else
{
SLTNode* prve = phead;
SLTNode* dst = phead;
while (dst)
{
if (dst == pos)
{
SLTNode* newnode = BuySListNode(x);
newnode->next = prve->next;
prve->next = newnode;
break;
}
else
{
prve = dst;
dst = dst->next;
}
}
}
}
在任意结点后面插入结点
void SListInsertAfter(SLTNode* pos, SLTDateType x)
{
SLTNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
void SLTErase(SLTNode* phead, SLTNode* pos)
{
if (pos == phead)
{
SLPopFront(&phead);
}
else
{
SLTNode* prve = phead;
while (prve)
{
if (prve->next == pos)
{
prve->next = pos->next;
free(pos);
break;
}
else
{
prve = prve->next;
}
}
}
}
void SLTEraseAfter( SLTNode* pos)
{
SLTNode* cur = pos->next;
pos->next = pos->next->next;
free(cur);
}
可以看到,在链表结点的后面插入和删除结点是比较容易的。
我们也可以像上章一样对所写代码进行测试,下面是整个的完整代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType date;
struct SListNode* next;
}SLTNode;
void SLNInit(SLTNode* a)
{
SLTNode* ps = a;
for (ps;ps != NULL;ps=ps->next) {
ps->date = 1;
}
}
void SLPrint(SLTNode* b)
{
SLTNode* phead = b;
while (phead != NULL)
{
printf("%d ", phead->date);
phead = phead->next;
}
printf("\n");
}
//尾插
void SLPushBack(SLTNode** phead, SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
if (*phead == NULL)
*phead = newnode;
else
{
SLTNode* crr = *phead;
while (crr->next != NULL)
{
crr = crr->next;
}
crr->next = newnode;
}
}
//头插
void SLPushFront(SLTNode** pphead, SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
if (*pphead == NULL)
*pphead = newnode;
else
{
newnode->next = *pphead;
*pphead = newnode;
}
}
//头删
void SLPopFront(SLTNode** pphead)
{
//没有结点:
assert(*pphead);
//只有一个结点时
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//多个结点时:
else
{
SLTNode* first = *pphead;
*pphead = first->next;
free(first);
first = NULL;
}
}
//尾删:
void SLPopBack(SLTNode* phead)
{
//没有结点时:
assert(phead);
//只有一个结点时:
if (phead->next == NULL)
{
free(phead);
phead = NULL;
}
//有多个结点时:
SLTNode* end = phead;
SLTNode* pre = NULL;
//找到尾结点:
while (end->next != NULL)
{
pre = end;
end = end->next;
}
free(end);
pre->next = NULL;
}
SLTNode* BuySListNode(SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->date = x;
newnode->next = NULL;
return newnode;
}
//查找
SLTNode* SListFind(SLTNode* plist, SLTDateType x)
{
SLTNode* cur = plist;
while (cur)
{
if (cur->date == x)
return cur;
else
cur = cur->next;
}
return NULL;
}
//在任意结点前面插入结点
void SListInsert(SLTNode* phead, SLTNode* pos, SLTDateType x)
{
if (pos == phead)
{
SLPushFront(&phead, x);
}
else
{
SLTNode* prve = phead;
SLTNode* dst = phead;
while (dst)
{
if (dst == pos)
{
SLTNode* newnode = BuySListNode(x);
newnode->next = prve->next;
prve->next = newnode;
break;
}
else
{
prve = dst;
dst = dst->next;
}
}
}
}
//在任意结点后面插入结点
void SListInsertAfter(SLTNode* pos, SLTDateType x)
{
SLTNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
//删除任意结点
void SLTErase(SLTNode* phead, SLTNode* pos)
{
if (pos == phead)
{
SLPopFront(&phead);
}
else
{
SLTNode* prve = phead;
while (prve)
{
if (prve->next == pos)
{
prve->next = pos->next;
free(pos);
break;
}
else
{
prve = prve->next;
}
}
}
}
//删除任意结点的后一个结点
void SLTEraseAfter( SLTNode* pos)
{
SLTNode* cur = pos->next;
pos->next = pos->next->next;
free(cur);
}
//测试尾插
void TextSListNode()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
}
//测试尾插和头删
void TextSListNode1()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
SLPopFront(&phead);
SLPrint(phead);
}
//测试头插和尾删
void TextSListNode2()
{
SListNode* phead = NULL;
SLPushFront(&phead, 5);
SLPushFront(&phead, 4);
SLPushFront(&phead, 3);
SLPushFront(&phead, 2);
SLPushFront(&phead, 1);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
SLPopBack(phead);
SLPrint(phead);
}
//测试查找:
void TextSListNode3()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
//找到值为3的结点并修改值为6
SLTNode* dst = SListFind(phead, 2);
dst->date = 6;
SLPrint(phead);
}
//测试在任意结点前面增加结点
void TextSListNode4()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
//找到值为3的结点并修改值为6
SLTNode* dst = SListFind(phead, 2);
//在值为2的结点前面添加一个值为6的结点:
SListInsert(phead, dst, 6);
SLPrint(phead);
}
//测试删除任意结点:
void TextSListNode5()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
//找到值为3的结点并修改值为6
SLTNode* dst = SListFind(phead, 2);
//在值为2的结点前面添加一个值为6的结点:
SListInsert(phead, dst, 6);
SLPrint(phead);
SLTNode* dst1 = SListFind(phead, 4);
SLTErase(phead, dst1);
SLPrint(phead);
}
//测试在任意结点后面插入结点
void TextSListNode6()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
//找到值为3的结点并修改值为6
SLTNode* dst = SListFind(phead, 2);
//在值为2的结点前面添加一个值为6的结点:
SListInsert(phead, dst, 6);
SLPrint(phead);
SLTNode* dst1 = SListFind(phead, 4);
SLPrint(phead);
SListInsertAfter(dst, 20);
SLPrint(phead);
SListInsertAfter(dst1, 40);
SLPrint(phead);
}
//测试删除任意结点后面的结点
void TextSListNode7()
{
SListNode* phead = NULL;
SLPushBack(&phead, 1);
SLPushBack(&phead, 2);
SLPushBack(&phead, 3);
SLPushBack(&phead, 4);
SLPushBack(&phead, 5);
SLPrint(phead);
//找到值为3的结点并修改值为6
SLTNode* dst = SListFind(phead, 2);
//在值为2的结点前面添加一个值为6的结点:
SListInsert(phead, dst, 6);
SLPrint(phead);
SLTNode* dst1 = SListFind(phead, 4);
SLPrint(phead);
SListInsertAfter(dst, 20);
SLPrint(phead);
SListInsertAfter(dst1, 40);
SLPrint(phead);
SLTEraseAfter(dst);
SLPrint(phead);
SLTEraseAfter(dst1);
SLPrint(phead);
}
int main()
{
TextSListNode7();
return 0;
}
小小三百行不成敬意,有错误的地方还请大佬指正: