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

  线性表是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

posted @ 2017-02-27 16:26  Nathaneko  阅读(1294)  评论(0编辑  收藏  举报