数据结构——线性表的链式存储结构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;
}

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

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

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

目录
打赏
0
0
0
0
1
分享
相关文章
|
3月前
|
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
104 10
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
108 7
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
214 5
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
117 5
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
5月前
|
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
585 9
|
5月前
|
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
146 58
|
3月前
|
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
242 77
|
2月前
|
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
39 11
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。