【单链表】无头单项不循环(2)

简介: 【单链表】无头单项不循环(2)

今天链表。

Test.c主函数

#include"SList.h"
int main()
{
  SLNode* phead = NULL;//结构体指针变量存放结构体的地址 头节点
  test5(&phead);//测试查找
  test6(&phead);//测试在pos前面插入
  test7(&phead);//测试在pos后面插入
  test8(&phead);//测试删除pos后面的元素
  test9(&phead);//测试删除pos的元素
  return 0;
}

test5

void test5(SLNode** pphead)//测试查找
{
  SLNode*ret=SLFind(*pphead, 77);
  if (ret != NULL)
  {
    printf("找到了:%d\n", ret->val);
  }
  else
  {
    printf("没找到\n");
  }
}

test6

void test6(SLNode** pphead)//测试在pos前面位置插入的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLInsert(pphead, ret, 34);
  SLNode* pos = SLFind(*pphead, 34);
  SLInsert(pphead, pos,  78);
  SLPrint(*pphead);
}

test7

void test7(SLNode** pphead)//测试在pos后面位置插入的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLInsertAfter(pphead, ret, 99);
  SLPrint(*pphead);
}

test8

void test8(SLNode** pphead)//测试删除pos后面的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLEraseAfter(pphead, ret);//99
  SLPrint(*pphead);
}

test9

void test9(SLNode** pphead)//测试删除pos的元素
{
  SLNode* ret = SLFind(*pphead, 78);
  SLErase(pphead, ret);
  SLPrint(*pphead);
}

Test.c总代码

#include"SList.h"
void test1(SLNode** pphead)//测试尾插
{
  SLPushBack(pphead, 10);
  SLPushBack(pphead, 20);
  SLPushBack(pphead, 30);
  SLPushBack(pphead, 40);
  SLPrint(*pphead);
}
void test2(SLNode** pphead)//测试头插
{
  SLPushFront(pphead, 77);
  SLPushFront(pphead, 66);
  SLPushFront(pphead, 55);
  SLPushFront(pphead, 33);
  SLPrint(*pphead);
}
//
void test3(SLNode** pphead)//测试头删
{
  SLPopFront(pphead);
  SLPopFront(pphead);
  SLPopFront(pphead);
  SLPrint(*pphead);
}
void test4(SLNode** pphead)//测试尾删
{
  SLPopBack(pphead);
  SLPopBack(pphead);
  SLPrint(*pphead);
}
void test5(SLNode** pphead)//测试查找
{
  SLNode*ret=SLFind(*pphead, 77);
  if (ret != NULL)
  {
    printf("找到了:%d\n", ret->val);
  }
  else
  {
    printf("没找到\n");
  }
}
void test6(SLNode** pphead)//测试在pos前面位置插入的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLInsert(pphead, ret, 34);
  SLNode* pos = SLFind(*pphead, 34);
  SLInsert(pphead, pos,  78);
  SLPrint(*pphead);
}
void test7(SLNode** pphead)//测试在pos后面位置插入的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLInsertAfter(pphead, ret, 99);
  SLPrint(*pphead);
}
void test8(SLNode** pphead)//测试删除pos后面的元素
{
  SLNode* ret = SLFind(*pphead, 77);
  SLEraseAfter(pphead, ret);//99
  SLPrint(*pphead);
}
void test9(SLNode** pphead)//测试删除pos的元素
{
  SLNode* ret = SLFind(*pphead, 78);
  SLErase(pphead, ret);
  SLPrint(*pphead);
}
int main()
{
  SLNode* phead = NULL;//结构体指针变量存放结构体的地址 头节点
  test1(&phead);//测试尾插
  test2(&phead);//测试头插
  test3(&phead);//测试尾删
    test4(&phead);//测试头删
  test5(&phead);//测试查找
  test6(&phead);//测试在pos前面插入
  test7(&phead);//测试在pos后面插入
  test8(&phead);//测试删除pos后面的元素
  test9(&phead);//测试删除pos的元素
  return 0;
}

SList.h头文件&函数声明

头文件

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

函数声明

  • 单链表元素查询
//找到某个数值在单链表
SLNode* SLFind(SLNode* phead, SLNDataType x);
  • 在pos前面位置插入元素
//在pos的前面插入
void SLInsert(SLNode** pphead, SLNode*pos,SLNDataType x);
  • 在pos后面插入元素
//在pos的后面插入
void SLInsertAfter(SLNode** pphead, SLNode* pos, SLNDataType x);
  • 删除pos后面的位置的元素
//删除pos的后面位置
void SLEraseAfter(SLNode** pphead, SLNode* pos);
  • 删除pos位置的元素
//删除pos位置
void SLErase(SLNode** pphead, SLNode* pos);
  • 空间释放
//空间释放
void SLDestroy(SLNode** pphead);

