数据结构(线性表及顺序表)

news2024/12/23 13:55:21

目录

线性表

线性结构定义

常见线性结构

线性表

顺序表及其实现

顺序结构

顺序表的存储映像图

顺序表seqList及操作的定义(seqList.h)

顺序表基本操作的实现分析

查找操作

实现代码

插入操作

实现代码

删除操作

实现代码

顺序表应用——基本操作的测试


线性表

线性结构定义

Ø一组特征相同且数量有限的元素构成的集合。
Ø该集合可以为空,也可以不为空。
Ø当不为空时,有唯一一个元素被称为首元素,有唯一一个元素被称为尾元素。
Ø除了尾元素,每个元素有且仅有一个直接后继元素;除了首元素,每个元素有且仅有一个直接前驱元素。

常见线性结构

线性表(List)、时间有序表(Chronological Ordered List)、排序表(Sorted List)、频率有序表(Frequency Ordered List)等。

线性表:通过元素之间的相对位置来确定它们之间相互关系。

时间有序表:按元素到达结构的时间先后,确定元素之间的关系。栈/队列

排序表:据元素的关键字值来确定其间的关系。

频率有序表:按元素的使用频率确定它们之间的相互关系。

线性表

一种仅由元素的相互位置确定它们之间相互关系的线性结构,元素之间呈现出你先我后的关系。

线性表的规模或长度是指线性表中元素的个数。

特别地:当元素的个数为零时,该线性表称为空表

线性表List的ADT :描述关系和关系操作

Data: { xi | xi ∈ElemSet, i=1,2,3,……n, n > 0} 或 Φ; ElemSet为元素集合。

Relation: {<xi,xi+1>|xi,xi+1∈ElemSet, i=1,2,3,……n-1},

                          x1为首元素,xn为尾元素。

Operations:

     initialize    前提:  无或指定List 的规模。结果:  分配相应空间及初始化。

     isEmpty   前提:无      结果:表List 为空返回true,否则返回false。

     isFull       前提:无  结果:表List 为满返回true,否则返回false。

    length    前提:无  结果:返回表List 中的元素个数。

    get        前提:已知元素序号。

                结果: 如果该序号元素存在,则返回相应元素的数据值。

    find       前提:已知元素的数据值。

                结果: 查找成功,返回元素的序号,否则返回查找失败标志。

    insert     前提:已知待插入的元素及插入位置。

                 结果:如果插入位置合理,在指定位置插入该元素。

   remove       前提:已知被删元素的值。

                   结果:首先按值查找相应元素,查找成功则删除该元素。

   clear           前提:  无

                    结果:删除表List 中的所有元素。

常见的基本操作来源于生活中对这种结构的了解。

基本操作可以分为几大类型:结构类、属性类、数据操纵类、遍历类和典型应用类

顺序表及其实现

顺序结构

Ø元素存放在内存中一块连续的空间里。
Ø借助存储空间物理上的连续性,元素可以按照其逻辑顺序依次存放,即元素存放的物理顺序和它的逻辑顺序是一致的。
Ø顺序存储的线性表称顺序表
Ø在高级语言的固有数据类型中,数组在存储器中就表现为一块连续的空间,因此用数组实现顺序表非常合适。
Ø数组中各元素位置由其下标来表示,它同时也是相应元素的位置序号。

顺序表的存储映像图

elem为数组名字,数组存储线性表。

maxSize为len的上界;initSize为最大的存储空间数,maxSize=initSize-1

elem[0]用于其它特殊用途,如果不用于特殊用途maxSize=initSize

len 为元素个数,即顺序表长度;

顺序表seqList及操作的定义(seqList.h)

#include <iostream>
#define INITSIZE 100
using namespace std;
 
//用于异常处理中识别错误类别
class illegalSize{};
class outOfBound{};

template <class elemType>
class seqList
{    private:
        elemType *elem; // 顺序表存储数组,存放实际的数据元素。
        int len;        // 顺序表中的元素个数,亦称表的长度。
        int maxSize;    // 顺序表的的最大可能的长度。
        void doubleSpace(); //私有函数,做内部工具
 public:
        seqList(int size=INITSIZE); //初始化顺序表
        //表为空返回true,否则返回false。                    注意各处:
                                                   //       const和const &的用法
        bool isEmpty()const { return ( len == 0 ); }
        //表为满返回true,否则返回false。
        bool isFull()const { return (len == maxSize); }
        int length()const {return len;}  //表的长度,即实际存储元素的个数。
        
