数据结构(一)——顺序表(C语言实现)

2023-05-16

  • 定义
  • 实现
    • 定义结构
    • 定义操作
      • 创建顺序表
      • 初始化顺序表
      • 插入元素
      • 删除元素
      • 销毁顺序表

定义

数据结构是相互之间存在一种或多种特定关系的数据元素的集合。根据数据元素之间关系的不同特性,通常有如下4类基本结构:

  • 集合:结构中的数据元素之间除了“同属于一个集合”的关系外,别无其他的关系。如:广义表
  • 线性结构:结构中的数据元素之间存在一个对一个的关系。如:链表
  • 树形结构:结构中的数据元素之间存在一个对多个的关系。如:二叉树
  • 图(网)状结构:结构中的数据元素之间存在多个对多个的关系。如:。1

在线性结构中,根据存储方式分为顺序表链表,根据对表的操作限制,分为队列

顺序表的特征是,在内存中占用连续的存储单元,可以简单的理解为顺序表就是数组。只是根据需要,在实际应用中动态分配顺序表占用的内存单元。而数组是在编译的时候,预分配了指定大小的内存单元,因此如下代码段会在编译的时候报错。

int len = 10;
char arr[len];

但是顺序表又会有数据全部的特点:可以根据下标直接访问、不方便插入和删除元素(因为需要移动后续的元素)。

实现

定义结构

typedef int SeqType; //存储单元类型

typedef struct{
    SeqType *elem; //存储空间基地址
    int length; //当前长度
    int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;

结构体内,有三个元素:存储空间基地址,类似于数组首地址;当前长度,记录顺序表中有效存储单元个数;当前分配的存储容量,顺序表中,最多容纳的存储单元个数。当顺序表中所有存储单元已经被使用,在下次插入元素之前,需要新增存储单元。这点是数组所不具有的特性。

*注:定义一个存储单元类型SeqType是为了使顺序表适和更多数据类型,使用的时候修改SeqType类型即可

定义操作

创建顺序表

/**
 * 创建顺序表
 */
SqList createList_sq() {
    //SqList list;
    //return list;

    SqList* list = (SqList*)malloc(sizeof(SqList));
    return *list;
}

这里提供两种创建顺序表的代码,一种是由系统分配list占用的内存,一种是自己动态分配的内存,需要在程序运行之前手动释放占用的内存空间。

初始化顺序表

/**
 * 初始化顺序表
 * 返回1 表示初始化成功
 * 返回0 表示初始化失败
 */
int initList_sq(SqList &L) { //只有在C++中才会有引用的存在
    L.elem = (SeqType *) malloc(sizeof(SeqType) * LIST_INIT_SIZE);
    if (!L.elem)
        return 0; //内存分配失败,存储空间不够
    L.length = 0; //表示顺序表为空
    L.listsize = LIST_INIT_SIZE; //表示顺序表里,最大存储单元个数
    return 1;
}

分配顺序表的存储单元,初始化顺序表属性的值。

插入元素

/**
 * 插入顺序表
 * 下标是负数就插入到结尾
 */
int insertList_sq(SqList &L, int index, SeqType val) {
    if (index > L.length) { //存储的下表超出顺序表实际的长度
        printf("插入的下标超出顺序表的实际长度");
        return 0;
    }
    if (index < 0) //下标是负数,插入到结尾
        index = L.length;
    if (L.length == L.listsize) { //顺序表的存储单元已经存满
        printf("顺序表的存储单元已满,继续分配新的存储单元。");
        SeqType* newBase = (SeqType*) realloc(L.elem,
                (L.listsize + LISTINCREMENT) * sizeof(SeqType)); //继续分配存储单元
        if (!newBase) {
            printf("分配内存单元失败");
            return 0;
        }
        L.elem = newBase;
        L.listsize += LISTINCREMENT;
    }
    //寻找合适的插入位置,index后面的元素向后移动
    for (int i = L.length; i > index; i--) {
        L.elem[i] = L.elem[i - 1]; //向后移动
    }
    L.elem[index] = val; //插入元素
    L.length++;
    return 1;
}

将元素插入到指定的位置。插入之前,需要先判断顺序表中是否已经存满,再根据需要新增存储单元,最后插入元素。

/**
 * 插入顺序表(结尾的位置)
 * 与上面的函数是重名函数,这叫函数重载,在C++里面支持
 */
int insertList_sq(SqList &L, SeqType val) {
    return insertList_sq(L, L.length, val);
}

*引用和重载,是C++中才支持,因此需要在cpp文件中编译。

删除元素

/**
 * 删除指定的元素
 * 返回0 找不到指定的元素,删除失败。
 * 返回1 找到待删除的元素,删除成功。
 */
int removeList_sq(SqList &L, SeqType val) {
    int index = -1; //记录匹配到的下标
    for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == val) {
            //找到匹配的val,结束循环
            index = i;
            break;
        }
    }
    if (index < 0)
        return 0;
    for (; index < L.length - 1; index++) {
        L.elem[index] = L.elem[index + 1];
    }
    L.length--;
    return 1;
}

