《数据结构》c语言版学习笔记——线性表的顺序存储结构

简介: 《数据结构》c语言版学习笔记——线性表的顺序存储结构

前言


数据结构是大学里计算机专业类必掌握的一门课程,它很重要,尤其是对一些考研的计算机类学生来说,通常为专业课。数据结构并不是哪种编程语言所设定的,它可以用c语言来写,也可以用c++、java、python等等,学会了一门编程语言,仅仅只是掌握一些,而学会了数据结构可以掌握很多技巧和算法并不断提高编程能力,这对将来很重要。


提示:本系列文章均使用Visual Studio 2019编程,编程语言为c语言。


一、顺序存储结构的建立


1.条件


设顺序线性表L,n为数据元素,则1 ≦ n ≦ ListLength(L),这里解释一下这个闭区间,首先我们知道线性表是从1开始的,而不是像数组从0开始,这点要知道,所以n的值不能小于1,并且不能大于该线性表的长度。

我们设该线性表的存储空间为20,即#define MAXSIZE 20,然后假设ElemType为int类型,使用一个结构体,定义一个data数组来存储数据元素,length为当前长度。

即,我们可知道建立一个顺序线性表有三个要点:

①首先要定义其最大存储量

②存储空间

③线性表的当前长度


2.代码


#include <stdio.h>
#define MAXSIZE 20            //设定存储空间初始分配量
//顺序存储结构的建立
typedef int ElemType;
typedef struct
{
  ElemType data[MAXSIZE];   //数组存储数据元素,最大值为MAXSIZE
  int length;               //线性表当前长度
}SqList;


二、顺序存储结构的获得元素


1.条件


首先这里返回值类型Status是一个int整型,返回OK代表1,返回ERROR代表0。我们要实行GetElem操作,即将顺序线性表L的第i个元素值返回,因为数组是从0开始的,代码中只要n的数值在所定义的数组下标的范围内,把数组n-1下标的值返回。

即,我们可知道顺序线性表获得元素有两个要点:

①判断语句

②返回值


2.代码


#include <stdio.h>
#define MAXSIZE 20            //设定存储空间初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
//顺序结构的获得元素操作
Status GetElem(SqList L, int n, ElemType* e)    //Status是函数类型,其值是函数结果状态代码,例OK等;
{                                               //SqList L为该线性表;int n为索引位置;ElemType*e为指针直接访问地址
  if (L.length == 0 || n<1 || n>L.length)     //线性表的长度不为0;线性表是从1访问的,而不是0;索引位置不能大于线性表的长度
    return ERROR;        //以上均返回错误
  *e = L.data[n-1];        //若满足以上条件,则将线性表L中的第n个位置元素值返回,即只要n的数值在数组下标范围内,就将数组第n-1下标的值返回
  return OK;
}


三、顺序存储结构的插入


1.条件


设k为当前位置,首先判断线性表是否已满,再对插入位置进行判断,然后判断插入位置是否在表尾,从而执行不同操作,若不在表尾,通过for语句遍历,将要插入的位置后的数据元素向后移动一位;若在表尾,则直接插入新元素,当前长度++。

即,顺序线性表插入元素有五个要点:

①若插入位置不合理,抛出异常

②判断语句

③从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置

④将要插入元素插入位置i处

⑤表长加1


2.代码


//顺序结构的插入操作
typedef int Status;
Status ListInsert(SqList* L, int n, ElemType e)
{
  int k;                          //k为当前位置
  if (L->length == MAXSIZE)       //当顺序线性表存储已满返回错误  
    return ERROR;    
  if (n<1 || n>L->length + 1)    //插入位置小于1、大于当前长度加一则返回错误
    return ERROR;
  if (n <= L->length)            //若插入位置不在线性表表尾,执行以下操作,将要插入的位置后数据元素向后移动一位
  {
    for (k = L->length - 1; k >= n - 1; k--)    //遍历从i索引位置到线性表长度的每个数据元素,将其全部向后移动一位
      L->data[k + 1] = L->data[k];           
  }
  //若插入位置在表尾,执行插入新元素操作
  L->data[n - 1] = e;             //[i-1]是因为顺序表位置-1=数组下标,数组从0开始,顺序表从1开始
  L->length++;
  return OK;
}


