(一)(C语言)实现顺序表(静态分配)的基本操作(初始化、判断是否为空,打印表,插入和删除等)讲解(含相关C语言代码讲解及运行结果)

2023-11-08

(一)(C语言)实现顺序表(静态分配)的基本操作(初始化、查找、打印表、插入和删除等)讲解(含C语言完整代码讲解及运行结果)

文章目录

  • 一、顺序表
  • 二、顺序表相关操作
    • 1.初始化
    • 2.插入
    • 3.删除
    • 4.打印表
    • 5.查找
  • 三、完整代码讲解(C语言)
  • 总结

一、顺序表

       线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。因此,顺序表的特点是表中元素的逻辑顺序和其物理顺序相同。

1.顺序表(静态分配)

#define Maxsize 10    //定义线性表的最大长度
typedef struct
{
    ElemType data[MaxSize];  //顺序表的元素(Elemtype为元素的类型,可替换为int,char,float等)
    int length;              //顺序表的当前长度(表中元素个数)
}SqList;                     //顺序表的类型定义

       一维数组可以静态分配,也可以动态分配。在静态分配时,由于数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据就会溢出,进而导致程序崩溃。

2.顺序表(动态分配) 

#define InitSize 100    //表长度的初始定义
typedef struct
{
    int *data;       //指示动态分配数组的指针,这里的int可替换为其他类型
    int length;      //数组的当前个数
    int MaxSize;     //数组的最大容量
}SeqList;             //动态分配数组顺序表的类型定义

//C语言的初始动态分配语句:
L.data=(ElemType *)malloc(sizeof(ElemType)*InitSize);//动态申请一整片的内存空间

//初始化为
void InitList(SeqList *L){
    (*L).data=(int*)malloc(InitSize*sizeof(int));//这里的int可替换为其他类型
    (*L).length=0;
    (*L).MaxSize=InitSize;
}

       在动态分配时,存储数组的空间在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,就另外开辟一块更大的存储空间,用于替换原来的存储空间,从而达到扩充存储数组空间的目的,不需要为线性表一次性地划分所有空间。

       注:动态分配并不是链式存储,它同样属于顺序存储结构,物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时动态决定。

二、顺序表相关操作(静态分配)

1.初始化

代码如下(示例):

//初始化
bool InitList(SqList *L){
    for (int i = 0; i < MaxSize; i++)
    {
        (*L).data[i]=0;              //利用循环将表中的数据都为0
    }
    (*L).length=0;                   //将length也置为0,意思是当前表中无数据
    return true;
}

2.插入

由于在位序为i的位置,增加一个元素,则原来位序为i及位序i之后的元素都要往后移一位,将位序i给空出来,用来存放要插入的新元素。例:位序i后一位为i+1,位序i的要往后移一位,就是将位序i处的值放在位序为i+1处,因为数组中下标从0开始的,则在数组中表现为data[i]=data[i-1];

// 插入
bool ListInsert(SqList *L,int i,int e){
    if(i<1||i>(*L).length+1){
   printf("要插入的位置错误\n");  //只能在表中第一个元素和(最后一个元素的后一位)两者之间插入,
   return false;                 //按位序的话,i的值要满足1<=i<=length+1
    }
    if((*L).length>=MaxSize) {
        printf("存储空间已满!\n");      //如果length大于等于Maxsize说明表已满,插入数据失败
        return false;
    }
      int  j;
      for ( j=(*L).length; j>=i; j--)    //从最后一位开始到第i位(包括第i位),从后往前,
      {                       //将值往后移一位,从而将第i位给空出来(这里的i都为位序,从1开始)
        (*L).data[j]=(*L).data[j-1];     
      }
      (*L).data[i-1]=e;                  //将要插入的值放入位序为i中,即在数组中为data[i-1]
      (*L).length++;                     //由于表插入了一个元素,故length的值要加1
      return true;
}

3.删除

由于删除了一个元素,表中会空出来一个位置,即位序i会空出来,这时候就需要将位序i之后的值往前移一位 ,例:位序i后一位为i+1,要往前移一位,就是将位序i+1处的值放在位序为i处,因为数组中下标从0开始的,则在数组中表现为data[i-1]=data[i];

