数据结构与算法——顺序表

第1关 顺序表基本操作

任务描述


本关任务要求针对线性结构的顺序存储方式完成其七个操作函数,分别实现线性表中数据的插入、删除、扩容、查找、访问、遍历和转置等功能。

相关知识


线性表是最基本的数据结构之一,数据元素之间有序连接。线性表可以采用不同的存储形式,顺序表就是其中之一。顺序表的实现方法简单,可以利用高级语言中的数组实现,元素间的逻辑次序与物理次序一致。
线性表存储在一片连续空间里,并通过data、curLength和maxSize三个元素记录线性结构相关属性。

data: 给出线性表存储空间的起始地址
maxSize: 指明线性表存储空间最多可存储的数据元素个数
curLength: 当前线性表里的数据元素个数
顺序表涉及的主要操作如下:

构造函数创建线性表:创建一个最多可存储maxSize个数据元素的顺序存储的线性表,并将其初始状态设置为curLength=0。该操作函数具体定义如下:
SeqList(int maxSize)

析构函数释放线性表存储空间:释放data所指向的用于存储线性表数据元素的存储空间。该操作函数具体定义如下:
~SeqList( )

清空线性表:将当前线性表变为一个空表,只需将curLength设置为0。该操作函数具体定义如下:
void clear( )

获取顺序表当前存储元素个数:返回线性表的当前长度curLength。该操作函数具体定义如下:
int size( )

判断线性表是否为空:若当前线性表是空表,则返回false,否则返回true。该操作函数具体定义如下:
bool empty( )

访问顺序表第i个数据元素:返回位于线性表的第i个数据元素data[i]。该操作函数具体定义如下:
elemType visit(int i)

在顺序表位置i插入元素value: 将value插入data[i]之前。若插入i>curLength 或i<0时,无法插入;若插入i=curLength,则先进行扩容;其余合法位置则正常插入元素value。该操作函数具体定义如下:
void insert(int i, const elemType &value)

删除位置序i处的元素: 删除线性表的i号数据元素。输入参数i范围应在[0,curLength-1]内,否则会产生不能预料的异常或错误。根据用户需要选择是否返回被删除的数据元素值。若无需返回,则该操作函数具体定义如下:
void remove(int i)

查找顺序表中第一次出现值为value的元素位置: 找到线性表中第一个值为value的数据元素的编号。返回值-1表示没有找到,返回值>=0表示该元素位置。该操作函数具体定义如下:
int search(const elemType &value)

删除顺序表中第一个值为x的数据元素: 删除第一个值为x的数据元素,返回该数据元素的编号。如果不存在值为x的数据元素,则返回-1。该操作函数具体定义如下:
int SL_DelValue(SeqList* slist, T x)

遍历顺序表: 打印整个线性表。该操作函数具体定义如下:
void traverse( )

逆置顺序表:将整个顺序表进行逆置存储。该操作函数具体定义如下:
void inverse( )

编程要求


本关任务是实现step1:顺序表/SeqList.h中的insert、remove、resize、search、visit、traverse和inverse七个基本操作。请注意,为了能够更好的比对输出结构,在参考教材代码的同时,请删除所有提示信息的输出! 基本操作具体要求如下:

* insert: 在顺序表的位置i插入结点x, 插入d[i]之前,i的有效范围[0,curLength]
* remove:删除顺序表第i号结点, i的有效范围应在[0,curLength-1],否则会产生异常或错误。
* search:查找第一个值为value的结点,存在则返回结点坐标, 未找到返回-1
* resize:对现有顺序表扩容,扩容后大小为原来的2倍。
* visit:访问顺序表第i号结点, i的有效范围应在[0,curLength-1],否则会产生异常或错误。找到则返回元素值,
* traverse:遍历输出顺序表中元素。
* inverse:逆置顺序表中元素。

输入输出格式请参见后续测试样例
注意:在实现本关任务的七个操作函数时,可调用以完成的其他操作。

测试说明


本关的测试文件是step1:顺序表/main.cpp,负责对实现的代码进行测试。具体代码,可以切换平台代码文件查看。
注意:step1:顺序表/main.cpp的代码不能被修改。

以下是平台对step1:顺序表/main.cpp的测试样例:
样例输入:
4 //输入线性表的长度
0 0 //0号位置出入元素0
1 1 //1号位置出入元素1
2 2 //2号位置出入元素2
3 3 //3号位置出入元素3
2  //设置j值 
0  //设置val值 
样例输出
0 1 2 3 //输出当前线性表的数据元素
0     //输出值为0的元素所在位置
2     //输出j位置元素值
0 1 3  //删除j位置元素后,输出线性表
3 1 0  //逆置当前线性表后输出

开始你的任务吧,祝你成功!

代码

seqList.h

#ifndef _SEQLIST_H_
#define _SEQLIST_H_
#include "List.h"