删除指定元素,需要先找到下标。依次移动下标后面的结点,修改length值。

/**
 * 根据下标删除是指定的结点,并返回元素的值
 * 返回0 下标超出顺序表长度,删除失败。
 * 返回1 下标正确,删除元素,并且将已删除元素值转给elem
 */
int removeList_sq(SqList &L, int index, SeqType &elem) {
    if (index >= L.length) //下标超出顺序表的长度
        return 0;
    index = index < 0 ? L.length : index; //下标负数表示删除最后一个节点
    elem = L.elem[index];
    for (int i = index; i < L.length - 1; i++) {
        L.elem[i] = L.elem[i + 1];
    }
    L.length--;
    return 1;
}

先取到指定下标的元素,赋值给elem,然后依次移动下标后面的结点。最后修改length值。

销毁顺序表

/**
 * 销毁顺序表
 */
void destoryList_sq(SqList &L) {
    free(L.elem); //释放存储空间
    L.length = 0;
    L.listsize = 0;
//  free(&L);
}

重点释放顺序表的存储单元。如果顺序表自身的内存也是动态分配的,需要手动释放。

最后附上,头文件的定义。

/*
 * sqlist.h
 *
 * 线性表的顺序存储
 *  Created on: 2016年8月30日
 *      Author: flueky
 */

#ifndef SQLIST_H_
#define SQLIST_H_

#define LIST_INIT_SIZE 50
#define LISTINCREMENT 10

typedef int SeqType; //存储单元类型