SList.h总代码

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//创建单链表
typedef int SLNDataType;//单链表节点数据类型
typedef struct SListNode//创建节点
{
  SLNDataType val;
  struct SListNode* next;
}SLNode;
//打印数据
void SLPrint(SLNode* phead);
//尾插
void SLPushBack(SLNode** pphead, SLNDataType x);
//头插
void SLPushFront(SLNode** pphead, SLNDataType x);
//头删
void SLPopFront(SLNode** pphead);
//尾删
void SLPopBack(SLNode** pphead);
//找到某个数值在单链表
SLNode* SLFind(SLNode* phead, SLNDataType x);
//在pos的前面插入
void SLInsert(SLNode** pphead, SLNode*pos,SLNDataType x);
//在pos的后面插入
void SLInsertAfter(SLNode** pphead, SLNode* pos, SLNDataType x);
//删除pos的后面位置
void SLEraseAfter(SLNode** pphead, SLNode* pos);
//删除pos位置
void SLErase(SLNode** pphead, SLNode* pos);
//空间释放
void SLDestroy(SLNode** pphead);

SList.c函数实现

查询SLFind

//在单链表中查找某个数字
//找到了返回这个链表的地址
//没找到返回NULL
SLNode* SLFind(SLNode* phead, SLNDataType x)
{
  SLNode* cur = phead;
  while(cur)
  {
    if (cur->val == x)
    {
      return cur;
    }
    cur = cur->next;
  }
  return NULL;
}

pos前面插入  

//在pos的前面插入
void SLInsert(SLNode** pphead, SLNode*pos,SLNDataType x)
{
  //严格限定单链表里面必须有一个有效节点
  assert(pphead);//应该没有人喝醉酒了吧
  assert(*pphead);
  assert(pos);
  SLNode* newnode = CreateNode(x);
  SLNode* cur = *pphead;
  SLNode* prve = NULL;
  //适合中间和尾
  if (prve)
  {
    while (cur != pos)
    {
      prve = cur;
      cur = cur->next;
    }
    prve->next = newnode;
    newnode->next = cur;
  }
  else
  {
    //头插
    SLPushFront(pphead, x);
  }
}

pos后面插入

//在pos的后面插入
void SLInsertAfter(SLNode** pphead, SLNode* pos, SLNDataType x)
{
  //严格限定单链表里面必须有一个有效节点
  assert(pphead);//应该没有人喝醉酒了吧
  assert(*pphead);
  assert(pos);
  SLNode* newnode = CreateNode(x);
  newnode->next = pos->next;
  pos->next = newnode;
  //头和尾都不用处理。
}

pos后面删除

//删除pos的后面位置
void SLEraseAfter(SLNode** pphead, SLNode* pos)
{
  //pos在最后一个不可
  assert(pos->next);
  assert(pos);
  SLNode* tmp = pos->next;
  pos->next = pos->next->next;
  free(tmp);
  tmp = NULL;
}

pos删除

//删除pos位置
void SLErase(SLNode** pphead, SLNode* pos)
{
  assert(pos);
  SLNode* cur = *pphead;
  SLNode* prve = NULL;
  if (prve)
  {
    while (cur != pos)
    {
      prve = cur;
      cur = cur->next;
    }
    prve->next = cur->next;
    free(pos);
    pos = NULL;
  }
  else
  {
    *pphead = pos->next;
    free(pos);
    pos = NULL;
  }
}

空间释放

//空间释放
void SLDestroy(SLNode** pphead)
{
  assert(*pphead);
  SLNode* cur = *pphead;
  while (cur)
  {
    SLNode* tmp = cur->next;
    free(cur);
    cur = tmp;//cur=cur->next
  }
}

SList.c总代码

