单向无头链表的实现

#pragma once
#include <stdio.h>
#include <stdlib.h>
typedef int SLDatatype;// 结构体内的数据类型可能发生改变,所以类型重定义方便改
typedef struct SListNode{
     SLDatatype data;
     struct SListNode* next;//链表的指针是指向结构体的的指针,所以是结构体类型
}SListNode;
void SListNodePrint(SListNode* pList);
void SListPushBack(SListNode** ppList,SLDatatype x);
void SListPushFront(SListNode** ppList, SLDatatype x);
void SListPopBack(SListNode** ppList);
SListNode* SListFind(SListNode* pList, SListData x);//查找不需要修改,所以传一级指针

查找函数也是修改函数:
SListNode* ret = SListFind()//用ret指针接收找到的位置
然后ret->data = 20;//就把查到到的位置的值修改成20

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
int main()
{
     SListNode* pList = NULL;//设置了一个链表类型的指针
     SListPushBack(&pList, 1);//这里要注意!!这里创建了一个pList的指针,要在这个指针后面进行栈创建的动作,但在传参的时候相当于重新                                   在堆栈上开辟了指针空间,
                                  //这个指针是pList的拷贝,所以在哪个上面的所有操作并不会改变真正的pList指针,所以要传指针的地址
                                  //也就是2及指针.
     SListPushBack(&pList, 2);
     SListPushBack(&pList, 3);
     SListPushFront(&pList, 0);
     SListNodePrint(pList);
     SListPopBack(&pList);
     SListPopBack(&pList);
     SListPopBack(&pList);
     SListPopBack(&pList);
     SListNodePrint(pList);
     system("pause");
     return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
void SListNodePrint(SListNode* pList)
{
     SListNode* cur = pList;//初始指针不能动,最后要用这个指针打印
     while (cur != NULL)
     {
          printf("%d->", cur->data);
          cur = cur->next;
     }
     printf("NULL\n");
}
//申请节点函数
SListNode* BuySListNode(SLDatatype x)
{
     SListNode* newNode =  (SListNode*)malloc(sizeof(SListNode));
     newNode->data = x;
     newNode->next = NULL;//把新节点后面置成空
     return newNode;//返回节点,所以上面是链表类型
}
void SListPushBack(SListNode** ppList, SLDatatype x)
{
     //申请节点并存入值
     SListNode* newNode = BuySListNode(x);
     //如果空把新节点赋到后面就是
     if (*ppList == NULL)
     {
          *ppList = newNode;
     }
     //如果不空就按步骤把新节点插到最后一个
     else
     {
          SListNode* tail = *ppList;//设置新指针用于走到链表的尾*
          while (tail->next != NULL)
          {
              tail = tail->next;
          }
          tail->next = newNode;//走到最后赋新节点
     }
}

void SListPushFront(SListNode** ppList, SLDatatype x)
{
     SListNode* newNode = BuySListNode(x);
     newNode->next = *ppList;//这个没有头节点所以不能ppList->next那样赋值,因为ppList存的就是这个链表的开头
     *ppList = newNode;//把newNode设置成起始节点
}

void SListPopBack(SListNode** ppList)//尾删
{
     //链表的删除必须要知道它的前节点:所以需要一对快慢指针,让慢指针永远跟着快指针走.如果快fast->next == NULL,
     //这时说明找到了尾,free(fast).因为释放了但是slow指针还是指向最后一个,不置成空就会成为野指针,所以需要前一个节点.
     //这时出现3种情况
     //为空
     if ((*ppList) == NULL)//"*"和->都是结合符号,所以要先给括号.传的ppList是二级指针,所以*ppList是指针本身
     {
          return;
     }
     //只有一个节点
     else if ((*ppList)->next == NULL)
     {
          free(*ppList);//直接free
          *ppList = NULL;
     }
     //正常
     else
     {
          SListNode* pre = NULL;
          SListNode* tail = *ppList;
          while (tail->next != NULL)
          {
              pre = tail;//快指针后移时候要提前把地址附个慢指针
              tail = tail->next;
          }
          free(tail);
          pre->next = NULL;
     }
}

SListNode* SListFind(SListNode* pList, SListData x)//查找
{
     SListNode* cur = pList;
     while (cur)
     {
          if (cur->data == x)
          {
              return cur;
          }
          else
          {
              cur = cur->next;
          }
     }
     return NULL;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值