main.c
#include <stdio.h>
#include "SList.h"
#include <stdlib.h>
void TestSList()
{
SListNode* pList = NULL;
SListPushBack(&pList, 1);//plist传的是值不是地址 进入phead后phead改变不会影响plist 所以采用二级指针的解引用
//解引用二级指针拿到的是一级指针的值,改变一级指针得传二级指针的地址,所以都得取地址
SListPushBack(&pList, 2);
SListPushBack(&pList, 3);
SListPushBack(&pList, 4);
SListPrint(pList);
SListPopBack(&pList);
SListPopBack(&pList);
SListPopBack(&pList);
SListPopBack(&pList);
SListPopBack(&pList);
SListPrint(pList);
SListPushFront(&pList,1);//先插的1 放在null后
SListPushFront(&pList,2);
SListPushFront(&pList,3);
SListPushFront(&pList,4);
SListPushFront(&pList,5);
SListPrint(pList);
SListPopFront(&pList);
SListPopFront(&pList);
SListPopFront(&pList);
SListPopFront(&pList);
SListPopFront(&pList);
SListPopFront(&pList);
SListPrint(pList);
}
void TestSList2()
{
SListNode* pList = NULL;
SListPushBack(&pList, 1);//plist传的是值不是地址 进入phead后phead改变不会影响plist 所以采用二级指针的解引用
//解引用二级指针拿到的是一级指针的值,改变一级指针得传二级指针的地址,所以都得取地址
SListPushBack(&pList, 2);
SListPushBack(&pList, 3);
SListPushBack(&pList, 4);
SListPrint(pList);
SListNode* pos = SListFind(pList, 3);
//找到后修改为30
if(pos)
{
pos->data = 30;
}
SListPrint(pList);
}
int main()
{
TestSList();
TestSList2();
return 0;
}
SList.h
#include <stdio.h>
#include <stdlib.h>
typedef int SListDataType;//结点
typedef struct SListNode
{
SListDataType data;
struct SListNode* next;
}SListNode;
void SListPushBack(SListNode** pphead,SListDataType x);
void SListPopBack(SListNode** pphead);
void SListPushFront(SListNode** pphead,SListDataType x);
void SListPopFront(SListNode** pphead);
SListNode* SListFind(SListNode* phead, SListDataType x);
void SListPrint(SListNode* phead);
SList.c
#include "SList.h"
#include <stdlib.h>
#include <stdlib.h>
//创建一个结点后返回
SListNode* BuySListNode(SListDataType x)
{
SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));
if(newNode == NULL)
{
printf("申请结点失败");
exit(-1);
}
newNode->data = x;
newNode->next = NULL;
//存新结点的地址 地址在newnode里
return newNode;
}
//尾插
void SListPushBack(SListNode** pphead,SListDataType x)
{
SListNode* newNode = BuySListNode(x);
if(*pphead == NULL)
{
*pphead = newNode;
}
//找到尾
else
{
SListNode* tail = *pphead;//指向第一个结点 可能为空结点
while(tail->next != NULL)
{
tail = tail->next;
}
tail->next = newNode;
}
}//funtion define is not allowed here 解决办法在后边加上}
//尾删
void SListPopBack(SListNode** pphead)
{
//空 一个结点 一个以上结点
if(*pphead == NULL)
{
return;
}
else if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
//定一个新的指针变量(局部变量)
SListNode* prev = NULL;
SListNode* tail = *pphead;
//prev在tail的前一个
while (tail->next != NULL) {
prev = tail;
tail = tail->next;
}
free(tail);
prev->next=NULL;
}
}
//头插
void SListPushFront(SListNode** pphead,SListDataType x)
{
SListNode* newnode = BuySListNode(x);//创建一个新结点
newnode->next = *pphead;//原来的第一个结点的地址在plist内,*pphead就是plist的值
*pphead = newnode;//新的结点变成第一个结点
}
//头删
void SListPopFront(SListNode** pphead)
{
//内存泄露:指针丢了
//空 一个结点和一个以上的结点
//*pphead就是plist
if(*pphead == NULL)
{
return;
}
else
{
//用next来保存要删除结点的后一个结点的地址(删除第一个结点会丢掉后一个结点的地址)
SListNode* next = (*pphead)->next;//存的为plist->next
free(*pphead);//释放当前结点
*pphead = next;//再指向下一结点 plist = next
}
}
//只是打印所以传一级指针
void SListPrint(SListNode* phead)
{
SListNode* cur = phead;
//遍历一个链表
while(cur != NULL)
{
printf("%d",cur->data);
//cur为结构体 用->访问
cur = cur->next;//不能是cur++,因为跳过的为一个指针的大小,不是下一个结点的地址
}
printf("NULL\n");
}
//顺序表是数组 插入给的是下标 链表给的是结点的地址 所以单链表不方便在当前位置插入
//pos->next = newnode会使pos丢失掉后一个指针 所以必须先用一个新的指针保存pos后一个结点的地址
//newnode->next = pos->next 导致自己给自己赋值
//也可以不保存将这两句上下颠倒newnode->next = pos->next pos->next = newnode
//查 到同时可以改
//使用的是一级指针 要改变指针才使用二级指针
SListNode* SListFind(SListNode* phead, SListDataType x)
{
SListNode* cur = phead;
while(cur)
{
if(cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//中间位置插入
void SListInsertAfter(SListNode* pos, SListDataType x)
{
//assert(pos);//断言
SListNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
//中间位置删除
void SListEraseAfter(SListNode* pos)
{
//assert(pos);//断言
if(pos->next)
{
SListNode* next = pos->next;
SListNode* nextnext = next->next;
pos->next = nextnext;
free(next);
}
}