走进数据结构和算法(c++版)(2)——线性表的顺序存储结构

线性表的顺序存储结构

  想要通过计算机帮助我们解决各种问题,首先我们就要把现实中的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能。当我们可以通过一条“线”把这些连续或是离散的数据元素“串”起来储存,就是线性结构。我们看下线性表的定义:

线性表 ( List ):零个或多个数据元素的有限序列。

  要注意的它是一个序列,数据元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继
  本文介绍的是线性表中顺序存储结构,那么什么是顺序存储结构?

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

  简单的来说就是线性的连续存储数据,我们可以用数组来实现。来看线性表的顺序存储的代码。

class Arr
{
public:
    Arr(int len = 50);//初始化,设定数组长度
    ~Arr();
    bool append_arr(int val);//追加一个元素
    bool insert_arr(int pos,int val);//在pos位置插入一个val值
    bool delet_arr(int pos,int &val);//删除pos位置的值
    bool is_empty();//判断数组是否为空
    bool is_full();//判断数组是否为满
    void sort_arr();//数组从小到大排序
    void show_arr();//输出数组
    void inversion_arr();//倒置数组
 private:
    int* Bbase;//存储的是数组第一个元素的地址
    int len;//数组长度
    int cnt=0;//当前数组有效元素的个数,即线性表长度

};

  这里我们要注意下“数组长度”“线性表长度”的区别。数组的长度是存放线性表的存储空间的长度这个量是一般是不变的。线性表的长度是线性表中数据元素的个数,即当前数组有效元素的个数。
  下面我们看下数组具体操作的代码:

#include "Arr.h"
#include<iostream>
using namespace std;

Arr::Arr(int len) :len(len), Bbase(new int[len])//初始化,设定数组长度
{

}


Arr::~Arr()
{
    delete [] Bbase;
}

bool Arr::is_empty()//判断数组是否为空
{
    return cnt == 0 ? true : false;
}

void  Arr::show_arr()//输出数组
{

    if (is_empty())
    {
        cout << "数组为空" << endl;
    }
    else
    {
        for (int i = 0; i < cnt; i++)
        {
            cout << Bbase[i] <<" ";
        }
        cout << endl;
    }
}
bool Arr::is_full()//判断数组是否为满
{
    return cnt == len ? true : false;
}

bool Arr::append_arr(int val)//追加一个元素
{
    if (is_full())return false;
    Bbase[cnt++] = val;
    return true;

}
bool Arr::insert_arr(int pos, int val)//在pos位置插入一个val值
{
    if (pos<1 || pos>cnt+1)
        return false;
    for (int i = cnt-1; i >= pos - 1; i--)
    {
        Bbase[i + 1] = Bbase[i];
    }
    Bbase[pos - 1] = val;
    cnt++;
    return true;
}
bool Arr::delet_arr(int pos, int &val)//删除pos位置的值
{
    if (is_empty())return false;
    if (pos<1 || pos>cnt)return false;
    val = Bbase[pos - 1];
    for (int i = pos; i < cnt; i++)
    {
        Bbase[i - 1] = Bbase[i];
    }
    cnt--;
    return true;
}
void Arr::inversion_arr()//倒置数组
{
    int i = 0, j = cnt - 1;
    int t;
    while (i < j)
    {
        t = Bbase[i];
        Bbase[i] = Bbase[j];
        Bbase[j] = t;
        i++;
        j--;
    }
}
void Arr::sort_arr()//数组从小到大排序
{
    int i, j, t;
    for (i = 0; i < cnt; i++)
    {
        for (j = i + 1; j < cnt; j++)
        {
            if (Bbase[i]>Bbase[j])
            {
                t = Bbase[i];
                Bbase[i] = Bbase[j];
                Bbase[j] = t;
            }
        }
    }
}

  数组的追加就是在线性表原有的数据元素后面再加上数据元素,同时线性表长度增加1。输出数组就是将线性表中的数据元素依次打印到屏幕上。倒置数组,就是把线性表头尾倒置。我们用下面的程序来试试效果。

#include<iostream>
#include "Arr.h"
using namespace std;

int main()
{
    Arr arr;
    arr.append_arr(4);
    arr.append_arr(2);
    arr.append_arr(5);
    arr.append_arr(11);
    arr.append_arr(9);
    arr.show_arr();
    arr.inversion_arr();
    arr.show_arr();
    system("pause"); 
    return 0;
}

  在vs上运行结果如下:
1

  插入操作就是在线性表中的任意位置增加一个数据元素。其的算法思路如下:

  1. 如果插入位置不合理,抛出异常;
  2. 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
  3. 从最后一个元素开始向前遍历到第 i 个位置,分别将它们都向后移动一个位置;
  4. 将要插入元素填入位置 i 处;
  5. 表长加 1 。

      需要注意的是,要在i位置插入数据元素,要先把这个位置给空出来。

#include<iostream>
#include "Arr.h"
using namespace std;

int main()
{
    Arr arr;
    arr.append_arr(4);
    arr.append_arr(2);
    arr.append_arr(5);
    arr.append_arr(11);
    arr.append_arr(9);
    arr.show_arr();
    arr.insert_arr(3, 0);
    arr.show_arr();
    system("pause"); 
    return 0;
}

  注意insert_arr(int pos,int val)函数中pos值是从1开始。当然你也可以修改程序使pos从0开始。运行结果如下:
2

  删除操作就是删除线性表中的任意位置的数据元素。其算法思想如下:

  1. 如果删除位置不合理,抛出异常;
  2. 取出删除元素;
  3. 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
  4. 表长减 1 。
#include<iostream>
#include "Arr.h"
using namespace std;

int main()
{
    int val;
    Arr arr;
    arr.append_arr(4);
    arr.append_arr(2);
    arr.append_arr(5);
    arr.append_arr(11);
    arr.append_arr(9);
    arr.show_arr();
    arr.delet_arr(4, val);
    cout << "删除的数据元素为:" << val << endl;
    arr.show_arr();
    system("pause"); 
    return 0;
}

  运行结果如下:
3

  排序算法会在后面文中详细讲解,这里就先看下效果。

#include<iostream>
#include "Arr.h"
using namespace std;

int main()
{
    Arr arr;
    arr.append_arr(4);
    arr.append_arr(2);
    arr.append_arr(5);
    arr.append_arr(11);
    arr.append_arr(9);
    arr.show_arr();
    arr.sort_arr();
    arr.show_arr();
    system("pause"); 
    return 0;
}

  运行结果如下:

4

线性表顺序存储结构的优缺点

优点

  • 无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
  • 可以快速地存取表中任一位置的元素。

缺点

  • 插入和删除操作需要移动大量元素。
  • 当线性表长度变化较大时,难以确定存储空间的容量。
  • 造成存储空间的”碎片”。

猜你喜欢

转载自blog.csdn.net/hu_weichen/article/details/80431865