四、顺序存储结构的删除


1.条件


设k为当前位置,首先判断线性表是否为空表,再判断删除元素长度,用指针取出所要删除的数据元素,然后再判断删除位置是否在表尾,若不在表尾,通过for语句遍历,将要删除的位置后数据元素向前移动一位;若在表尾,则删除该元素,当前长度- -。

顺序线性表删除元素有四个要点:

①若删除位置不合理,抛出异常

②取出删除元素

③从删除元素位置开始遍历到最后一个元素位置,将它们向前移动一位

④表长减1


2.代码


//顺序结构的删除操作
typedef int Status;
Status ListDelete(SqList* L, int n, ElemType* e)
{
  int k;                    //k为当前位置
  if (L->length == 0)       //若线性表为空,即空表,则返回错误
    return ERROR;
  if (n<1 || n>L->length)   //当删除元素小于1,大于当前长度,删除位置不正确返回错误
    return ERROR;
  *e = L->data[n - 1];      //e相当于回收站,将要删除的元素位置放到e中;*e表示取指针e所指地址存储的值;线性表中第n个值相当于数组data[n-1]
  if (n < L->length)        //若删除操作不是最后位置,执行以下操作,将要删除的位置后数据元素向前移动一位
  {
    for (k = n; k < L->length; k++)    //遍历从n索引位置到线性表长度的每个数据元素,将其全部向后移动一位
      L->data[k - 1] = L->data[k];
  }
  L->length--;             
  return OK;
}


五、总代码


//线性表顺序存储结构
#include <stdio.h>
#define MAXSIZE 20            //设定存储空间初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
//顺序存储结构的建立
typedef int Status;
typedef int ElemType;
typedef struct
{
  ElemType data[MAXSIZE];   //数组存储数据元素,最大值为MAXSIZE
  int length;               //线性表当前长度
}SqList;
//顺序结构的获得元素操作
Status GetElem(SqList L, int n, ElemType* e)    //Status是函数类型,其值是函数结果状态代码,例OK等;
{                                               //SqList L为该线性表;int n为索引位置;ElemType*e为指针直接访问地址
  if (L.length == 0 || n<1 || n>L.length)     //线性表的长度不为0;线性表是从1访问的,而不是0;索引位置不能大于线性表的长度
    return ERROR;        //以上均返回错误
  *e = L.data[n-1];        //若满足以上条件,则将线性表L中的第n个位置元素值返回,即只要n的数值在数组下标范围内,就将数组第n-1下标的值返回
  return OK;
}
//顺序结构的插入操作
Status ListInsert(SqList* L, int n, ElemType e)
{
  int k;                          //k为当前位置
  if (L->length == MAXSIZE)       //当顺序线性表存储已满返回错误  
    return ERROR;    
  if (n<1 || n>L->length + 1)    //插入位置小于1、大于当前长度加一则返回错误
    return ERROR;
  if (n <= L->length)            //若插入位置不在线性表表尾,执行以下操作,将要插入的位置后数据元素向后移动一位
  {
    for (k = L->length - 1; k >= n - 1; k--)    //遍历从i索引位置到线性表长度的每个数据元素,将其全部向后移动一位
      L->data[k + 1] = L->data[k];           
  }
  //若插入位置在表尾,执行插入新元素操作
  L->data[n - 1] = e;             //[i-1]是因为顺序表位置-1=数组下标,数组从0开始,顺序表从1开始
  L->length++;
  return OK;
}
//顺序结构的删除操作
Status ListDelete(SqList* L, int n, ElemType* e)
{
  int k;               //k为当前位置
  if (L->length == 0)       //若线性表为空,即空表,则返回错误
    return ERROR;
  if (n<1 || n>L->length)   //当删除元素小于1,大于当前长度,删除位置不正确返回错误
    return ERROR;
  *e = L->data[n - 1];      //e相当于回收站,将要删除的元素位置放到e中;*e表示取指针e所指地址存储的值;线性表中第n个值相当于数组data[n-1]
  if (n < L->length)        //若删除操作不是最后位置,执行以下操作,将要删除的位置后数据元素向前移动一位
  {
    for (k = n; k < L->length; k++)    //遍历从n索引位置到线性表长度的每个数据元素,将其全部向后移动一位
      L->data[k - 1] = L->data[k];
  }
  L->length--;             
  return OK;
}


