[数据结构]线性表之顺序表的类模板实现

LinearList.h抽象基类:

#ifndef LINEARLIST
#define LINEARLIST
//线性表的抽象基类

template<class T>
class LinearList
{
public:
    LinearList(){};//如果派生类不需要向基类构造函数传递参数,则就会调用基类默认构造函数,所以,要么不写,要么就自己写默认构造函数。
    ~LinearList(){};//派生类也会调用基类的析构函数。

    virtual int Size()const=0;
    virtual int Length()const=0;
    virtual int Search(T& x)const=0;
    virtual int Locate(int i)const=0;
    virtual bool getData(int i,T& x)const=0;
    virtual void setData(int i,T& x)=0;
    virtual bool Insert(int i,T& x)=0;
    virtual bool Remove(int i,T& x)=0;
    virtual bool IsEmpty()const=0;
    virtual bool IsFull()const=0;
    virtual void Sort()=0;
    virtual void input()=0;
    virtual void output()=0;

    //virtual LinearList<T>& operator=(LinearList<T>& L)=0; //在继承类中形参不同,故不能声明纯虚函数,否则继承类无法定义对象。
};

#endif

实现及测试文件:

/////////////////////////
#include"LinearList.h"
#include <iostream>
#include <cstdlib>
using namespace std;

const int defaultSize=100;
template<class T>
class SeqList:public LinearList<T>
{
protected:
    T* data;
    int maxSize;
    int last;
    void reSize(int newSize);
public:
    SeqList(int sz=defaultSize):data(new T[sz]),maxSize(sz),last(-1){}
    SeqList(const SeqList<T>& L);
    ~SeqList(){delete []data;}

    int Size()const{return maxSize;}
    int Length()const{return last+1;}
    int Search(T& x)const;
    int Locate(int i)const;
    bool getData(int i,T& x)const{if(i>0&&i<=last+1){x=data[i-1];return true;}else return false;}
    void setData(int i,T& x){if(i>0&&i<=last+1)data[i-1]=x;else {cerr<<"err"<<endl;exit(1);}}
    bool Insert(int i,T& x);
    bool Remove(int i,T& x);
    bool IsEmpty()const{return (last==-1)?true:false;}
    bool IsFull()const{return (last==maxSize-1)?true:false;}
    void Sort(){};//未提供具体的实现。
    void input();
    void output();

    SeqList<T>& operator=(SeqList<T>& L);
};

template<class T>
SeqList<T>::SeqList(const SeqList<T>& L)
{
    maxSize=L.maxSize;
    last=L.last;
    data=new T[maxSize];
    if(data==NULL){
        cerr<<"err"<<endl;
        exit(1);
    }
    T value;
    for(int i=0;i<=last;++i){
        L.getData(i+1,value);setData(i,value);
    }
}

template<class T>
SeqList<T>& SeqList<T>::operator=(SeqList<T>& L)
{
    maxSize=L.maxSize;
    last=L.last;
    data=new T[maxSize];
    if(data==NULL){
        cerr<<"err"<<endl;
        exit(1);
    }
    T value;
    for(int i=0;i<=last;++i){
        L.getData(i+1,value);setData(i,value);
    }
    return *this;
}

template<class T>
void SeqList<T>::reSize(int newSize)
{
    if(newSize<=0){
        cerr<<"err"<<endl;
        exit(1);
    }
    if(newSize!=maxSize){
        maxSize=newSize;
        T* ptr=new T[maxSize];
        if(ptr==NULL){
            cerr<<"err"<<endl;
            exit(1);
        }
        T* srcptr=data;
        T* destptr=ptr;
        n=last+1;
        while(n--)
            *destptr++=*srcptr++;

        delete []data;
        data=destptr;
    }
}

template<class T>
int SeqList<T>::Search(T& x)const
{
    for(int i=0;i<=last;++i)
        if(data[i]==x)
            return i+1;
    return 0;
}

template<class T>
int SeqList<T>::Locate(int i)const
{
    if(i>=1&&i<=last+1)
        return i;
    else
        return 0;
}