#include"SList.h"
void SLPrint(SLNode* phead)
{
  assert(phead);
  SLNode* tail = phead;
  printf("phead->");
  while (tail->next != NULL)
  {
    printf("%d->", tail->val);
    tail = tail->next;
  }
  printf("NULL");
  printf("\n");
}
//创建链表的节点---结构体
SLNode* CreateNode(SLNDataType x)
{
  SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
  if (newnode == NULL)
  {
    perror("malloc");
    return;
  }
  newnode->val = x;
  newnode->next = NULL;
  return newnode;
}
//测试尾插
void SLPushBack(SLNode** pphead, SLNDataType x)
{
  //assert(*pphead);
  SLNode* newnode = CreateNode(x);
  //无节点
  if (*pphead == NULL)
  {
    *pphead = newnode;
  }
  //多个节点
  else
  {
    SLNode* tail = *pphead;
    while (tail->next != NULL)
    {
      tail = tail->next;
    }
    tail->next = newnode;
  }
}
//头插
void SLPushFront(SLNode** pphead, SLNDataType x)
{
  //assert(*pphead);
  SLNode* newnode = CreateNode(x);
    newnode->next = *pphead;
    *pphead = newnode;
}
//---删除就涉及空间的释放---断言(删过头)
//头删
void SLPopFront(SLNode** pphead)
{
  assert(*pphead);
  SLNode* tail = *pphead;
  *pphead = (*pphead)->next;
  free(tail);
  tail = NULL;
}
//尾删
void SLPopBack(SLNode** pphead)
{
  assert(*pphead);
  //一个节点
  if ((*pphead)->next == NULL)
  {
    free(*pphead);
    *pphead = NULL;
  }
  else
  {
    SLNode* tail = *pphead;
    SLNode* prve = NULL;//虽然这里prve置为NULL和tail都是一样,但是在OJ题目当中会出错
    while (tail->next != NULL)
    {
      prve = tail;
      tail = tail->next;
    }
    prve->next = NULL;
    free(tail);
    tail = NULL;
  }
}
//在单链表中查找某个数字
//找到了返回这个链表的地址
//没找到返回NULL
SLNode* SLFind(SLNode* phead, SLNDataType x)
{
  SLNode* cur = phead;
  while(cur)
  {
    if (cur->val == x)
    {
      return cur;
    }
    cur = cur->next;
  }
  return NULL;
}
//在pos的前面插入
void SLInsert(SLNode** pphead, SLNode*pos,SLNDataType x)
{
  //严格限定单链表里面必须有一个有效节点
  assert(pphead);//应该没有人喝醉酒了吧
  assert(*pphead);
  assert(pos);
  SLNode* newnode = CreateNode(x);
  SLNode* cur = *pphead;
  SLNode* prve = NULL;
  //适合中间和尾
  if (prve)
  {
    while (cur != pos)
    {
      prve = cur;
      cur = cur->next;
    }
    prve->next = newnode;
    newnode->next = cur;
  }
  else
  {
    //头插
    SLPushFront(pphead, x);
  }
}
//在pos的后面插入
void SLInsertAfter(SLNode** pphead, SLNode* pos, SLNDataType x)
{
  //严格限定单链表里面必须有一个有效节点
  assert(pphead);//应该没有人喝醉酒了吧
  assert(*pphead);
  assert(pos);
  SLNode* newnode = CreateNode(x);
  newnode->next = pos->next;
  pos->next = newnode;
  //头和尾都不用处理。
}
//删除pos的后面位置
void SLEraseAfter(SLNode** pphead, SLNode* pos)
{
  //pos在最后一个不可
  assert(pos->next);
  assert(pos);
  SLNode* tmp = pos->next;
  pos->next = pos->next->next;
  free(tmp);
  tmp = NULL;
}
//删除pos位置
void SLErase(SLNode** pphead, SLNode* pos)
{
  assert(pos);
  SLNode* cur = *pphead;
  SLNode* prve = NULL;
  if (prve)
  {
    while (cur != pos)
    {
      prve = cur;
      cur = cur->next;
    }
    prve->next = cur->next;
    free(pos);
    pos = NULL;
  }
  else
  {
    *pphead = pos->next;
    free(pos);
    pos = NULL;
  }
}
//空间释放
void SLDestroy(SLNode** pphead)
{
  assert(*pphead);
  SLNode* cur = *pphead;
  while (cur)
  {
    SLNode* tmp = cur->next;
    free(cur);
    cur = tmp;//cur=cur->next
  }
}

最近改bug改的想砸电脑,保持冷静。下篇博客我们将继续链表其他类型。好好学习,天天向上。

代码---------→【唐棣棣 (TSQXG) - Gitee.com

联系---------→【邮箱:2784139418@qq.com】

目录
相关文章
不带头非循环的单向链表的增删查改的实现(代码版)
不带头非循环的单向链表的增删查改的实现(代码版)
|
6月前
【无头双向链表和链表练习题2】
【无头双向链表和链表练习题2】
34 0
【单链表】无头单项不循环(1)
【单链表】无头单项不循环(1)
608 2
|
存储 C语言
单链表(无头单项非循环)
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表的形式有很多,本篇文章主要介绍的是单链表且无头结点。在严版数据结构(C语言 第2版)中,单链表采用的是有头节点,这两种形式,各有利弊。含头节点的单链表在学习时,可能会容易些,但是在实践中或者在力扣中做题时,很少会有带头节点。但是有时候做题,使用带头节点的单链表会简单许多,不常见。
72 0
单链表(无头单项非循环)
LeetCode刷题Day04——链表(设计单/双链表、移除、翻转、交换链表节点)
迭代法:首先创建一个临时的节点p用于遍历链表,其开始可以指向头节点,也可以让其next节点指向头节点(如果p指向头节点则while循环的判断条件是p!=null,反之则是p.next!=null),随后p不断地向后移动,在这个过程中进行要求的操作。如果结果要返回头指针,可以实现创建一个节点让其next指向头指针。 如果是要删除元素,那么需要拥有前一个节点的指针,让其指向要删除的元素的下一个元素,所以此时则不能让p指向头节点,而应该是让next去指向,即判断的是下一个元素的值,这样才能够实现删除。 如果是要翻转链表,那么需要不断改变指针的方向,即让next等于之前的元素,所以需要一个变量prev
|
11月前
|
存储 算法
数据结构单链表之检测和删除链表中的循环 | 第十三套
数据结构单链表之检测和删除链表中的循环 | 第十三套
50 0
|
存储 C++
【双向链表】带头双向循环(1)
【双向链表】带头双向循环(1)
63 0
拿捏链表(一)-----------移除链表元素
拿捏链表(一)-----------移除链表元素
45 0
无头单向不循环链表和带头双向循环链表的创建
接下来我们将会了解最基础的链表--->单链表 以及最方便也是最爽的链表--->带头双向循环链表。
41 0