链表练习

用链表实现简单的一串数,并进行操作

进行各种增删改查
逆向打印
不通过遍历来删除一个非尾节点
不通过遍历在一个借点钱插入一个节点
通过单链表实现约瑟夫环
逆置/反转单链表

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//定义一个类
typedef struct SListNode
{
    int data;
    struct SListNode *pNext;
}SList;
//初始化头部
void Init(SList **pphead)
{
    *pphead = NULL;
}
//输出链表
void Print(SList *pHead)
{
    assert(pHead);
    if(pHead == NULL)
    {
        printf("链表为空\n");
        return;
    }
    while(pHead != NULL)
    {
        printf("%d -> ",pHead->data);
        pHead = pHead->pNext;
    }
    printf("NULL\n");
}
//尾插
void SListPushBack(SList **ppHead, int data)
{
    SList *pNode; 
    SList *pNew = (SList *)malloc(sizeof(SList));
    if(*ppHead == NULL)
    {
        *ppHead = pNew;
        pNew->data = data;
        pNew->pNext = NULL;
        return;
    }
    pNode = *ppHead;
    while(pNode->pNext != NULL)
    {
        pNode = pNode->pNext;
    }
    pNode->pNext = pNew;
    pNew->data = data;
    pNew->pNext = NULL;
}
//头部插入
void SListPushFront(SList **ppHead, int data)
{
    SList *pNew = (SList *)malloc(sizeof(SList));
    if(*ppHead == NULL)
    {
        *ppHead = pNew;
        pNew->data = data;
        pNew->pNext = NULL;
        return;
    }
    pNew->pNext = *ppHead;
    pNew->data = data;
    *ppHead = pNew;
}
//尾删
void SListPopBack(SList **ppHead)
{
    SList *pHead = *ppHead;
    SList *pNode;
    if(*ppHead == NULL)
    {
        printf("链表为空\n");
        return;
    }
    if(pHead->pNext == NULL)
    {
        free(pHead);
        *ppHead = NULL;
        return;
    }
    while(pHead->pNext != NULL)
    {
        pNode = pHead;
        pHead = pHead->pNext;
    }
    free(pHead);
    pNode->pNext = NULL;
}
//头删
void SListPopFront(SList **ppHead)
{
    SList *pHead = *ppHead;
    if(pHead->pNext == NULL)
    {
        free(pHead);
        *ppHead = NULL;
        return;
    }
    *ppHead = pHead->pNext;
    free(pHead);
}
//随机插
void SListInsert(SList **ppHead, int x, int data)
{
    SList *pHead;
    SList *pNew = (SList *)malloc(sizeof(SList));
    pHead = *ppHead;
    if(pHead->data == x)
    {
        pNew->pNext = pHead;
        pNew->data = data;
        *ppHead = pNew;
        return;
    }
    while(pHead->pNext->data != x)
    {
        pHead = pHead->pNext;
    }
    pNew->pNext = pHead->pNext;
    pHead->pNext = pNew;
    pNew->data = data;
}
//按值删除所有
void SListRemoveAll(SList **ppHead, int data)
{
    SList *pNode = *ppHead;
    SList *pNode1;
    while(pNode->pNext != NULL)
    {
        if(pNode->pNext->data == data)
        {
            pNode1 = pNode->pNext;
            pNode->pNext = pNode1->pNext;
            free(pNode1);
        }else
        {
            pNode = pNode->pNext;
        }
    }
    if((*ppHead)->data == data)
    {
        SListPopFront(ppHead);
    }
}
//查找
SList *SListFind(SList *pHead, int data)
{
    SList *pNode = pHead;
    while(pNode != NULL)
    {
        if(pNode->data == data)
        {
            return pNode;
        }
        pNode = pNode->pNext;
    }
    return NULL;
}
//销毁
void SListDestroy(SList **ppHead)
{
    SList *pNode;
    assert(ppHead);
    while(*ppHead != NULL)
    {
        pNode = *ppHead;
        *ppHead = (*ppHead)->pNext;
        free(pNode);
    }
}
  • 不通过遍历来删除一个非尾节点