template<class T>
bool SeqList<T>::Insert(int i,T& x)
{
    if(i<0||i>last+1)
        return false;
    if(IsFull())
        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(i<=0||i>last+1)
        return false;
    if(IsEmpty())
        return false;
    x=data[i-1];
    for(int j=i;j<=last;++j)
        data[j-1]=data[j];
    --last;
    return true;
}

template<class T>
void SeqList<T>::input()
{
    cout<<"PLZ input element number-1:"<<endl;
    while(1){
        cin>>last;
        if(last<=maxSize-1) break;
        cout<<"err! repeat."<<endl;
    }
    for(int i=0;i<=last;++i)
        cin>>data[i];
}

template<class T>
void SeqList<T>::output()
{
    for(int i=0;i<=last;++i)
        cout<<"#"<<i+1<<":"<<data[i]<<"  ";
    cout<<endl;
}

int main(int argc, char* argv[])
{

    SeqList<int> s(10);
    int val=2;
    s.input();
    s.output();
    cout<<"size: "<<s.Size()<<endl;
    cout<<"Length: "<<s.Length()<<endl;
    cout<<"Search: "<<s.Search(val)<<endl;
    cout<<"Locate: "<<s.Locate(2)<<endl;

    int val1,val2=99;
    s.getData(2,val1);
    cout<<"getData: "<<val1<<endl;
    s.setData(2,val2);
    s.getData(2,val1);
    cout<<"setData: "<<val1<<endl;

    s.Insert(0,val2);//插入是失败的,因为最初顺序表示满的。
    s.output();
    s.Remove(2,val1);
    s.output();

    cout<<"IsEmpty(): "<<s.IsEmpty()<<endl;
    cout<<"IsFull: "<<s.IsFull()<<endl;

    system("pause");
    return 0;
}

运行结果:

PLZ input element number-1:

9

0 1 2 3 4 5 6 7 8 9

#1:0  #2:1  #3:2  #4:3  #5:4  #6:5  #7:6  #8:7  #9:8  #10:9

size: 10

Length: 10

Search: 3

Locate: 2

getData: 1

setData: 99

#1:0  #2:99  #3:2  #4:3  #5:4  #6:5  #7:6  #8:7  #9:8  #10:9

#1:0  #2:2  #3:3  #4:4  #5:5  #6:6  #7:7  #8:8  #9:9

IsEmpty(): 0

IsFull: 0

请按任意键继续. . .

要点分析:

1.抽象基类中没有数据成员,只有成员函数的接口,且都是纯虚函数。所以继承类中要实现全部的接口功能,把抽象基类覆盖掉,而且接口要完全相同。

2.抽象基类可以不提供构造和析构函数,这样在派生类中调用系统默认生成的抽象基类构造函数和析构函数。或者你自己定义抽象基类默认的构造函数

和析构函数,也可定义带参数的构造和析构函数,让派生类调用。派生类是必须要调用基类的构造函数和析构函数的,或者显示调用或者隐式调用。

构造函数先调用基类的在调用派生类的,析构函数先调用派生类的在调用基类的。

3.好处是为了利用多态机制。方便使用。

4.只是理论模型,要用于实际还得仔细修改。

时间: 2024-11-01 11:13:56

[数据结构]线性表之顺序表的类模板实现的相关文章

《数据结构》复习之线性表(顺序表和链表)

线性表的概念 线性表的比较 线性表的数据结构 顺序表的算法操作 双链表的补充 总结 1.线性表的概念 线性表的存储结构有顺序存储结构和链式存储结构两种.前者成为顺序表,后者称为链表. 顺序表: 顺序表就是把线性表中的所有元素按照其逻辑顺序,一次存储到从指定的存储 位置开始的一块连续的存储空间中,如下图所示. 链表 在链表的存储中,每一个节点不仅包含所存元素本身的信息,还包含元素之间的逻辑关系的信息,即前驱节点包含后继节点的地址信息,这样就可以通过前驱节点中的地址信息方便地找到后继节点的位置,如下

[C++] 数据结构(C):线性表之顺序表

1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + Status GetElement(SeqList L, int i, ElementType &e) (按位)取值  + int LocateElement(SeqList L, ElementType e) (按值)查找  + Status ListInsert(SeqList &L, int i, ElementType e) (按位)插入  + Status ListDelet