        elemType get(int i )const;//返回第i个元素的值
        //返回值等于e的元素的序号,无则返回0.
        int find (const elemType &e )const;
        //在第i个位置上插入新的元素(值为e),
        //使原来的第i个元素成为第i+1个元素。
        void insert(int i, const elemType &e );
        // 若第i个元素存在,删除并将其值放入e指向的空间。
        void remove(int i, elemType &e );
 
        void clear() { len=0; }; //清除顺序表,使得其成为空表
        ~seqList() { delete []elem; }; //释放表占用的动态数组
};
//属性赋初值,注意模板函数用法:帽子和胡须
template <class elemType>  seqList<elemType>::seqList(int size)
//初始化顺序表
{
    elem = new elemType[size];//申请动态数组
    if (!elem) throw illegalSize();
    maxSize = size-1; //0下标位置用于查找时做哨兵位。
    len = 0;
}
template <class elemType>
void seqList<elemType>::doubleSpace()
{   int i;
    elemType *tmp = new elemType[2*maxSize];
    if (!tmp) throw illegalSize();
 
    for (i=1; i<=len; i++)    tmp[i] = elem[i];
 
    delete []elem;   elem = tmp;
    maxSize = 2*maxSize - 1;
}

顺序表基本操作的实现分析

查找操作

待查元素放哨兵位,从后往前比较 

分析时间效率:

查找成功情况:

查找每个位置元素等概率1/n

平均: (1+2+…+n)1/n=(n+1)/2

时间复杂度:O(n)

查找不成功情况:

每次查找从尾部到哨兵位,比较n+1次

时间复杂度:O(n)

实现代码

template <class elemType> //注意各处const, const+&组合的用法
int seqList<elemType>::find (const elemType &e )const  
// 返回值等于e的元素的序号,无则返回0.
{
    int i;
    elem[0] = e;  //哨兵位先置为待查元素
    for (i=len; i>=0; i--)
        if (elem[i]==e) break;
    return i;
}

插入操作

新元素欲插在下标为i的位置,i可能的取值为n+1, n, … ,  2, 1

特别注意:

从后往前至i位置逐个元素后移一位。

分析时间效率

插入每个位置等概率1/n+1

移动的次数分别0,1,2,…,n

平均: (1+2+…+n)/(n+1)=n/2

时间复杂度:O(n)

如何写出一个完成的程序?

“五步口诀法”:

1.参数检查
2.空间是否支持
3.核心操作
4.对其他属性的影响
5.正确返回

实现代码

template <class elemType>
void seqList<elemType>::insert (int i, const elemType &e )
{  int k;
    if ((i<1)||(i>len+1)) return; //插入位置越界
    if (len==maxSize) doubleSpace(); //空间满了,无法插入元素
    for (k=len+1; k>i; k--)        //循环注意:左右边界的检查
        elem[k]=elem[k-1];
    elem[i]=e;
    len++;
}

删除操作

元素在下标为i的位置,i可能的取值为n, … ,  2, 1

特别注意:

是自i+1位置开始,从前往后逐个元素前移一位。

分析时间效率

删除每个位置等概率1/n

移动的次数分别0,1,2,…,n-1

平均: (1+2+…+n-1)/n=n-1/2

时间复杂度:O(n)

实现代码

template <class elemType> //注意五步口诀法
void seqList<elemType>::remove (int i, elemType &e )
{  int k;
    if ((i<1)||(i>len)) return;
    e=elem[i];
    for (k=i; k<len; k++)
        elem[k]=elem[k+1];
    len--;
} 
template <class elemType> 
elemType seqList<elemType>::get(int i)const// 返回第i个元素的值
{
    if ((i<1)||(i>len)) throw outOfBound();
    return elem[i];
}
 

常见错误:

        1.混淆lenmaxSize的含义,前者是实际元素的个数,后者是存储空间的大小,也是最多能存多少元素的限制。

        2.seqList对象作为函数形参,直接用对象形式而不用引用形式, 这样即浪费空间又引起seqList类的复制构造函数的执行,降低运行效率

        3.insert函数实现中忘记检查位置i合理、忘了检查表中是否有空间可以支持插入一个新的元素等,造成算法不完整。可以试着使用分析参数、空间检查、核心操作、对其他属性的影响、正确返回的“五步口诀法”,就可以设计出一个相对完整的程序。

