C++数据结构----顺序表

150 阅读3分钟

 线性表-----处理线性结构的数据结构

线性结构

A_{0}A_{1}A_{2}.....A_{i-1}A_{i}A_{i+1}....A_{n-1}

  • 除了A_{0},A_{n-1}​外,每个元素都有它的前趋和后继
  • 每个元素A_{i}​,它的前驱是A_{i-1}​,它的后继是A_{i+1}
  • A_{0}​只有后继,没有前驱;A_{n-1}​只有前驱,没有后继

线性表的基本操作

  • 创建一个空的线性表create() ----C++中一般用构造函数解决
  • 清除一个线性表clear() ----删除线性表的所有数据元素
  • 求线性表的长度Length() ----也就是求目前线性表中的元素个数

增加insert(i,x)

  • 在线性表第i个位置插入元素x----a_{0}...a_{i-1}a_{i}...\rightarrow a_{0}...a_{i-1}xa_{i}...

删除remove(i)

  • 删除线性表第i个位置的元素

  • 查索引search(x) -----给定元素x,查找是否存在,存在返回x的位置
  • 访问元素visit(i) -----给定索引,访问该位置的元素
  • 遍历元素traverse() -----顺序访问元素的所有位置

线性表的抽象类 

template<class elemType>
class list{
    public:
    //少了create函数,因为在具体实现时,构造函数可以满足该功能
    virtual void clear()=0;
    virtual int Length() const=0;
    virtual void insert(int i,const elemType& x)=0;
    virtual void remove(int i)=0;
    virtual int search(const elemType& x) const=0;
    virtual elemType visit(int i) const=0;
    virtual void traverse() const=0;
    virtual ~list(){};//析构函数,delete指针,防止内存泄露
};

注意,这里基本操作加上virtual原因,是希望其继承类必须实现该函数功能

有关查的操作,如果不希望改变或者不能改变传参的值,要加上const关键字

顺序表-----线性表的顺序实现 

 用动态数组去实现

数据成员----

  • 线性表第一个元素的起始地址的指针----data
  • 数组规模maxsize----也就是目前的数组容量上限
  • 数组中当前的元素个数----curLength

顺序表类

template<class elemType>
class seqList:public list<elemType>{
    private:
    elemType* data;
    int maxsize;
    int curLength;
    public:
    seqList(int initSize=10);//构造函数,默认初始化长度为10
    void clear(){ curLength=0;}
    int Length() const{ return curLength;}
    void insert(int i,const elemType& x);
    void remove(int i);
    int search(const elemType& x) const;
    elemType visit(int i) const{
        if(i<curLength) return data[i];
    }
    void traverse() const;
    ~seqList(){delete[] data;}
};

为了解决插入元素的容量不足问题,即---curLength==maxsize

需要做一个隐式扩容操作,即容量满后,私有函数去进行扩容,用户无需知道,给用户造成数组永远不会满的假象

private  void doublespace();

具体实现---保存在seqList.h文件

#ifndef MY_seqlist
#define MY_seqlist
#include"list.h"
template<class elemType>
class seqList:public list<elemType>{
    private:
    elemType* data;
    int maxsize;
    int curLength;
    void doublespace();
    public:
    seqList(int initSize=10);//构造函数,默认初始化长度为10
    void clear(){ curLength=0;}
    int Length() const{ return curLength;}
    void insert(int i,const elemType& x);
    void remove(int i);
    int search(const elemType& x) const;
    elemType visit(int i) const{
        return data[i];
    }
    void traverse() const;
    ~seqList(){delete[] data;}
};
//私有扩容操作
template<class elemType>
void seqList<elemType>::doublespace(){
       elemType* tmp=data;
       maxsize*=2;
       data=new elemType[maxsize];
       for(int i=0;i<curLength;i++){
           data[i]=tmp[i];
       }
       delete[] tmp;
}
//构造函数
template<class elemType>
seqList<elemType>::seqList(int initSize){
    data =new elemType[initSize];
    maxsize=initSize;
    curLength=0;
}
//查元素
template<class elemType>
int seqList<elemType>::search(const elemType& x) const{
    int i;
    for(i=0;i<curLength&&x!=data[i];i++);
    if(i==curLength){
        return -1;
    }
    else{
        return i;
    }
}
//插入
template<class elemType>
void seqList<elemType>::insert(int i,const elemType& x){
    //是否需要扩容?
    if(curLength==maxsize){
        doublespace();
    }
    //当前第i个位置直到最后的元素右移一位,把第i个位置空出来
       for(int j=curLength;j>i;j--){
             data[j]=data[j-1];
       }
    //x放到当前索引位置i,然后表长+1
       data[i]=x;
       ++curLength;
}
//删除
template<class elemType>
void seqList<elemType>::remove(int i){
     for(int j=i;j<curLength-1;j++){
         data[j]=data[j+1];
     }
     --curLength;
}
//遍历
#include<iostream>
using namespace std;
template<class elemType>
void seqList<elemType>::traverse() const{
    for(int i=0;i<curLength;i++){
         cout<<data[i]<<",";
    }
    cout<<endl;
}
#endif

 插入函数也可以这样写

template<class elemType>
int seqList<elemType>::search(const elemType& x) const{
    int i;
   /* for(i=0;i<curLength&&x!=data[i];i++);
    if(i==curLength){
        return -1;
    }
    else{
        return i;
    }*/
    for(int i=0;i<curLength;i++){
        if(data[i]==x) break;
    }
    if(i==curLength){
        return -1;
    }
    else{
        return i;
    }
}

主程序的测试用例程序---maintest.cpp

#include"list.h"
#include<iostream>
using namespace std;
int main(){
    seqList<int> seq;
    seq.insert(0,19);
    seq.insert(1,18);
    seq.insert(2,88);
    seq.insert(3,6);
    seq.traverse();
    cout<<seq.Length()<<endl;
    cout<<seq.visit(2)<<endl;
    cout<<seq.search(6)<<endl;
    seq.remove(2);
    seq.traverse();
   // seq.~seqList();
    return 0;
}

最初的list.h文件

#ifndef MY_list
#define MY_list
template<class elemType>
class list{
    public:
    //少了create函数,因为在具体实现时,构造函数可以满足该功能
    virtual void clear()=0;
    virtual int Length() const=0;
    virtual void insert(int i,const elemType& x)=0;
    virtual void remove(int i)=0;
    virtual int search(const elemType& x) const=0;
    virtual elemType visit(int i) const=0;
    virtual void traverse() const=0;
    virtual ~list(){};//析构函数,delete指针,防止内存泄露
};
#include"seqList.h"
#endif

\