总结


以上就是本次的笔记内容,本文仅仅通过文字和代码简单介绍了顺序存储结构的各项操作,建议自己分析总结其各个操作并结合自己的编程能力选择编程语言再写一遍代码从而加深印象。


相关文章
|
搜索推荐 C语言
数据结构(C语言)之对归并排序的介绍与理解
归并排序是一种基于分治策略的排序算法,通过递归将数组不断分割为子数组,直到每个子数组仅剩一个元素,再逐步合并这些有序的子数组以得到最终的有序数组。递归版本中,每次分割区间为[left, mid]和[mid+1, right],确保每两个区间内数据有序后进行合并。非递归版本则通过逐步增加gap值(初始为1),先对单个元素排序,再逐步扩大到更大的区间进行合并,直至整个数组有序。归并排序的时间复杂度为O(n*logn),空间复杂度为O(n),且具有稳定性,适用于普通排序及大文件排序场景。
|
存储 安全 C语言
【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】
分支的语句,这可能不是预期的行为,这种现象被称为“case穿透”,在某些特定情况下可以利用这一特性来简化代码,但在大多数情况下,需要谨慎使用。编写一个程序,该程序需输入个人数据,进而预测其成年后的身高。根据提示,在右侧编辑器补充代码,计算并输出最终预测的身高。分支下的语句,提示用户输入无效。常量的值必须是唯一的,且在同一个。语句的作用至关重要,如果遗漏。开始你的任务吧,祝你成功!,程序将会继续执行下一个。常量都不匹配,就会执行。来确保程序的正确性。
532 10
|
小程序 C语言
【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】
目录 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果: 任务描述 相关知识 编程编写一个程序,从键盘输入3个变量的值,例如a=5,b=6,c=7,然后将3个变量的值进行交换,使得a=6,b=7,c=5。面积=sqrt(s(s−a)(s−b)(s−c)),s=(a+b+c)/2。使用输入函数获取半径,格式指示符与数据类型一致,实验一下,不一致会如何。根据提示,在右侧编辑器补充代码,计算并输出圆的周长和面积。
404 10
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
693 10
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
473 7
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
653 5
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
480 5
|
存储 编译器 C语言
【C语言程序设计——选择结构程序设计】求一元二次方程的根(头歌实践教学平台习题)【合集】
本任务要求根据求根公式计算并输出一元二次方程的两个实根,精确到小数点后两位。若方程无实根,则输出提示信息。主要内容包括: - **任务描述**:使用求根公式计算一元二次方程的实根。 - **相关知识**:掌握 `sqrt()` 函数的基本使用方法,判断方程是否有实根。 - **编程要求**:根据输入的系数,计算并输出方程的根或提示无实根。 - **测试说明**:提供两组测试数据及预期输出,确保代码正确性。 - **通关代码**:包含完整的 C 语言代码示例,实现上述功能。 通过本任务,你将学会如何处理一元二次方程的求解问题,并熟悉 `sqrt()` 函数的使用。
340 5
|
存储 算法 安全
【C语言程序设计——选择结构程序设计】按从小到大排序三个数(头歌实践教学平台习题)【合集】
本任务要求从键盘输入三个数,并按从小到大的顺序排序后输出。主要内容包括: - **任务描述**:实现三个数的排序并输出。 - **编程要求**:根据提示在编辑器中补充代码。 - **相关知识**: - 选择结构(if、if-else、switch) - 主要语句类型(条件语句) - 比较操作与交换操作 - **测试说明**:提供两组测试数据及预期输出。 - **通关代码**:完整代码示例。 - **测试结果**:展示测试通过的结果。 通过本任务,你将掌握基本的选择结构和排序算法的应用。祝你成功!
297 4
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
387 4