数据结构-线性表_顺序表

进入大学一年了,今日终于有勇气写写随笔并展示出来了. 如有不足之处,请大家指正. 今日我想写的就是我对数据结构-线性表_顺序表的理解. 不BB了,进入正题!!!!! 数据结构中的逻辑结构分为线性结构和非线性结构,而线性表就属于线性结构. 线性结构是 n 个数据元素的有序(次序)集合,它有下列几个特征: 集合中必存在唯一的一个 "第一个元素": 集合中必存在唯一的一个 "最后的元素": 除最后元素之外,其它数据元素均有唯一的 "后继": 除第一元素

数据结构-02 _用顺序表解决线性表的编程问题

看到这个标题,相必最先应该只到什么是顺序表,什么是线性表. 线性表(linear list):由n(n>=0)个相同的数据类型的数据元素(结点)a0,a1,a2,...an-1 组成的有限序列. 顺序表:把线性表的结构按照逻辑顺序存放在一组地址连续的存储单元里,用这种方式存储的线性表简称顺序表. 线性表的基本操作: 1.初始化操作 2.插入操作:InsertNode(T a,int i) 在线性表的第i个位置插入一个值为a的新元素,使得原序号为i,i+1,...,n 的数据元素的序号变成i+1,

【算法和数据结构】_17_小算法_线性结构:顺序表

/* 本程序用来测试数据结构中的线性结构:顺序表 */ #include <stdio.h> #include <stdlib.h> #define LINEAR_MAX_SIZE 64 struct LinearList { int* List; //顺序表指针 unsigned short int ListLen; //顺序表最大的元素个数 unsigned short int CurrentLen; //顺序表当前元素的个数 }; typedef struct LinearL

数据结构Java实现02----线性表与顺序表

[正文] 本节内容: 线性结构 线性表抽象数据类型 顺序表 顺序表应用 一.线性结构: 如果一个数据元素序列满足: (1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素: (2)第一个数据元素没有前驱数据元素: (3)最后一个数据元素没有后继数据元素. 则称这样的数据结构为线性结构. 二.线性表抽象数据类型: 1.线性表抽象数据类型的概念: 线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合. 数据集合: 可以表示为a0,a1,a2,...a

java数据结构与算法之顺序表与链表深入分析

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 ??数据结构与算法这门学科虽然在大学期间就已学习过了,但是到现在确实也忘了不少,因此最近又重新看了本书-<数据结构与算法分析>加上之前看的<java数据结构>也算是对数据结构的进一步深入学习了,于是也就打算

数据结构C#版笔记--顺序表(SeqList)

线性结构(Linear Stucture)是数据结构(Data Structure)中最基本的结构,其特征用图形表示如下: 即:每个元素前面有且只有一个元素(称为"前驱"),同样后面有且只有一个元素(称为"后继")--注:起始元素的前驱认为是空,末尾元素的后继认为也是空,这样在概念上就不冲突了. 线性表(List)是线性结构的一种典型实现,它又可以分为:顺序表(SeqList)和链表(LinkList)二大类. 顺序表(SeqList)的基本特征为:元素在内部存储时

数据结构Java实现01----线性表与顺序表

一.线性结构: 如果一个数据元素序列满足: (1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素: (2)第一个数据元素没有前驱数据元素: (3)最后一个数据元素没有后继数据元素. 则称这样的数据结构为线性结构. 二.线性表抽象数据类型: 1.线性表抽象数据类型的概念: 线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合. 数据集合: 可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型. 操作集合包括如下: 1

线性链表之顺序表

顺序表中数据元素的存储地址是其序号的线性函数,只要确定了存储顺序表的起始地址(即 基地址),计算任意一个元素的存储地址的时间是相等的,具有这一特点的存储结构称为[随机存储]. 使用的基本数据结构:数组 特点:顺序存取,随机访问. /* Name: SeqList Copyright: 1.0 Author: Johnny Zen Date: 04/06/17 21:51 Description: 线性链表之顺序表 *//* Chinese:顺序(线性)表 English:SeqList*/#in