创建malloc指针的节点
SLTNode* BuySLTNode(SLTDataType x);
SLTNode* BuySLTNode(SLTDataType x)//创建malloc指针的节点
{
SLTNode* newnode = (SLTNode * )malloc(sizeof(SLTNode));
if ((newnode == NULL))
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
打印链表
void SListPrint(SLTNode* phead);
void SListPrint(SLTNode* phead)
{
SLTNode* cur = phead;//phead赋值给结构体cur的指针,指向第一个节点
while(cur!=NULL)//cur不等于空就继续
{
printf("%d->",cur->data);
cur = cur->next;//cur移动到下一个节点
}
printf("NULL\n");//打印空
}
链表的销毁
void SListDestory(SLTNode** pphead);
void SListDestory(SLTNode** pphead)//链表是需要销毁的
{
assert(pphead);
SLTNode* cur = *pphead;
while (cur)//指针直接去做逻辑判断
{
SLTNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
头插
void SListPushFront(SLTNode** pphead, SLTDataType x);
void SListPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuySLTNode(x);
newnode->next = *pphead;
*pphead = newnode;//指向同一个位置
}
尾插
void SListPushBack(SLTNode** pphead, SLTDataType x);
void SListPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuySLTNode(x);
//1.空
//2.非空
if (*pphead == NULL)
{
*pphead = newnode;//存的是plist的地址
}
//链表不为空,尾插,要改变的是结构体SListNode的成员
//tail就是结构体的指针
else
{
SLTNode* tail = *pphead;
while (tail->next!=NULL)
{
tail = tail->next;
}
tail->next= newnode;
}
}
尾删
void SListPushBack(SLTNode** pphead, SLTDataType x);
void SListPopBack(SLTNode** pphead)
{
assert(pphead);
//1.一个节点
//.多个节点
// 温柔的检查
if(*pphead==NULL)
{
return;
}
//暴力检查
//assert(*pphead != NULL);
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//方法一
//assert(pphead);
//SLTNode* prev = NULL;
//SLTNode* tail = *pphead;
//while (tail->next!= NULL)
//{
// prev = tail;
// tail = tail->next;
//}
//prev->next = NULL;
//free(tail);
//tail = NULL;
//方法二
else
{
SLTNode* tail = *pphead;
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
头删
void SListPopFront(SLTNode** pphead);
void SListPopFront(SLTNode** pphead)
{
assert(pphead);//一级指针有时候检查有时候不检查,看场景,二级都要检查
//温柔的检查
if (*pphead == NULL)
{
return ;
}
//暴力检查
//assert(*pphead!= NULL);
SLTNode* del = *pphead;
//同一priority(优先级)加个括号告诉编译器
*pphead =(*pphead)->next;
free(del);
del = NULL;
}
SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
这是我SList.h里的代码:
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLTDataType;//定义节点
typedef struct SLisNode
{
SLTDataType data;
struct SLisNode* next;//结构体指针指向下一个结构的指针
} SLTNode;
SLTNode* BuySLTNode(SLTDataType x);//创建malloc指针的节点
void SListPrint(SLTNode* phead);//打印链表
void SListDestory(SLTNode** pphead);//链表是需要销毁的
void SListPushFront(SLTNode** pphead, SLTDataType x);//头插
void SListPushBack(SLTNode** pphead, SLTDataType x);//尾插
void SListPushBack(SLTNode** pphead, SLTDataType x);//尾删
void SListPopFront(SLTNode** pphead);//头删
SLTNode* SListFind(SLTNode* phead,SLTDataType x);//查找链表
//单链表在pos之前插入
void SListInsert(SLTNode** pphead, SLTNode*pos, SLTDataType x);
//单链表在pos后面插入
void SListInsertAfter(SLTNode* pos,SLTDataType x);
//删除pos位置
//void SListErase(SLTNode** pphead,SLTNode* pos);
//删除pos后面位置
//void SListEraseAfter( SLTNode* pos);
这是我SList.c里的代码:
#include"SList.h"
void SListPrint(SLTNode* phead)
{
SLTNode* cur = phead;//phead赋值给结构体cur的指针,指向第一个节点
while(cur!=NULL)//cur不等于空就继续
{
printf("%d->",cur->data);
cur = cur->next;//cur移动到下一个节点
}
printf("NULL\n");//打印空
}
SLTNode* BuySLTNode(SLTDataType x)//创建malloc指针的节点
{
SLTNode* newnode = (SLTNode * )malloc(sizeof(SLTNode));
if ((newnode == NULL))
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void SListDestory(SLTNode** pphead)//链表是需要销毁的
{
assert(pphead);
SLTNode* cur = *pphead;
while (cur)//指针直接去做逻辑判断
{
SLTNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
void SListPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuySLTNode(x);
newnode->next = *pphead;
*pphead = newnode;//指向同一个位置
}
void SListPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuySLTNode(x);
//1.空
//2.非空
if (*pphead == NULL)
{
*pphead = newnode;//存的是plist的地址
}
//链表不为空,尾插,要改变的是结构体SListNode的成员
//tail就是结构体的指针
else
{
SLTNode* tail = *pphead;
while (tail->next!=NULL)
{
tail = tail->next;
}
tail->next= newnode;
}
}
void SListPopBack(SLTNode** pphead)
{
assert(pphead);
//1.一个节点
//.多个节点
// 温柔的检查
if(*pphead==NULL)
{
return;
}
//暴力检查
//assert(*pphead != NULL);
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//方法一
//assert(pphead);
//SLTNode* prev = NULL;
//SLTNode* tail = *pphead;
//while (tail->next!= NULL)
//{
// prev = tail;
// tail = tail->next;
//}
//prev->next = NULL;
//free(tail);
//tail = NULL;
//方法二
else
{
SLTNode* tail = *pphead;
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
void SListPopFront(SLTNode** pphead)
{
assert(pphead);//一级指针有时候检查有时候不检查,看场景,二级都要检查
//温柔的检查
if (*pphead == NULL)
{
return ;
}
//暴力检查
//assert(*pphead!= NULL);
SLTNode* del = *pphead;
//同一priority(优先级)加个括号告诉编译器
*pphead =(*pphead)->next;
free(del);
del = NULL;
}
SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//在pos之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead);
assert(pos);
if (pos == *pphead)
{
SListPushFront(pphead,x);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
assert(prev);//找不到不要尾插
}
SLTNode* newnode = BuySLTNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
//在pos后面插入
void SListInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuySLTNode(x);
//后插注意顺序
newnode->next = pos->next;
pos->next = newnode;
}
这是我Test.c里的代码:
#include"SList.h"
void TestSList1()
{
SLTNode* plist = NULL;
SListPushFront(&plist, 1);
SListPushFront(&plist, 2);
SListPushFront(&plist, 3);
SListPushFront(&plist, 4);
SListPrint(plist);
SListPopFront(&plist);
SListPrint(plist);
SListPopFront(&plist);
SListPrint(plist);
SListPopFront(&plist);
SListPrint(plist);
SListPopFront(&plist);
SListPrint(plist);
}
void TestSList2()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListPopBack(&plist);
SListPrint(plist);
SListPopBack(&plist);
SListPrint(plist);
SListPopBack(&plist);
SListPrint(plist);
SListPopBack(&plist);
SListPrint(plist);
SListPopBack(&plist);
SListPrint(plist);
SListDestory(&plist);
}
void TestSList3()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SLTNode* pos = SListFind(plist, 3);
if (pos)
{
pos->data *= 10;
printf("找到了\n");
}
else
{
printf("没有找到\n");
}
SListPrint(plist);
pos = SListFind(plist,1);
if (pos)
{
SListInsert(&plist, pos, 10);//1的前面插入10
}
SListPrint(plist);
SListDestory(&plist);
}
//改变int*要传二级指针
//void swapi(int* px, int* py)
//{
// int tmp = *px;
// *px = *py;
// *py = tmp;
//}
//void swapptr(int** ppx, int** ppy)
//{
// int* tmp = *ppx;
// *ppx = *ppy;
// *ppy = tmp;
//}
int main()
{
//int x = 0;
//int y = 1;
//swapi(&x, &y);
//int* p1 = &x, * p2 = &y;
//swapptr(&p1, &p2);
//TestSList1();
//TestSList2();
TestSList3();
return 0;
}
我们现在是想在第三个位置插入数字30,在1的前面插入10,检查一下运行结果: