原文托管在Github: https://github.com/shellhub/blog/issues/52

数据结构与算法之线性表-顺序表实现(C语言版本)

前言

数据结构与算法是一个程序员必备的技能之一,而顺序表更是每个程序员在面试过程中要经常被问到的,如Java语言中的ArrayList类的底层实现就是使用顺序表实现的,别把顺序表想的有多么高大上,其实就是使用数组实现的一种线性表

什么是线性表

线性表(英语:Linear List)是由n(n≥0)个数据元素(结点)a[0],a[1],a[2]…,a[n-1]组成的有限序列。 其中: 数据元素的个数n定义为表的长度 = "list".length() ("list".length() = 0(表里没有一个元素)时称为空表) 将非空的线性表(n>=1)记作:(a[0],a[1],a[2],…,a[n-1]) * 数据元素a[i](0≤i≤n-1)只是个抽象符号,其具体含义在不同情况下可以不同

一个数据元素可以由若干个数据项组成。数据元素称为记录,含有大量记录的线性表又称为文件。这种结构具有下列特点:存在一个唯一的没有前驱的(头)数据元素;存在一个唯一的没有后继的(尾)数据元素;此外,每一个数据元素均有一个直接前驱和一个直接后继数据元素。

什么是顺序表

顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。

顺序表的实现

为了能实现顺序表的基本操作如(增,删,改,查),我们使用结构体封装一个指向一维数组的指针base,同时提供一个名字叫做length的整型变量表示顺序表中实际有用的元素个数,当插入一个元素时length++, 当删除一个元素时length--,所以length可以记录当前顺序表的长度

顺序表综合案列-学生信息管理系统

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>#define INIT_SIZE 1
#define INCREMENT_SIZE 5
typedef struct {int id; //学号int age; //年龄char name[10]; //姓名
} Student;typedef Student ElemType;typedef struct {ElemType *base;int size; /* 顺序表的最大容量 */int length; /* 记录顺序表的元素个数 */
} SqList;/*** 初始化顺序表* @param p 指向顺序表的指针* @return 如果初始化成功返回true否则返回false*/
bool init(SqList *p) {p->base = malloc(sizeof(SqList) * INIT_SIZE);if (p->base == NULL) {return false;}p->size = INIT_SIZE;p->length = 0;return true;
}/*** 指定位置插入数据元素* @param p 指向顺序表的指针* @param index 插入的下标* @param elem 插入的元素值* @return 如果插入成功返回true,否则返回false*/
bool insert(SqList *p, int index, ElemType elem) {if (index < 0 || index > p->length) {perror("插入下标不合法");return false;}//如果顺序表满了,则重新分配更大的容量if (p->length == p->size) {int newSize = p->size + INCREMENT_SIZE;ElemType *newBase = realloc(p->base, newSize);if (newBase == NULL) {perror("顺序表已满,重新分配内存失败");return false;}p->base = newBase;p->size = newSize;}//从最后一个元素开始依次把元素复制到后面的位置for (int i = p->length - 1; i >= index; --i) {p->base[i + 1] = p->base[i];}p->base[index] = elem;p->length++;return true;
}/*** 删除指定下标的数据元素* @param p 指向顺序表的指针* @param index 删除的元素的下标* @param elem 返回删除的元素* @return 如果删除成功返回true否则返回false*/
bool del(SqList *p, int index, ElemType *elem) {if (p->length == 0) {perror("顺序是空的,无法执行删除操作");return false;}if (index < 0 || index > p->length - 1) {perror("删除位置不合法");return false;}//把删除的元素保存起来*elem = p->base[index];//从删除位置开始依次把后面的元素赋值到前面for (int i = index; i < p->length - 1; ++i) {p->base[i] = p->base[i + 1];}p->length--;return true;
}/*** 更新顺序表中特定的元素值* @param p 指向顺序表的指针* @param index 更新下标* @param elem 更改后的新元素值* @return 如果更改成功则返回true,否则返回false*/
bool update(SqList *p, int index, ElemType elem) {if (p->length == 0) {perror("顺序表是空的,无法指向更新");return false;}if (index < 0 || index > p->length - 1) {perror("更新下标不合法");return false;}p->base[index] = elem;return true;
}/*** 搜索顺序表中特定下标的元素* @param list 指定的顺序表* @param index 搜索的下标* @param elem 保存搜索到的元素* @return 如果搜索成功则返回true,否则返回false*/
bool search(SqList list, int index, ElemType *elem) {if (list.length == 0) {perror("顺序表没有任何元素,无法查找");return 0;}if (index < 0 || index > list.length - 1) {perror("查找下标不合法");return false;}*elem = list.base[index - 1];return true;
}/*** 打印顺序表* @param list 指定顺序表*/
void output(SqList list) {printf("学号t年龄t姓名n");for (int i = 0; i < list.length; ++i) {printf("%dt%dt%sn", list.base[i].id, list.base[i].age, list.base[i].name);}printf("n");
}int main() {SqList list;while (1) {printf("tt顺序表的基本操作n");printf("tt1.初始化顺序表n");printf("tt2.顺序表的插入n");printf("tt3.顺序表的删除n");printf("tt4.顺序表的查找(下标)n");printf("tt5.顺序表的修改n");printf("tt6.打印n");printf("tt0.退出n");int choice;printf("请输入功能编号:");scanf("%d", &choice);switch (choice) {case 1:if (init(&list)) {printf("初始化成功n");}assert(list.length == 0);break;case 2:;ElemType elem;printf("请输入插入的学生学号:");scanf("%d", &elem.id);printf("请输入插入的学生年龄:");scanf("%d", &elem.age);printf("请输入插入的学生姓名:");scanf("%s", elem.name);printf("请输入插入位置:");int index;scanf("%d", &index);if (insert(&list, index, elem)) {printf("插入成功n");}break;case 3:printf("请输入删除位置:");scanf("%d", &index);if (del(&list, index, &elem)) {printf("删除的学生 学号:%dt年龄:%dt姓名:%sn", elem.id, elem.age, elem.name);}break;case 4:printf("请输入要查找的位置:");scanf("%d", &index);if (search(list, index, &elem)) {printf("查找的学生 学号:%dt年龄:%dt姓名:%sn", elem.id, elem.age, elem.name);}break;case 5:printf("请输入更新位置:");scanf("%d", &index);printf("请输入更新后的学生学号:");scanf("%d", &elem.id);printf("请输入更新后的学生年龄:");scanf("%d", &elem.age);printf("请输入更新后的学生姓名:");scanf("%s", elem.name);if (update(&list, index, elem)) {printf("更新成功n");}break;case 6:output(list);break;case 0:exit(0);default:printf("输入编号有误,请重新输入n");break;}}return 0;
}

顺序表优缺点

  • 优点

    • 因为顺序表使用数组实现,可以通过下标存取,所以存取速度极快,T(n)=O(1)
    • 无需为表中元素之间的逻辑关系而增加额外的存储空间
    • 空间利用效率高
  • 缺点
    • 插入删除均需要循环移动元素,比较浪费时间 T(n)=O(n)
    • 需要提前预估顺序表的长度(INIT_SIZE),分配太大浪费,造成内存的碎片化