typedef struct{
    SeqType *elem; //存储空间基地址
    int length; //当前长度
    int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;

/**
 * 创建顺序表
 */
SqList createList_sq();

/**
 * 初始化顺序表
 */
int initList_sq(SqList &);

/**
 * 插入顺序表
 */
int insertList_sq(SqList &,int index,SeqType);

/**
 * 插入顺序表(结尾的位置)
 */
int insertList_sq(SqList &,SeqType);

/**
 * 在顺序表中移除指定位置元素,下标从0开始
 */
int removeList_sq(SqList &,int,SeqType &);

/**
 * 在顺序表中删除指定元素
 */
int removeList_sq(SqList &,SeqType);
/**
 * 销毁顺序表
 */
void destoryList_sq(SqList &);

#endif /* SQLIST_H_ */

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

数据结构(一)——顺序表(C语言实现) 的相关文章

随机推荐

  • win10远程win10的问题

    在被远程电脑上打开注册表 定位到 HKLM SYSTEM CurrentControlSet Control Terminal Server Winstations RDP tcp 找到 34 SecurityLayer 34 xff0c
  • C++11 thread 在 Windows 系统中无法使用问题解决

    最近在Windows10上使用C 43 43 11的 thread 时遇到了 34 未定义标识符 34 thread 34 34 的问题 xff0c 但是我已经包含了 lt thread gt 头文件 xff0c 这种问题在Linux上就没
  • Arch Install & some configuration

    一 安装 到 http mirror lupaworld com archlinux iso latest 或者 http ftp sjtu edu cn pub mirror2 www archlinux org iso latest 下
  • ubuntu20.04服务器安装xrdp

    span class token function sudo span span class token function apt span update span class token punctuation span span cla
  • ubuntu18 xrdp安装

    span class token comment 下载最新的安装脚本 span span class token function apt span span class token function install span tightv
  • Linux开发工具--makefile

    文章目录 makefileLinux第一个小程序 进度条Git三板斧 makefile 会不会写makefile xff0c 从一个侧面说明了一个人是否具备完成大型工程得能力 xff0c makefile带来的好处就是 自动化编译 xff0
  • Linux下安装MySQL

    第一步 xff1a 创建虚拟机 第二步 xff1a 虚拟机操作 vi etc sysconfig network scripts ifcfg ens33 将里面的unboot 61 on改为unboot 61 yes 紧接着重启网卡 sys
  • Ubuntu系统安装MySQL5.7&&MySQL8.x

    MySQL5 7版本在Ubuntu xff08 WSL环境 xff09 系统安装 课程中配置的WSL环境是最新的Ubuntu22 04版本 xff0c 这个版本的软件商店内置的MySQL是8 0版本 所以我们需要额外的步骤才可以安装5 7版
  • win10 安装debian,安装docker

    参考文章 xff1a https docs microsoft com zh cn windows wsl install win10 https docs docker com engine install debian https do
  • Jenkins结合SVN报错E230001: Server SSL certificate verification failed的解决方法

    最近公司搬家 xff0c 之前用来做一些自动化工作的Jenkins服务器 罢工 了 在最后SVN提交时报了一个之前没有的错误 xff1a svn E230001 Commit failed details follow svn E23000
  • 为WSL的ubuntu子系统安装图形化界面

    WSL只提供黑窗口登录功能 xff0c 为了使用gui xff0c 需要安装gui并且使用远程连接的方式登录 更新源 sudo apt get update 安装xorg sudo apt get install xorg 安装xfce4
  • Json 转sqlserver创建表脚本 JSONtoSQLGenerator

    This code takes a JSON input string and automatically generates SQL Server CREATE TABLE statements to make it easier to
  • 如何远程登陆Linux图形界面

    可以使用xrdp软件 xff0c 下面是具体的操作步骤 xff1a 1 给Linux系统安装xrdp工具 xff0c 在命令行中输入 xff1a sudo apt get install xrdp 2 在windows中点击开始 gt 运行
  • 信息学奥赛一本通-1049:晶晶赴约会

    题目描述 晶晶的朋友贝贝约晶晶下周一起去看展览 xff0c 但晶晶每周的1 3 5有课必须上课 xff0c 请帮晶晶判断她能否接受贝贝的邀请 xff0c 如果能输出YES xff1b 如果不能则输出NO 注意YES和NO都是大写字母 xff
  • 洛谷P1553 数字反转(升级版)

    洛谷P1553 数字反转 xff08 升级版 xff09 题目描述输入格式输出格式输入输出样例说明 提示个人理解整数百分数分数小数 AC代码写在最后 题目描述 给定一个数 xff0c 请将该数各个位上数字反转得到一个新数 这次与NOIp20
  • Windows10 WSL2 安装Ubuntu并使用图形化界面

    有了WSL2后 xff0c 又有可以折腾的东西了 可以使用WSL2的Linux环境编译 LaTeX LaTeX L A T E X 文档 xff0c 要比Windows端快很多 xff0c 也可以用vscode的Remote WSL插件来编
  • VMware创建虚拟机并分配地址

    修改虚拟机设置 修改网卡配置 vi etc sysconfig network scripts ifcfg ens33 TYPE 61 Ethernet PROXY METHOD 61 none BROWSER ONLY 61 no BOO
  • 蓝桥杯单片机开发板-定时器中断实现数码管0-99+摇摆灯(详解)

    本博文程序实现的功能是蓝桥杯51单片机通过定时器功能来实现数码管的计数与8个LED小灯的交替闪烁 首先是程序初始化函数 xff1a span class token keyword void span span class token fu
  • 鸿蒙OS2.0添加加密门禁卡进入卡包

    鸿蒙OS2 0添加加密门禁卡进入卡包 该功能需要手机支持NFC功能 xff0c 畅享 Nova 等系列不具备NFC功能 xff0c 如找不到添加小区门禁卡的功能 xff0c 可能需要将系统升级至最新版本 打开 钱包 在 钱包 gt 钥匙 g
  • 数据结构(一)——顺序表(C语言实现)

    定义实现 定义结构定义操作 创建顺序表初始化顺序表插入元素删除元素销毁顺序表 定义 数据结构是相互之间存在一种或多种特定关系的数据元素的集合 根据数据元素之间关系的不同特性 xff0c 通常有如下4类基本结构 集合 xff1a 结构中的数据