顺序表--C++类的实现

一.线性表的定义

线性表是一个若干个数据元素组成的有限序列

作为“序列”,除了第一个和最后一个元素,都是有前驱和后继的

二.顺序表的实现

顺序表是线性表的顺序存储方式,需要用到一段地址连续的存储单元来存储数据

顺序存储结构需要三个属性:

  • 存储空间的起始位置: 数组data

  • 线性表的最大存储空间:maxSize

  • 线性表的当前长度:last

我们重点来聊一聊数组长度和线性表长度的区别

  1. 数组长度maxSize是存放线性表存储空间的长度,一般是不变的,但是也可以改,但是会有损耗

  2. 线性表长度last是存放的数据元素的个数,这个是可以随意改变的

  3. last≤maxSize

那么顺序表类中的private部分的定义如下

template <class T>
class SeqList{
 private:
  T *data;
  int maxSize;
  int last;
  //这里也可以添加修改数组长度的函数,看个人需求
}

三.地址计算方法

Loc(第i个元素)=Loc(第一个元素)+(i-1)* c

c表示一个数据元素所占的存储空间

时间复杂程度为O(1)

通常把这种存储结构称为随机存储结构

四.顺序表的插入与删除操作

1.获取元素的操作
template <class T>
bool getData(int i,T&x){
   if(i>=0&&i<=last){    //判断i是否合法
     x=data[i];
     return true;
   }else{
     return false;
   }
}
2.插入操作

算法思路如下:

  • 如果线性表长度≥数组长度,抛出异常

  • 如果插入位置不合理,抛出异常

  • 从最后一个元素开始向前遍历到第i个位置,分别向后移动一个位置

  • 将要插入的元素添入位置中

  • 表长+1

那我们就来动手操作

template <class T>
bool Insert(int i,T&x){
  //第一步操作
    if(last>=maxSize-1){
     return false;
    }
  //第二步操作
    if(i<0||i>last){
     return false;
    }  
  //第三步操作
    for(int j=last;j>=i;j--){
     data[j+1]=data[j];          //后移操作

    }
  //第四步操作
    data[i]=x;
  //第五步操作
    last++;
  return true;
}

每一个数据结构我们需要熟练掌握其增删改减的方法,非常重要

3.删除操作

基本算法如下:

  • 删除的位置不合理,抛出异常(记得判断是否表空)

  • 取出删除元素

  • 从删除元素的位置开始遍历到最后一个元素,将它们向前移动一个位置

  • 表长减1

template <class T>
bool Delete(int i,T&x){
  //第一步
   if(last==0){
   return false;
   }
   if(i<0||i>last){
     return false;
   }
  //第二步
  x=data[i];
  //第三步
  for(int j=i;j<last;j++){
   data[j]=data[j+1];
  }
  //第四步
  last--;
  return true;
}

用之前学到的大O()推导式我们可以得出

插入和删除的时间复杂程度是O(n)

详细内容见:数据结构中的基础算法-CSDN博客

五.顺序表的优缺点

优点:

  • 无需增加额外的存储空间

  • 可以快速存取任一位置的元素

缺点:

  • 插入和删除需要移动大量元素

  • 线性表长度变化大时,难以确定存储空间的容量

  • 造成存储空间的“碎片”

六.顺序表类的完整代码

本人一直用的代码,大家可以参考着写