rsa算法c语言实现_数据结构与算法之线性表-顺序表实现(C语言版本)相关推荐

  1. python线性表顺序存储实现_数据结构——基于C的线性表的顺序存储结构的基本操作的实现...

    /*** *SeqList.c *Copyright (c) 2015, XZG. All rights reserved. *Purpose: * 线性表顺序存储结构的创建.数据插入.数据获取.获取 ...

  2. python思想读后感_数据结构与算法:Python语言描述读后感1000字

    <数据结构与算法:Python语言描述>是一本由裘宗燕著作,机械工业出版社出版的平装图书,本书定价:CNY 45.00,页数:343,特精心从网络上整理的一些读者的读后感,希望对大家能有帮 ...

  3. 一篇解双链表(0基础看)(C语言)《数据结构与算法》

    目录 序言 带头双向循环链表 1. 概念 2. 效果展示图 3. 接口实现 3.01. 本文章要实现的接口 ​3.02. 双链表的实现 3.03. 双链表的初始化 3.04. 打印链表 3.05. 动 ...

  4. 2.2基本算法之递归和自调用函数_数据结构与算法之5——队列和栈

    栈和队列比较简单,而且实用性非常广泛,这里主要介绍一下他们的概念和实现,在很多算法中,栈和队列的运用很重要,因此,虽然简单确是最重要的数据结构之一,必须重视. 栈是保证元素后进先出(后存入者先使用,L ...

  5. 循环首次适应算法_数据结构与算法之2——排序问题

    排序真的是数据结构与算法中的重中之重啊,无论是对编程能力的提升,以后工作后的应用,或者是应对面试的时候都是经常需要用到的.基本的几个经典排序一定要做到滚瓜烂熟,能够做到给你一个具体的排序算法题,一定能 ...

  6. mooc数据结构与算法python版期末测验_中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案...

    中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案 更多相关问题 采用fopen()函数打开文件,支持文件读取的参数有: [简答题]简单阐述高分子材料热-机械特征及成型加工的关系,并 ...

  7. 嵌入式团队培训_数据结构和算法概述

    嵌入式团队培训_数据结构与算法概述 要求:理解并记忆即可,会求解算法的时间复杂度 一:数据结构 1.逻辑结构: 2.物理结构 3.抽象数据类型 二:算法 1.算法的五个基本特征: 2.算法设计的要求 ...

  8. 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表

    列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...

  9. vrp 节约算法 c++_数据结构和算法(Golang实现)(8.1)基础知识-前言

    基础知识 学习数据结构和算法.我们要知道一些基础的知识. 一.什么是算法 算法(英文algorithm)这个词在中文里面博大精深,表示算账的方法,也可以表示运筹帷幄的计谋等.在计算机科技里,它表示什么 ...

最新文章

  1. C++ STL: 容器vector源码分析
  2. mysql查询通过两个字段逆序
  3. MySQL安装叫重启_MySQL重启命令和MySQL数据库安装目录的操作过程
  4. pytorch FC_classification
  5. 屏幕监控中捕获鼠标位置信息
  6. Git学习(四)标签管理
  7. com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor和oracle不识别
  8. 【图像隐写】基于matlab DWT数字水印嵌入+攻击+提取【含Matlab源码 1759期】
  9. mysql里判断_mysql里如何使用判断语句?
  10. golang gin mysql_Golang 的Gin框架入门教学
  11. UG工程图模板制作方法,超级实用
  12. Winform之网易音乐、百度音乐、QQ音乐付费音乐免费下载
  13. 三菱PLC FB库新建和调用-(Gx Work2版本)
  14. 技术学校面试该说什么_我第一次现场技术面试后,香港专业教育学院学到了什么...
  15. python工具类-sql操作封装
  16. A站复兴?B站说NO
  17. 100 道 Linux 常见面试题,慢慢读~
  18. 从内积、外积和叉乘到多维空间的理解
  19. 华氏度与摄氏度对照表
  20. 解决微信返回码为40113,错误信息errmsg:unsupported file type

热门文章

  1. 基于Office 365的随需应变业务应用平台
  2. 在Azure Container Service创建Kubernetes(k8s)群集运行ASP.NET Core跨平台应用程序
  3. OSS.Social微信项目标准库介绍
  4. Xamarin的坑 - 绑定(一) - 拿微信iOS SDK 简单说起
  5. Visual Studio “15”第三个预览版发布
  6. 从业十余年谈谈对dotnet看法与坚持
  7. python读取oracle数据库性能_用python对oracle进行简单性能测试
  8. [转]Xdebug----Failed loading
  9. ffmpeg源码分析及mp4文件解析
  10. 【土地评价与土地管理】案例:兰州市榆中县农用地分等