//删除一个无头单链表的非尾节点(不能遍历链表)
void DelSList(SList **ppHead,int data)
{
    SList *pHead = *ppHead;
    assert(ppHead);
    while(pHead->data != data)
    {
        pHead = pHead->pNext;
    }
    while(pHead->pNext->pNext != NULL)
    {
        pHead->data = pHead->pNext->data;
        pHead = pHead->pNext;
    }
    pHead->data = pHead->pNext->data;
    free(pHead->pNext);
    pHead->pNext = NULL;
}
  • 反转链表
//反转链表
void SListRever(SList **ppHead)
{
    SList *p1,*p2,*p3;
    assert(ppHead);
    p1 = NULL;
    p2 = *ppHead;
    p3 = p2->pNext;
    while(p2 != NULL)
    {
        p2->pNext = p1;
        p1 = p2;
        p2 = p3;
        if(p3 != NULL)
        {
            p3 = p3->pNext;
        }
    }
    *ppHead = p1;
}
  • 不通过遍历在一个借点钱插入一个节点
//在无头单链表的一个节点前插入一个节点(不能遍历链表)
void InsertNoFirstNode(SList **ppPos, int data)
{
    SList *pPos = *ppPos;
    SList *pNode;
    assert(ppPos);
    if(*ppPos == NULL)
    {
        SListPushBack(ppPos, data);
        return;
    }
    pNode = (SList *)malloc(sizeof(SList));
    pNode->data = data;
    pNode->pNext = NULL;

    pNode->pNext = pPos->pNext;
    pPos->pNext = pNode;
    pNode->data = pPos->data;
    pPos->data = data;
}
  • 单链表实现约瑟夫环
//单链表实现约瑟夫环
void SListJosephCircle(SList **ppHead, int n)
{
    SList *pHead = *ppHead;
    SList *pNode;
    int i;
    while(pHead->pNext != NULL)
    {
        pHead = pHead->pNext;
    }
    pHead->pNext = *ppHead;
    pHead = *ppHead;
    while(pHead->pNext != pHead)
    {
        i = n;
        while((--i)>0)
        {
            pNode = pHead;
            pHead = pHead->pNext;
        }

        pNode->pNext = pHead->pNext;
        free(pHead);

        pHead = pNode->pNext;
    }
    pHead->pNext = NULL;
    *ppHead = pHead;
}
  • 逆向打印
//逆向打印链表
void PrintFail(SList *pHead)
{
    if(pHead == NULL)
    {
        return;
    }
    else
    {
        PrintFail(pHead->pNext);
        printf("->%d",pHead->data);

    }
}
  • 主函数部分
int main()
{
    SList *pHead;
    SList *pNode;
    //初始化头部
    Init(&pHead);
    //尾部插入
    SListPushBack(&pHead, 1);
    SListPushBack(&pHead, 2);
    SListPushBack(&pHead, 3);
    //头部插入
    SListPushFront(&pHead, 5);
    SListPushFront(&pHead, 6);
    SListPushFront(&pHead, 8);
    //尾删
    SListPopBack(&pHead);
    //头删
    SListPopFront(&pHead);
    //插入
    SListInsert(&pHead, 5, 4);
    SListInsert(&pHead, 6, 2);
    SListInsert(&pHead, 2, 8);


    //按值删除所有
    //SListRemoveAll(&pHead, 2);
    //SListRemoveAll(&pHead, 8);
    //查找
    pNode = SListFind(pHead, 6);
    //printf("%d\n",pNode->data);


    //销毁
    //SListDestroy(&pHead);

    //删除一个无头单链表的非尾节点(不能遍历链表)
    DelSList(&pHead,1);

    //在无头单链表的一个节点前插入一个节点(不能遍历链表)
    InsertNoFirstNode(&pNode, 9);

    //翻转链表
    //SListRever(&pHead);

    //单链表实现约瑟夫环
    ////SListJosephCircle(&pHead,3);

    //输出
    Print(pHead);

    //逆向打印
    PrintFail(pHead);
    return 0;
}

进行链表相关操作,假如感觉很难的话,建议还是多画图,把每个节点的信息都划出来,这样就会很容易理解。
这里写图片描述
遇到不会的一通乱画,就会其八九了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值