#include <iostream>
using namespace std;
const int defaultSize = 100;
template<class T>
class SeqList {
protected:
    T* data;
    int maxSize;
    int last;//从零开始存的最后一个位置
    void reSize(int newSize);
public:
    SeqList(int sz = defaultSize);
    SeqList(SeqList<T>& L);
    ~SeqList() { delete[] data; }
    int Size()const { return maxSize; }
    int Length() { return last + 1; }
    int Search(T& x)const;  //const保护对象数据成员,且const成员函数执行时不能调用非const成员函数
    int Locate(int i)const;
    bool getData(int i, T& x)const
    {//输入的是第i位元素0,1,2,3...
        if (i >= 0 && i <= last) { x = data[i]; return true; }
        else return false;
    }
    void setData(int i, T& x)
    {//与上面同样 修改后:
        if (i >= 0 && i <= last)data[i] = x;
    }
    bool Insert(int i, T& x);
    bool Remove(int i, T& x);
    bool IsEmpty() { return (last == -1) ? true : false; }
    bool IsFull() { return (last == maxSize - 1) ? true : false; }
    void input();
    void output();
    SeqList<T>operator=(SeqList<T>& L);

};
template <class T>
SeqList<T>::SeqList(int sz) {
    if (sz > 0) {
        maxSize = sz;
        last = maxSize - 1;//修改01
        data = new T[maxSize];
        //if (data == NULL)
        //{
        //    cerr << "存储分配错误!" << endl; exit(1);
        //}
    }
}
template <class T>
SeqList<T>::SeqList(SeqList<T>& L) {
    maxSize = L.Size();
    last = L.Length() - 1;
    T value;
    data = new T[maxSize];
   // if (data == NULL)
   // {
    //    cerr << "存储分配错误!" << endl; exit(1);
    //}
    for (int i = 0; i <= last; i++) {
        L.getData(i, value);
        data[i] = value;
    }
}
template <class T>
void SeqList<T>::reSize(int newSize) {//未测试
    if (newSize <= 0)
    {
        cout << "无效的数组大小" << endl;
    }
    if (newSize != maxSize) {
        T* newarray = new T[newSize];
       // if (newarray == NULL)
       // {
        //    cerr << "存储分配错误!" << endl; exit(1);
       // }
        int n = last + 1;
        T* srcptr = data;
        T* destptr = newarray;
        while (n--)
            *destptr++ = *srcptr++;
        delete[] data;
        data = newarray;
        maxSize = newSize;
    }
}
template <class T>
int SeqList<T>::Search(T& x)const {
    for (int i = 0; i <= last; i++)//修改
        if (data[i] == x)
            return i;
    return 0;
}
template<class T>
int SeqList<T>::Locate(int i) const {
    if (i >= 0 && i <= last)//修改 ...这函数有什么用?
        return i;
    else
        return 0;
}
template <class T>
bool SeqList<T>::Insert(int i, T& x) {//第i位
    if (last == maxSize - 1)
        return false;
    if (i<0 || i>last)
        return false;
    for (int j = last; j >= i; j--)
        data[j + 1] = data[j];
    data[i] = x;
    last++;
    return true;
}
template <class T>
bool SeqList<T>::Remove(int i, T& x) {
    if (last == -1)
        return false;
    if (i<0 || i>last)return false;

    x = data[i];//存被删除的元素的值
    for (int j = i; j < last; j++)
        data[j] = data[j + 1];//修改03
    last--;
    return true;
}
template <class T>
void SeqList<T>::input() {
    // cout << "开始建立顺序表,请输入表中元素个数:";
    while (1) {
        cin >> last;
        last -= 1;//修改02
        if (last <= maxSize)
            break;
        //cout << "表中元素个数输入有误,范围不能超过" << maxSize - 1 << ":";
    }
    for (int i = 0; i <= last; i++) {
        //  cout << i << " ";
        cin >> data[i];
    }
}
template <class T>
void SeqList<T>::output() {
    //cout << "顺序表当前元素最后位置:" << last << endl;
   cout<<"{"<<" ";
    for (int i = 0; i <= last; i++)
        cout << data[i] << " ";
    cout <<"}"<< endl;
}
template <class T>
SeqList<T> SeqList<T>::operator = (SeqList<T>& L) {
    delete data;
    maxSize = L.Size();
    last = L.Length() - 1;
    T value;
    data = new T[maxSize];
    //if (data == NULL)
    //{
    //    cerr << "存储分配错误!" << endl; exit(1);
   // }
    for (int i = 0; i <= last; i++) {//修改04
        L.getData(i, value);
        data[i] = value;
    }
    return *this;
}
  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值