// 删除
bool ListDelete(SqList *L,int i,int *e){
    if(i<1||i>(*L).length){
        printf("要删除的位置错误\n");  //判断i值是否合法
        return false;
    }
    (*e)=(*L).data[i-1];              //将位序i中的值赋予e,用于返回
    int j;                          
    for (j=i;j<(*L).length;j++)       //利用循环从位序为i处到位序为的length最后一个元素,从前往后依次往前移动一个元素
    {                         
         (*L).data[j-1]=(*L).data[j];    
    }                                   
    (*L).length--;                    //由于删除一个元素,所以length减一    
    return true;
}

4.打印表

//打印表
void printList(SqList L){
    for (int i = 0; i < L.length; i++)         //i值从0开始
    {
        printf("第%d的值为:%d\n",i+1,L.data[i]); //利用数组下标依次将表中数据元素打印出来
    }
    if(L.length==0){
        printf("表中没有数据!\n");    //length为0时,此时表中无数据元素
    }
}

5.查找(按位查找和按值查找)

//查找
//1.按位查找
bool GetElem(SqList L,int i){
    if (i<1||i>L.length)
    {   
        printf("要查询的值的位置不合法!\n");
        return false;       //如果i值不合法(i只能在1<=i<=length内),则查找失败
    }
    printf("表中第%d个元素为:%d\n",i,L.data[i-1]);//输出表中位序为i的值
    return true;
}
//2.按值查找
bool LocateElem(SqList L,int e){
     if (L.length==0)
     {
        return false;
     }
     for (int i = 0; i < L.length; i++)//利用循环依次查找表中数据元素
     {
         if (L.data[i]==e)             //并依次和要查找的e值进行比较,如果相同则在表中找到e值,输出    
         {
            printf("此值%d为表中第%d个元素\n",e,i+1);
            return true;
         }
     }
}

三、完整代码讲解(C语言) 

在主函数中,为了方便我就设计插入了两个值,然后依次打印表中数据,按位查找,按值查找,删除,打印表进行。

#include<stdio.h>
#include<stdbool.h>   //如果要用bool类型,要加上这个头文件
#include<stdlib.h>
// 顺序表(静态分配)
#define MaxSize 10
typedef struct
{
    int data[MaxSize];
    int length; 
}SqList;
//初始化
bool InitList(SqList *L){
    for (int i = 0; i < MaxSize; i++)
    {
        (*L).data[i]=0;              //利用循环将表中的数据都为0
    }
    (*L).length=0;                   //将length也置为0,意思是表中无数据
    return true;
}
// 判断顺序表是否为空
int IsEmpty(SqList L){
    if (L.length==0)
    {
       return 111;
    }
    else
    {
        return 000;
    }   
}
//打印表
void printList(SqList L){
    for (int i = 0; i < L.length; i++)         //i值从0开始
    {
        printf("第%d的值为:%d\n",i+1,L.data[i]); //利用数组下标依次将表中数据元素打印出来
    }
    if(L.length==0){
        printf("表中没有数据!\n");    //length为0时,此时表中无数据元素
    }
}
// 插入
bool ListInsert(SqList *L,int i,int e){
    if(i<1||i>(*L).length+1){
        printf("要插入的位置错误\n");  //只能在表中第一个元素和(最后一个元素的后一位)两者之间插入,
        return false;                //按位序的话,1<=i<=length+1
    }
    if((*L).length>=MaxSize) {
        printf("存储空间已满!\n");      //如果length大于等于Maxsize说明表已满,插入数据失败
        return false;
    }
      int  j;
      for ( j=(*L).length; j>=i; j--)    //从最后一位开始到第i位(包括第i位),从后往前,
      {                                  //将值往后移一位,从而将第i位给空出来(这里的i都为位序,从1开始)
        (*L).data[j]=(*L).data[j-1];     
      }
      (*L).data[i-1]=e;                  //将要插入的值放入位序为i中,即在数组中为data[i-1]
      (*L).length++;                     //由于表插入了一个元素,故length的值要加1
      return true;
}
// 删除
bool ListDelete(SqList *L,int i,int *e){
    if(i<1||i>(*L).length){
        printf("要删除的位置错误\n");  //判断i值是否合法
        return false;
    }
    (*e)=(*L).data[i-1];              //将位序i中的值赋予e,用于返回
    int j;                          
    for (j=i;j<(*L).length;j++)       //利用循环从位序为i处到位序为的length最后一个元素,从前往后依次往前移动一个元素
    {                         
         (*L).data[j-1]=(*L).data[j];    
    }                                   
    (*L).length--;                    //由于删除一个元素,所以length减一    
    return true;
}
//查找
//1.按位查找
bool GetElem(SqList L,int i){
    if (i<1||i>L.length)
    {   
        printf("要查询的值的位置不合法!\n");
        return false;       //如果i值不合法(i只能在1<=i<=length内),则查找失败
    }
    printf("表中第%d个元素为:%d\n",i,L.data[i-1]);//输出表中位序为i的值
    return true;
}
//2.按值查找
bool LocateElem(SqList L,int e){
     if (L.length==0)
     {
        return false;
     }
     for (int i = 0; i < L.length; i++)//利用循环依次查找表中数据元素
     {
         if (L.data[i]==e)             //并依次和要查找的e值进行比较,如果相同则在表中找到e值,输出    
         {
            printf("此值%d为表中第%d个元素\n",e,i+1);
            return true;
         }
     }
}
int main(){
    SqList L;
    // 初始化
    InitList(&L);
    // 判断是否为空
    int ret;               //用来接收判断表是否为空的数据
    ret=IsEmpty(L);
    printf("ret= %d\n",ret);   //表为空输出“111”,表不为空输出“000”

    // 第一次插入数据
    printf("输入要插入的位置:\n");
    int i;int e;
    scanf("%d",&i);         //输入要插入的位置
    printf("输入要插入的值:\n");
    scanf("%d",&e);         //输入插入的值
    ListInsert(&L,i,e);
    // 打印表
    printList(L);

    //第二次插入数据
    printf("输入要插入的位置:\n");
    scanf("%d",&i);         
    printf("输入要插入的值:\n");
    scanf("%d",&e);          
    ListInsert(&L,i,e);
    // 再次打印表
    printList(L);

    //按位查找
    printf("输入要查询第几位的值:\n");
    scanf("%d",&i);
    GetElem(L,i);
    //按值查找
    printf("输入要查询的值:\n");
    scanf("%d",&e);
    LocateElem(L,e);
    
    // 删除数据
    printf("输入要删除的位置:\n");
    int n;int e3;                 //e3用来接收删除所返回的要删除的值
    scanf("%d",&n);               //输入要删除第几个值
    ListDelete(&L,n,&e3);
    printf("删除的值为:%d\n",e3);  //输出e3
    // 打印表
    printList(L);

    system("pause");
}

