无头单链表

简介: 无头单链表

一、单链表结构的定义

//单链表结构的定义
typedef int SLNDataType;//数据类型
typedef struct SListNode {
  SLNDataType val;//结点数据域
  struct SListNode* next;//结点指针域
}SLNode;

二、单链表结点的创建

//单链表结点的创建
SLNode* CreateNode(SLNDataType x)
{
  SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));//为新结点申请空间
  if (newnode == NULL)//申请失败
  {
    perror("malloc fail");
    exit(-1);
  }
  newnode->val = x;//新结点数据域
  newnode->next = NULL;//新结点指针域
  return newnode;
}

三、单链表打印

//单链表的打印
void SLTPrint(SLNode* phead)
{
  SLNode* cur = phead;
  while (cur)
  {
    printf("%d->", cur->val);
    cur = cur->next;
  }
  if (cur == NULL)
    printf("NULL\n");
}

四、单链表尾插

//单链表的尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{
    assert(pphead);
  SLNode* newnode = CreateNode(x);
  //链表为空
  if (*pphead == NULL)
  {
    *pphead = newnode;
  }
  else//链表不为空
  {
    SLNode* tail = *pphead;
    while (tail->next)//找尾结点
    {
      tail = tail->next;
    }
    tail->next = newnode;//尾插
  }
}

五、单链表头插

//单链表头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{
    assert(pphead);
  SLNode* newnode = CreateNode(x);
  newnode->next = *pphead;
  *pphead = newnode;
    //SLNode* newnode = CreateNode(x);
  链表为空
  //if (*pphead == NULL)
  //{
  //  *pphead = newnode;
  //}
  //else//链表不为空
  //{
  //  SLNode* tmp = *pphead;
  //  *pphead = newnode;
  //  (*pphead)->next = tmp;
  //}
}

六、单链表尾删

//单链表尾删
void SLTPopBack(SLNode** pphead)
{
  assert(pphead);
  assert(*pphead);//链表不能为空
  if ((*pphead)->next == NULL)//链表只有一个结点
  {
    free(*pphead);
    *pphead = NULL;
  }
  else//链表有多个结点
  {
    SLNode* tail = *pphead;
    SLNode* prev = NULL;
    while (tail->next != NULL)
    {
      prev = tail;
      tail = tail->next;
    }
    prev->next = NULL;
    free(tail);
    tail = NULL;
  }
}

七、单链表头删

//单链表头删
void SLTPopFront(SLNode** pphead)
{
  assert(pphead);
  assert(*pphead);
  //SLNode* tmp = *pphead;
  //*pphead = (*pphead)->next;
  //free(tmp);
  //tmp = NULL;
  SLNode* tmp = (*pphead)->next;
  free(*pphead);
  *pphead = tmp;
}

八、单链表查找(返回找到的结点)

//单链表查找(返回找到的结点)
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{
  if (phead == NULL)
    return NULL;
  else
  {
    SLNode* cur = phead;
    while (cur)
    {
      if (cur->val == x)
        return cur;
      cur = cur->next;
    }
    return cur;//return NULL;
  }
}

九、单链表任意位置插入

//单链表任意位置插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
  assert(pphead);
  assert(pos);//必须在有效结点处插入
  assert(*pphead);//如果pos是有效结点,那么链表一定不为空
  SLNode* newnode = CreateNode(x);
  if (*pphead == pos)//插入位置在头结点处
  {
    //头插
    SLTPushFront(pphead, x);
  }
  else
  {
    SLNode* cur = *pphead;
    while (cur->next != pos)//找插入位置的前一结点
    {
      cur = cur->next;
    }
    newnode->next = cur->next;
    cur->next = newnode;
  }
}

十、单链表任意位置删除

//单链表任意位置删除
void SLTErase(SLNode** pphead, SLNode* pos)
{
  assert(pphead);
  assert(pos);//删除的必须是有效结点
  assert(*pphead);//链表不能为空
  if (*pphead == pos)//删除的结点是头结点
  {
    //头删
    SLTPopFront(pphead);
  }
  else
  {
    SLNode* cur = *pphead;
    while (cur->next != pos)//找删除结点的前一结点
    {
      cur = cur->next;
    }
    cur->next = pos->next;
    free(pos);
    pos = NULL;
  }
}

十一、单链表任意位置后插入

//单链表任意位置后插入
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{
  assert(pos);//必须是有效结点
  SLNode* newnode = CreateNode(x);
  newnode->next = pos->next;
  pos->next = newnode;
}

十二、单链表任意位置后删除

//单链表任意位置后删除
void SLTEraseAfter(SLNode* pos)
{
  assert(pos);//必须是有效结点
  assert(pos->next);//如果pos是最后一个结点,那么pos的后一位置为空
  SLNode* tmp = pos->next;
  pos->next = tmp->next;
  free(tmp);
  tmp = NULL;
}

十三、单链表任意位置插入(不提供链表头结点)

先进行任意位置后插入,再交换两个结点的值

//单链表任意位置插入(不提供链表头结点)
void SLTInsertNohead(SLNode* pos, SLNDataType x)
{
  assert(pos);
  SLTInsertAfter(pos, x);//先在pos位置后插入
  pos->next->val = pos->val;
  pos->val = x;
}


目录
相关文章
|
8月前
【数据结构】单链表之--无头单向非循环链表
【数据结构】单链表之--无头单向非循环链表
|
3月前
|
测试技术 C语言
单链表之无头链表(C语言版)
本文详细介绍了使用C语言实现无头单链表的方法,包括节点和链表结构的定义、链表的创建与销毁、节点的插入与删除,以及链表的打印等功能。文章通过具体的代码示例,展示了如何在无头链表中进行头插法、尾插法、自定义位置插入和删除,以及如何清空和销毁链表。
52 0
单链表之无头链表(C语言版)
|
3月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
41 0
|
8月前
快速入门无头双链表
快速入门无头双链表
29 3
|
8月前
|
存储 C语言
链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)
在上一篇文章中,我们探索了顺序表这一基础的数据结构,它提供了一种有序存储数据的方法,使得数据的访 问和操作变得更加高效。想要进一步了解,大家可以移步于上一篇文章:探索顺序表:数据结构中的秩序之美 今天,我们将进一步深入,探讨另一个重要的数据结构——链表 链表和顺序表一样,都属于线性表,也用于存储数据,但其内部结构和操作方式有着明显的不同。通过C语言的具体实现,我们将会更加直观地理解它
139 1
链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)
|
8月前
【无头双向链表和链表练习题2】
【无头双向链表和链表练习题2】
39 0
【单链表】无头单项不循环(2)
【单链表】无头单项不循环(2)
636 2
【单链表】无头单项不循环(1)
【单链表】无头单项不循环(1)
614 2
|
存储 C语言
单链表(无头单项非循环)
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表的形式有很多,本篇文章主要介绍的是单链表且无头结点。在严版数据结构(C语言 第2版)中,单链表采用的是有头节点,这两种形式,各有利弊。含头节点的单链表在学习时,可能会容易些,但是在实践中或者在力扣中做题时,很少会有带头节点。但是有时候做题,使用带头节点的单链表会简单许多,不常见。
85 0
单链表(无头单项非循环)
|
8月前
|
存储 缓存 算法
手撕无头单链表
手撕无头单链表
42 0