template <class elemType>          // elemType为顺序表存储的元素类型
class seqList: public List<elemType>
{ 
private:
  elemType *data;              // 利用数组存储数据元素 
    int curLength;              // 当前顺序表中存储的元素个数
    int maxSize;              // 顺序表的最大长度
    void resize();              // 表满时扩大表空间
public:
    seqList(int initSize = 10);        // 构造函数 
  seqList(seqList & sl) ;          // 拷贝构造函数
    ~seqList()  {delete [] data;}      // 析构函数 
    void clear()  {curLength = 0;}      // 清空表,只需修改curLength
  bool empty() const {return curLength==0;}  // 判空
    int size() const {return curLength;}  // 返回顺序表的当前存储元素的个数 
    void insert(int i,const elemType &value);  // 在位置i上插入一个元素value,表的长度增1
    void remove(int i);            // 删除位置i上的元素value,若删除位置合法,表的长度减1 
    int search(const elemType &value) const ;  // 查找值为value的元素第一次出现的位序
    elemType visit(int i) const;      // 访问位序为i的元素值,“位序”0表示第一个元素,类似于数组下标
    void traverse() const ;          // 遍历顺序表
  void inverse();              // 逆置顺序表
};
template <class elemType>
seqList<elemType>::seqList(int initSize) 
{ 
  if (initSize <= 0) throw badSize();
  maxSize = initSize;            
  data = new elemType[maxSize];      // 创建一个大小为maxSize的顺序表
  curLength = 0;              
} 
template <class elemType>
seqList<elemType>::seqList(seqList & sl) { 
    maxSize = sl.maxSize;            
    curLength = sl. curLength;              
    data = new elemType[maxSize];  
    for (int i = 0; i < curLength; ++i)
        data[i] = sl.data[i];    
}
template <class elemType>
void seqList<elemType>::insert(int i, const elemType &value)
{ 
    if (i < 0 || i > curLength) throw outOfRange();  // 合法的插入位置为[0..n]
    if (curLength == maxSize) resize();      // 表满,扩大数组容量
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/

    for (int j = curLength;j > i;j--) {
        data[j] = data[j - 1];
    }

    data[i] = value;
    ++curLength;

    /********** End **********/
}

template <class elemType>
void seqList<elemType>::remove(int i) 
{ 
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/
  
    if (i < 0 || i > curLength - 1) {
        throw outOfRange();
    }

    for (int j = i;j < curLength - 1;j++){
        data[j] = data[j+1];
    }

    --curLength;

    /********** End **********/
}

template <class elemType>
void seqList<elemType>::resize()
{ 
    elemType *p = data;              // p指向原顺序表空间
    maxSize *= 2;                  // 表空间扩大2倍
    data = new elemType[maxSize];          // data指向新的表空间
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/
   
    for (int i = 0;i < curLength; ++i) {
        data[i] = p[i];
    }

    delete [] p;

    /********** End **********/
}

template<class elemType>
int seqList<elemType>::search(const elemType & value) const
{
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/
   
   for (int i = 0;i < curLength;i++) {
       if (value == data[i]) {
           return i;
       }

       return -1;
   }

    /********** End **********/              
}

template<class elemType>
elemType seqList<elemType>::visit(int i) const
{
  if (i < 0 || i > curLength-1 ) throw outOfRange();// 合法的访问位置为[0..n-1] 
  // 请在这里补充代码,完成本关任务
    /********** Begin *********/

    return data[i];
 
    /********** End **********/
}

template<class elemType>
void seqList<elemType>::traverse()const
{
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/

    if(empty()) {
        cout << endl;
    }
    else {
        for (int i = 0;i < curLength;i++) {
            cout << data[i] << " ";
        }
        cout << endl;
    }

    /********** End **********/          
}

template<class elemType>
void seqList<elemType>::inverse() 
{
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/

    elemType tmp;
    for(int i = 0;i < curLength/2;i++) {
        tmp = data[i];
        data[i] = data[curLength-i-1];
        data[curLength-i-1] = tmp;
    }

    /********** End **********/
}

#endif

第2关 合并两个顺序表

任务描述


1.按要求生成顺序表1和顺序表2。
接收由键盘输出的两组数据,第1组数据按录入顺序生成顺序表1,第2组数据按录入的逆序生成顺序表2。
例如,若第一组数据依次录入0 1 2,则顺序表1的0-2号位置依次为 0 1 2。若第二组数据依次录入为0 1 2,则顺序表2的0-2号位置依次为 2 1 0。
2.合并顺序表2到顺序表1中,即顺序表2的元素依次插入到顺序表1尾元素后,打印合并后的顺序表1。

相关知识


为了完成本关任务,你需要掌握:1.顺序表的存储;2.顺序表的基本操作。
本关可调用第1关中已实现的所有顺序表基本操作,请注意头文件的调用。

测试说明


平台会对你编写的代码进行测试:

4 //输入第一个表的长度
0 2 4 6//依次输入顺序表1元素
5  //输入第二个表的长度
1 3 5 7 9  //依次输入顺序表2元素
预期输出:
归并表为:0 2 4 6 9 7 5 3 1

代码

/*
合并两个顺序表:
1.按要求生成顺序表1和顺序表2。
接收由键盘输出的两组数据,第1组数据按录入顺序生成顺序表1,第2组数据按录入的逆序生成顺序表2。
例如,若第一组数据依次录入0 1 2,则顺序表1的0-2号位置依次为 0 1 2。若第二组数据依次录入为0 1 2,则顺序表2的0-2号位置依次为 2 1 0。
2.合并顺序表2到顺序表1中,即顺序表2的元素依次插入到顺序表1尾元素后,打印合并后的顺序表1。

提示:本关可调用第1关中已实现的顺序表基本操作,请注意头文件的调用。
*/

#include <iostream>    
#include <cstdlib>
using namespace std;     
#include "seqList.h"
#include "List.h"

int main()   
{   

    seqList<int>* sl_1;
    seqList<int>* sl_2;
    sl_1 = new seqList<int>();
    sl_2 = new seqList<int>();

    int val;
    int n;

    cin >> n;
    for (int i = 0;i < n;i++){
        cin >> val;
        sl_1 -> insert(i,val);
    }

    cin >> n;
    for (int i = 0;i < n;i++){
        cin >> val;
        sl_2 -> insert(i,val);
    }

    sl_2 -> inverse();

    n = sl_2 -> size();
    int l = sl_1 -> size();
    for (int i = 0;i < n;i++){
        val = sl_2 -> visit(i);
        sl_1 -> insert(l + i,val);
    }

    sl_1 -> traverse();

}

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小柒_02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值