C单链表代码

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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值