结果如下: 


总结

顺序表的优点:

            1.存储密度大:每个存储结点只存储数据本身

            2.可以随机存取表中任一元素

顺序表的缺点:

            1.在插入、删除某一元素时,需要移动大量元素

            2.大片连续空间分配不方便

            3.改变容量不方便


文章还有瑕疵,请各位指正。

链表的操作和链表的一些不易理解的知识会在下一篇介绍,如:LNode *和LinkList的区别,和在C语言中如何实现链表的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(一)(C语言)实现顺序表(静态分配)的基本操作(初始化、判断是否为空,打印表,插入和删除等)讲解(含相关C语言代码讲解及运行结果) 的相关文章

随机推荐

  • 宝塔面板部署nginx+springboot+netty

    nginx配置集成netty的springboot前后端分离项目 项目环境 CentOS 7 9 宝塔面板 nginx1 21 前后端分离项目按照日常部署方式部署到服务器 前往nginx配置文件nginx conf 配置TCP socket
  • 两台机器之间同步时间,并修改服务器层级

    作业a 第一台机器从阿里云同步时间 第二台机器从第一台机器同步时间 第一台机器配置 vim etc chrony conf 修改第一台机器的配置文件 将原有的pool注释掉 并添加阿里云时钟源 gt server ntp aliyun co
  • C++实现两个字符串交替组合成一个字符串

    引言 这道题来自力扣 给出两个字符串 将两个字符串交替着组合成一个字符串 如 string str1 abcd string str2 hb string str ahbbcd string str1 abcd string str2 hb
  • kafka高性能设计:内存池

    前言 Kafka的内存池是一个用于管理内存分配的缓存区域 它通过在内存上保留一块固定大小的内存池 用于分配消息缓存 批处理缓存等对象 以减少频繁调用内存分配函数的开销 Kafka内存池的实现利用了Java NIO中的 ByteBuffer
  • 罗技键盘连计算机,罗技键盘怎么连接电脑

    罗技蓝牙键盘连接电脑需装入电池 打开电源开关 转动拨盘至 1 位置 然后长按 PC 键3秒进入 搜索 模式 打开电脑 前往 设置 设备 蓝牙和其他设备 打开 蓝牙 在蓝牙搜索列表中选中罗技蓝牙键盘的名称 确认配对即可完成连接 本文以惠普光影
  • 搭建tcp客户端,双进程实现tcp服务端客户端随时收发,udp服务端客户端

    tcp客户端 include
  • HTML+CSS简易淘宝页面

    效果图 效果图中的图片可以去我微信公众号新白者 回复照片就行 HTML代码 注意这个外部链接引入css的名字与自己的相同 div div div a a div div div
  • 自动化测试开发 —— 如何封装自动化测试框架?

    封装自动化测试框架 测试人员不用关注框架的底层实现 根据指定的规则进行测试用例的创建 执行即可 这样就降低了自动化测试门槛 能解放出更多的人力去做更深入的测试工作 本篇文章就来介绍下 如何封装自动化测试框架 1 明确自动化测试框架需求 支持
  • 两数相加—思路和心得

    题目链接 https leetcode cn com problems add two numbers Definition for singly linked list public class ListNode int val List
  • Python运算符重载及其可重载运算符

    每个类型都有其独特的操作方法 例如列表类型支持直接做加法操作实现添加元素的功能 字符串类型支持直接做加法实现字符串的拼接功能 也就是说 同样的运算符对于不同序列类型的意义是不一样的 这是怎么做到的呢 其实在 Python 内部 每种序列类型
  • AJAX面试题

    1 什么是AJAX 为什么要使用Ajax 请谈一下你对Ajax的认识 什么是ajax AJAX是 Asynchronous JavaScript and XML 的缩写 他是指一种创建交互式网页应用的网页开发技术 Ajax包含下列技术 基于
  • 蓝桥杯备赛Day8——队列

    大家好 我是牛哥带你学代码 本专栏详细介绍了蓝桥杯备赛的指南 特别适合迎战python组的小白选手 专栏以天作为单位 定期更新 将会一直更新 直到所有数据结构相关知识及高阶用法全部囊括 欢迎大家订阅本专栏 队列也属于基础数据结构 队列概念
  • C#串口通信三步走

    第一步 实例化串口通讯类 SerialPort sp new SerialPort 第二步 设置串口信息并打开串口 串口设置 public void SetSP string PortName string BaudRate string
  • 项目开发总结报告(GB8567——88)(转载)

    项目开发总结报告 GB8567 88 1引言1 1编写目的说明编写这份项目开发总结报告的目的 指出预期的阅读范围 1 2背景说明 a 本项目的名称和所开发出来的软件系统的名称 b 此软件的任务提出者 开发者 用户及安装此软件的计算中心 1
  • unity3D 巡逻兵

    游戏要求 创建一个地图和若干巡逻兵 使用动画 每个巡逻兵走一个3 5个边的凸多边型 位置数据是相对地址 即每次确定下一个目标位置 用自己当前位置为原点计算 巡逻兵碰撞到障碍物 则会自动选下一个点为目标 巡逻兵在设定范围内感知到玩家 会自动追
  • UPC思维题--移动

    题目描述 考虑333的立方体 有六个面 每个面有九个正方形 染色方法如下 角上的方格是red 中心是green 其他为blue 初始有一个机器人站在立方体顶面中心 面朝一个blue方格 它将接受到一系列如下指令 L 左转90度 R 右转90
  • gzip 命令

    NAME gzip compression decompression tool using Lempel Ziv coding LZ77 SYNOPSIS gzip cdfhkLlNnqrtVv S suffix file file gu
  • SQL Server连接字符串句法

    Application Name 应用程序名称 应用程序的名称 如果没有被指定的话 它的值为 NET SqlClient Data Provider 数据提供程序 AttachDBFilename extended properties 扩
  • ts总结 之 ts中的类型

    其他内容 ts中的类型 编译选项 webpack打包 类 文章目录 ts是什么 ts增加了什么 TypeScript中的基本类型 字面量 number boolean string any unknown 类型断言 void never o
  • (一)(C语言)实现顺序表(静态分配)的基本操作(初始化、判断是否为空,打印表,插入和删除等)讲解(含相关C语言代码讲解及运行结果)

    一 C语言 实现顺序表 静态分配 的基本操作 初始化 查找 打印表 插入和删除等 讲解 含C语言完整代码讲解及运行结果 文章目录 一 顺序表 二 顺序表相关操作 1 初始化 2 插入 3 删除 4 打印表 5 查找 三 完整代码讲解 C语言