• 基础数据结构-线性表-顺序表


      线性表是n个数据元素的有限序列,数据之间存在顺序关系,一般同一个线性表属于同一类数据对象(例如A~Z的字母表)。线性表存在唯一一个首位元素和末位元素,除了第一个元素和最后一个元素,每个元素存在着一个前驱和一个后继(A的后继是B,B的前驱是A)。线性表主要有顺序表和链表两种存储形式,线性表是一种逻辑结构,顺序表和链表是物理存储结构。本篇主要讲的是顺序表的实现。

      顺序表是线性表的顺序表示,用一组地址连续的存储单元依次存储线性表的数据元素,本文主要用数组实现最简单的顺序表。

      顺序表的类定义如下:

    #include<iostream>
    using namespace std;
    
    #define ok 0
    #define error -1
    
    //顺序表类定义
    class SeqList
    {
    private:
        int *list;    //存储元素的数组
        int maxsize;    //顺序表可以存储的最大长度
        int size;        //顺序表的实际长度
    public:
        SeqList();    //构造函数
        ~SeqList();    //析构函数,用于回收存储空间
        int list_size();    //获取顺序表实际长度,用于增、删等操作
        int list_insert(int i, int item); //在i位置插入一个元素item
        int list_del(int i);    //删除i位置的元素
        int list_get(int i);    //获取i位置的元素
        void list_display();        //输出顺序表
    };
    SeqList::SeqList()
    {
        maxsize = 1000;
        size = 0;
        list = new int[maxsize]; //创建一个大小为1000的顺序表
    }
    SeqList::~SeqList()
    {
        delete []list;    //回收空间
    }

      为了对顺序表进行操作,我们需要增、删、查、改等功能,基础语法这里就不解释了。size=0初始了顺序表的实际大小为0,因为这个时候创建的顺序表是空的,在后续的操作中插入一个数据size便加1,删除一个便减1。

      下面是插入功能的实现:

    int SeqList::list_insert(int i, int item)
    {
        if(size == maxsize || i<1 || i>size+1)
            return error;    //检查顺序表是否已满,输入参数的位置是否在实际范围内
        else
        {
            int temp;
            for(temp=size-1; temp>=i-1; temp--)    //temp=size-1是因为数组是从0开始的,例如一个数组a有3个元素:a[0],a[1],a[2],此时size=3,最后一个元素下标=size-1
                list[temp+1]=list[temp];    //将要插入元素位置的后续元素全部往后移动一个位置,从最后一个元素开始移动
            list[i-1]=item;    //将插入的元素item覆盖到i个元素的位置上(i-1同理temp)
            size++;
            return ok;
        }
    }

      插入的操作原理是让插入位置后续的元素全部后移一个位置,顺序表实际长度增加1,然后让待插入的元素覆盖插入位置原有的元素。所以对于需要频繁修改的线性表,顺序表需要比较多次的计算,后面会讲的链表的链式存储结构更适合需要高频改动的场景。

      需要稍微转换一下思维的就是数组下标是从0开始存储数据的,在注释里我解释了。

      下面是删除的操作,删除的原理是让要删除的位置后面的元素一个个覆盖上去,相当于后面的元素全部往前移动一个位置。

    int SeqList::list_del(int i)
    {
        if(size == 0 || i<1 || i>size+1)
            return error;
        else
        {
            int temp;
            for(temp=i-1; temp<size-1; temp++)    //从i-1后面的元素全部往前移动1个位置,覆盖掉要删除的元素位置
                list[temp]=list[temp+1];
            list[size-1]=0;    //将最后一个多出来的元素设为0
            size--;
            return ok;
        }
    }

      下面是其它基本操作:

    int SeqList::list_size(){         //获取顺序表实际长度
        return size;
    }
    
    void SeqList::list_display() //用于输出整个顺序表
    {     
        int i;
        cout << size << ' ';    //首先输出顺序表大小,再输出内容
        for(i=0;i<size-1;i++)
            cout << list[i] << ' ';
        cout << list[size-1] << ' ' << endl;
    }
    
    int SeqList::list_get(int i)    //获取指定位置i的元素值
    {        
        if (i<1||i>size+1)
            return error;
        else{
            cout << list[i-1] << endl;
            return ok;
        }
    }

      接下来结合实验题目:

    实现顺序表的用C++语言和类实现顺序表
    属性包括:数组、实际长度、最大长度(设定为1000)
    操作包括:创建、插入、删除、查找

    输入
    第1行先输入n表示有n个数据,即n是实际长度;接着输入n个数据
    第2行输入要插入的位置和新数据
    第3行输入要插入的位置和新数据
    第4行输入要删除的位置
    第5行输入要删除的位置
    第6行输入要查找的位置
    第7行输入要查找的位置

    输出
    数据之间用空格隔开
    第1行输出创建后的顺序表内容,包括顺序表实际长度和数据
    每成功执行一次操作(插入或删除),输出执行后的顺序表内容
    每成功执行一次查找,输出查找到的数据
    如果执行操作失败(包括插入、删除、查找等失败),输出字符串error,不必输出顺序表内容

    样例输入
    6 11 22 33 44 55 66
    3 777
    1 888
    1
    9
    0
    5

    样例输出
    6 11 22 33 44 55 66
    7 11 22 777 33 44 55 66
    8 888 11 22 777 33 44 55 66
    7 11 22 777 33 44 55 66
    error
    error
    44

      因为具体操作函数我们在上面已经写好了,接下来在主函数调用就可以了。

    int main()
    {
    int i,t,ln,flag; SeqList sl; cin >> t; for(i=1;i<=t;i++)  //输入初始顺序表 { cin >> ln; sl.list_insert(i,ln); } sl.list_display(); //输出第1行:输入的数据 cin >> t >> ln; //第2行输入要插入的位置和新数据 flag = sl.list_insert(t,ln); if (flag==error) cout << "error" << endl; else sl.list_display(); cin >> t >> ln; //第3行输入要插入的位置和新数据 flag = sl.list_insert(t,ln); if (flag==error) cout << "error" << endl; else sl.list_display(); cin >> t; //第4行输入要删除的位置 flag = sl.list_del(t); if (flag==error) cout << "error" << endl; else sl.list_display(); cin >> t; //第5行输入要删除的位置 flag = sl.list_del(t); if (flag==error) cout << "error" << endl; else sl.list_display(); cin >> t; //第6行输入要查找的位置 flag = sl.list_get(t); if (flag==error) cout << "error" << endl; cin >> t; //第7行输入要查找的位置 flag = sl.list_get(t); if (flag==error) cout << "error" << endl; return 0; }

      篇幅差不多了,因为本文主要读者是给刚开始学习数据结构的同学,所以更多关于顺序表的操作下一篇会讲。第一篇编程博客文章,虽然是简单的内容但发现写下来发现还是挺需要时间的,不知道开学后有没有空余的时间呢。

    作者:Nathaneko

  • 相关阅读:
    Docker系列
    Eclipse 安装TestNG插件,结合Maven使用
    HttpClient设置忽略SSL,实现HTTPS访问, 解决Certificates does not conform to algorithm constraints
    Jenkins Html Rport 使用frame报错解决办法
    Zend Framework1 框架入门(针对Windows,包含安装配置与数据库增删改查)
    Windows下Nginx配置SSL实现Https访问(包含证书生成)
    Windows下Nginx Virtual Host多站点配置详解
    幽灵般的存在:零宽空白
    我的公司培训讲义(2):设计模式思想精要教程
    突如其来而又必然的离职
  • 原文地址:https://www.cnblogs.com/nathaneko/p/6474855.html
Copyright © 2020-2023  润新知