顺序表应用——基本操作的测试

调用前面构造的seqlist.h

#include <iostream>
#include "seqlist.h"
using namespace std;
 
//求两个正整数集合的交集,用线性表处理集合问题。
int main()
{
    seqList<int> list1(20), list2(20), list3(20); //实例化对象
    int i, j, x;
    int len1,len3;
    //输入第一个整数集合中的元素,输入零结束:
    i=1;
    cout<<"输入第一个正整数集合,以零为结束标志:";
    cin>>x;
 
    while (x!=0)
    {
        list1.insert(i,x);
        i++;
        cin>>x;
    }
    //输入第二个整数集合中的元素,输入零结束:
    i=1;
    cout<<"输入第一个正整数集合,以零为结束标志:";
    cin>>x;
 
    while (x!=0)
    {
        list2.insert(i,x);
        i++;
        cin>>x;
    }
   //求list1,list2的交集,结果存入list3
    len1 = list1.length();
    j=1;
    for (i=1; i<=len1; i++)
    {
        x=list1.get(i);
        if (list2.find(x)!=0)
        {   
            list3.insert(j,x);
            j++;
        }
    }
   //显示list3中的元素
    cout<<"两个集合的交集元素为:";
    len3 = list3.length();
    for (i=1; i<=len3; i++)
    {
        x=list3.get(i);
        cout<<x<<" ";
    }
    cout<<endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手绘图说电子元器件-集成电路

集成电路是高度集成化的电子器件,具有集成度高、功能完整、可靠性好、体积小、重量轻、功耗低的特点,已成为现代电子技术中不可或缺的核心器件。 集成电路可分为模拟集成电路和数字集成电路两大类,包括集成运放、时基集成电路、集成稳压器、门电路、触发器、计数器、译码器…

【 uniapp - 黑马优购 | 分类界面 】创建cate分支、数据获取、动态渲染

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

【Lilishop商城】No4-4.业务逻辑的代码开发,涉及到:会员B端第三方登录的开发-web端第三方授权联合登录接口开发

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代…

机器学习——支持向量机(SVM)

文章目录1. 优化目标2. 大间距的直观理解3. 大间距分类背后的数学支持向量机&#xff08;Support Vector Machines&#xff09;是广泛应用于工业界和学术界的一种监督学习算法&#xff0c;在学习复杂的非线性方程时提供了一种更为清晰&#xff0c;更加强大的方式。下面从SVM的优…

【nowcoder】笔试强训Day10

目录 一、选择题 二、编程题 2.1井字棋 2.2密码强度等级 一、选择题 1.下列运算符合法的是&#xff08; &#xff09; A. && B. <> C. if D. : 逻辑与&&语法规则&#xff1a;表达式1&&表达式2&#xff0c;其中两个表达式都是布尔表达式…

LeetCode453.最小操作次数使数组元素相等

LeetCode刷题记录 文章目录&#x1f4dc;题目描述&#x1f4a1;解题思路&#x1f4dc;题目描述 给你一个长度为 n 的整数数组&#xff0c;每次操作将会使 n - 1 个元素增加 1 。 返回让数组所有元素相等的最小操作次数。 示例1 输入&#xff1a;nums [1,2,3] 输出&#xff1a…

EduIQ Network LookOut Administrator

EduIQ Network LookOut Administrator 网络了望管理员允许您从屏幕的远端实时监视计算机。您可以随时看到他们在做什么。除了计算机控制&#xff0c;您还可以捕获摩西和键盘用户。使用Network LookOut Administrator软件可以完成一些有用的工作&#xff1a; 远程儿童计算机控制…

记录一次Gstreamer运行报错排查

背景 系统&#xff1a;Ubuntu 20.04 显卡型号&#xff1a;RTX 2060 之前正常运行的Gstreamer的编解码代码&#xff08;有用到显卡硬件加速&#xff09;&#xff0c;突然运行报错。经过一番折腾&#xff0c;最终找到原因&#xff0c;是因为NVIDIA驱动近期更新了&#xff0c;与…

Node.js——模块化(一)

1. 模块化的基本概念 1.1 什么是模块化 1. 编程领域中的模块化 1.2 模块化规范 2. Node.js 中的模块化 2.1 Node.js 中模块的分类 2.2 加载模块 加载自定义模块给相对路径 ./是平级&#xff08;同一文件夹下调用&#xff09; //这是07.test.js代码 // 注意&#xff1a;在使用…

Cypress笔记-连接命令

.each() 作用 遍历数组数据结构&#xff08;具有 length 属性的数组或对象&#xff09; cy.get(.connectors-each-ul>li).each(function($el, index, $list){ //遍历每个li元素console.log($el, index, $list)}).its() 作用 获取对象的属性值 示例代码 cy.get(.conne…

MergeTree概述

概述 Clickhouse 中最强大的表引擎当属 MergeTree &#xff08;合并树&#xff09;引擎及该系列&#xff08;MergeTree&#xff09;中的其他引擎。MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中&#xff0c;数据可以以数据片段的形式一个接着一个的快速写入&am…

DonkeyCar [02] - 软件配置 - 上位机(windows)

前言&#xff1a;在windows下配置Donkey Car的上位机&#xff1a; 1 安装miniconda Python Conda是开源的管理系统&#xff0c;Miniconda是conda的开源最小安装。 Donkey的默认安装版本&#xff0c;3.7&#xff0c;Miniconda已经是 最新的版本&#xff0c;是3.10.8吧&#xf…

IB如何选科更有助于大学申请?

如果你准准备选择就读IB课程体系&#xff0c;IB选科颇为重要的&#xff0c;选课对于提升自己的竞争力是非常重要的&#xff0c;可以说合理的选课&#xff0c;是申请外国大学的奠基石。IB课程不同于其他两种课程体系&#xff0c;它并不以某个国家的课程体系为基础&#xff0c;而…

02、Java 数据结构:时间复杂度与空间复杂度

时间复杂度与空间复杂度1 场景理解1.1 场景11.2 场景21.3 场景31.4 场景41.5 代码实现2 时间复杂度2.1 渐进时间复杂度2.2 从基本操作执行次数推导出时间复杂度2.3 两种方法来计算2.4 四个场景的时间复杂度分析2.5 大 O 表达式的优劣3 空间复杂度4 时间复杂度和空间按复杂度关系…

《计算机网络》——第四章知识点

第四章思维导图如下&#xff1b; 网络层向上只提供灵活的、无连接的、尽最大努力交付的数据报服务&#xff0c;主要任务是把分组&#xff08;IP数据报)从通过路由选择与转发从源端传到目的端&#xff0c;为分组交换网上的不同主机提供通信服务。 互联网可以由多种异构网络互连…

基于Shell编程完成定时备份数据库,看这篇就够了

一. 前言 最近文哥班里有一个学员面试成功上岸&#xff0c;在公司开发时遇到了这么一个需求&#xff1a;领导要求他编写一个shell脚本&#xff0c;完成定时备份数据库的需求。由于他对linux以及shell编程不是很了解&#xff0c;这位学员感到束手无策&#xff0c;于是就求助文哥…

List的介绍

目录 1.什么是List 2.常见接口介绍 3.List 1.什么是List 在集合框架中&#xff0c;List是一个接口&#xff0c;继承自Collection。Collection也是一个接口&#xff0c;该接口规范了后续容器中常用的一些方法&#xff0c;具体如下所示 Iterable也是一个接口&#xff0c;表示实…

ArcGIS基础实验操作100例--实验11以线要素分割面要素(一)

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 基础编辑篇--实验11 以线要素分割面要素&#xff08;一&#xff09; 目录 一、实验背景 二、实验数据 …

今年十八,蓝桥速刷(Python-I)

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;红中 &#x1f342;专栏地址&#xff1a;python专栏 抽根烟先 蓝桥杯是个啥 蓝桥杯&#xff0c;又称圈钱杯(不是 是由…

MySQL数据库调优

MySQL数据库调优一、MySQL架构设计1.1、引言1.2、MySQL Server层1.2.1、连接器&#xff08;Connector&#xff09;1.2.2、查询缓存 &#xff08;Query Cache&#xff09;1.2.3、分析器&#xff08;Analyzer&#xff09;1.2.4、优化器&#xff08;optimizer&#xff09;1.2.5、执…