数据结构——线性表的链式存储结构1(单链表)

简介: 数据结构——线性表的链式存储结构1(单链表)

目录

前言

链表的定义

单链表的构建

单链表数据的插入

单链表数据的删除

单链表的数据的查询

单链表的数据修改

单链表的建立(头插法)

单链表的建立(尾插法)

单链表整表的删除(空间释放)

单链表结构与顺序存储结构的优缺点

前言

为了解决顺序存储不足:用线性表另外一种结构-链式存储。在顺序存储结构(数组描述)中,元素的地址是由数学公式决定的,而在链式储存结构中,元素的地址是随机分布的,每个元素都有一个明确的指针指向线性表的下一个元素的位置(即地址)。

链表的定义

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。在顺序结构中,每个数据元素只需要存数据元素信息就行了,而在链式结构中,除了存储数据元素信息外,还要存储它的后继元素的存储地址。所以一般结点包括两个信息:数据和指针。链表就是n个节点组成的,如果每个结点只包含一个指针,那么就是单链表。


有头有尾:我们把链表中第一个结点的存储位置叫作头指针,那么整个链表的存取就必须是从头指针开始进行的。而线性链表的最后一个结点指针为空(NULL)。从图中可以看到,结点都是由两部分组成,数据域和指针域。

image.png

结点是由存放数据元素的数据域和存放后继结点地址的指针域组成

单链表的构建

typedef int ElenTypedf;
typedef struct Node
{
  ElenTypedf data;//存储数据
  struct Node* next;
}Node;
typedef struct Node* LinkList;

单链表数据的插入

//单链表的插入
void ListInert(LinkList* ps, int i,ElenTypedf e)
{
  int j;
  LinkList p,s; //声明一个节点p
  p = *ps;
  j = 1;//计数器
  assert(!p&&j>i);//第i个元素不存在
  while (p && j < i)
  {
    p = p->next;
    ++j;
  }
  s = (LinkList)malloc(sizeof(Node));
  s->data = e;
  s->next = p->next;
  p->next = s;
}

单链表数据的删除

//单链表的删除
void ListDelete(LinkList* ps, int i)
{
  int j;
  LinkList p;
  p = *ps;
  j = 1;
  while (p->next && j < i)
  {
    p = p->next;
    j++;
  }
  assert(!(p->next) && j > i);
  p->next = p->next->next;
}

单链表的数据的查询

//单链表的数据查询
ElenTypedf ListSearch(LinkList ps,int i,ElenTypedf*e)
{
  int j = 0;
  LinkList p;//声明一个节点p
  p = ps->next;
  j = 1;
  while (p && j < i)
  {
    p = p->next;
    ++j;
  }
  assert(!p && j > i);
  *e = p->data;
}

单链表的数据修改

//单链表的数据修改
void ListModify(LinkList* ps, int i, ElenTypedf e)
{
  int j = 0;
  LinkList p;
  p = *ps;
  j = 1;
  while (p && j < i)
  {
    p = p->next;
    ++j;
  }
  assert(!p && j > i);
  p->data = e;
}

单链表的建立(头插法)

//单链表的建立(头插法)
void LinkListpushfront(LinkList* ps, int n)
{
  LinkList p;
  int i = 0;
  srand(time(0));
  *ps = (LinkList)malloc(sizeof(Node));
  (*ps)->next = NULL;//先建立一个头节点
  for (i = 0; i < n; i++)
  {
    p = (LinkList)malloc(sizeof(Node));
    p->data = rand() % 100 + 1;
    p->next = (*ps)->next;
    (*ps)->next = p;
  }
}

单链表的建立(尾插法)

//单链表的建立(尾插法)
void LinkListPushBack(LinkList* L, int n)
{
  LinkList p, r;
  int i = 0;
  srand(time(0));
  *L = (LinkList)malloc(sizeof(Node));
  r = *L;
  for (i = 0; i < n; i++)
  {
    p = (LinkList)malloc(sizeof(Node));
    p->data = rand() % 100 + 1;
        r->next=p;
    r = p;
  }
  r->next = NULL;
}

单链表整表的删除(空间释放)

//单链表整表的删除
void ClearList(LinkList* L)
{
  LinkList p, q;
  p = (*L)->next;
  while (p)
  {
    q = p->next;
    free(p);
    p = q;
  }
  (*L)->next = NULL;
}
int main()
{
  LinkList p=NULL;
  LinkListPushBack(&p,10);
  return 0;
}

单链表结构与顺序存储结构的优缺点

若线性表需要频繁查找,很少进行插入和删除操作时,适宜采用顺序存储结构。

当线性表中的元素个数变化较大或者根本不知道多大时最好用单链表结构。

相关文章
|
1月前
【数据结构】单链表(长期维护)(1)
【数据结构】单链表(长期维护)(1)
|
3月前
|
存储 算法
【数据结构和算法】--- 二叉树(4)--二叉树链式结构的实现(2)
【数据结构和算法】--- 二叉树(4)--二叉树链式结构的实现(2)
28 0
|
11天前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
|
1月前
|
存储
【数据结构】单链表-->详细讲解,后赋源码
【数据结构】单链表-->详细讲解,后赋源码
22 4
|
1月前
|
算法 索引
【初阶数据结构篇】单链表算法题进阶
深拷贝应该正好由 n 个全新节点组成,其中每个新节点的值都设为其对应的原节点的值。
|
1月前
【数据结构】单链表(长期维护)(2)
【数据结构】单链表(长期维护)(2)
|
2月前
|
存储 DataX C语言
【数据结构】单链表
数据结构中的单链表
23 0
【数据结构】单链表
|
3月前
|
算法 程序员 数据处理
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
|
3月前
|
算法 C语言
【数据结构与算法 经典例题】返回单链表的倒数第 k 个节点
【数据结构与算法 经典例题】返回单链表的倒数第 k 个节点
|
3月前
|
存储 算法 C语言
【数据结构与算法】深入理解 单链表
【数据结构与算法】深入理解 单链表