線性表——數組描述

抽象數據類型(abstract date tpye, ADT)
1.抽象數據類型linearList
C++支持兩種類——抽象類和具體類。一個抽象類包含沒有實現的代碼的成員函數。這樣的成員函數成爲“虛函數(pure virtual function)”.
具體類是沒有虛函數的類。只有虛函數纔可以實例化(只能對具體類建立實例或對象)。但是可以建立抽象類的對象指針。

一個線性表的抽象類:

template<class T>
class linearList
{
    public:
        virtual ~linearList() {
        };
        //線性表爲空,返回true 
        virtual bool empty() const  = 0;
        //返回線性表的元素個數 
        virtual int size() const = 0;
        //返回索引爲theIndex的元素 
        virtual T& get(int theIndex) const = 0;
        //返回元素theElement第一次出現的索引 
        virtual int indexof(const T& theElement) const = 0;
        //刪除索引爲theIndex的元素 
        virtual void erase(int theIndex) = 0;
        //將元素theElement插入索引爲theIndex的位置 
        virtual void insert(int theIndex, const T& theElement) = 0;
        //線性表插入輸出流out 
        virtual void output(ostream& out) const = 0;
};

一個抽象類的派生類,只有實現了基類的所有純虛函數纔是具體類,否則依然是抽象類不能實例化。

抽象類linearList的派生類arrayList(具體類) :

template<class T>
class arrayList : public linearList<T>
{
    protected:
        T* element; //存儲線性元素的一維數組 
        int arrayLength;    //一維數組的容量 
        int listSize;   //線性表的元素個數 
        //索引theIndex無效,則拋出異常 
        void checkIndex(int theIndex) const;

    public:
        //構造函數,複製函數和析構函數
        arrayList(int initialCapacity = 10);
        arrayList(const arrayList<T>&);
        ~arrayList()
        {
            delete [] element;
        }

        //DAT方法
        bool empty() const
        {
            return listSize == 0;
        } 
        int size() const
        {
            return listSize;    
        }
        T& get(int theIndex) const;
        int indexof(const T& theElement) const;
        void erase(int theIndex);
        void insetr(int theIndex, const T& theElement);
        void output(ostream& out) const;

        //其他方法
        int capacity() const
        {
            return arrayLength;
        }
};

類的具體實現:

template<class T>
arrayList<T>::arrayList(int initialCapacity)
{
    if(initialCapacity < 1)
    {
        ostringstream s;
        s << "初始容量 = " << initialCapacity << "必須大於零";   
        //throw illegalParameterValue(s.str());
    }

        arrayLength = initialCapacity;
        element = new T[arrayLength];
        listSize = 0;   
}

template<class T>
arrayList<T>::arrayList(const arrayList<T>& theList)
{
    arrayLength = theList.arrayLength;
    listSize = theList.listSize;
    element = new T[arrayLength];
    copy(theList.elemet, theList.element + listSize, element);
}

template<class T>
T& arrayList<T>::get(int theIndex) const
{
    checkIndex(theIndex);
    return element(theIndex); 
} 

template<class T>
int arrayList<T>::indexof(const T& theElement) const
{
    int theIndex = (int) (find(element, element + listSize, theElement) - element);

    if(theIndex == listSize)
    {
        return -1;
    }
    else
    {
        return theIndex;
    }
}

template<class T>
void arrayList<T>::erase(int theIndex)
{
    //如果引索不存在,則拋出異常 
    checkIndex(theIndex);

    //引索存在,向前移動引索大於theIndex的元素
    copy(element + theIndex + 1, element + listSize, element + theIndex);
    element[--listSize].~T();  //調用析構函數 
}

template<class T>
void arrayList<T>::insetr(int theIndex, const T& theElement) 
{
    if(theIndex < 0 || theIndex > listSize)
    {
        ostringstream s;
        s << "索引 = " << theIndex << "索引大小 = " << listSize;
        throw illeaglIndex(s.str());    
    }

    //有效引索,確定數組是否已滿
    if(listSize == arrayLength) //數組長度空間已滿,數組長度倍增 
    {
        changeLength1D(element, arrayLength, 2 * arrayLength) ;
        arrayLength *= 2;
    } 

    //把元素向右移動一個位置
    copy_backward(element + theIndex, element + listSize,
                  element + theIndex + 1); 
    element[theIndex] = theElement;
    listSize++;
} 

template<class T>
void arrayList<T>::output(ostream& out) const
{
    copy(element, element + listSize, ostream_iterator<T>(cout, " "));
}

template<class T>
void arrayList<T>::checkIndex(int theIndex) const
{
    //確定索引theIndex在 0 到 listSize 之間
    if(theIndex < 0 || theIndex >= listSize)
    {
        ostringstream s;
        s << "索引 = " << theIndex << "索引大小 = " << listSize;
        throw illeaglIndex(s.str());    
    }
}

//改變一個一維數組長度
template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
    if(newLength < 0)
        cout<< "錯誤" <<endl; 

    T* temp = new T[newLength]; //新數組
    int number = min(oldLength, newLength);
    copy(a, a + number, temp);
    delete [] a;
    a = temp; 
}

庫定義了三種類:istringstream、ostringstream和stringstream,分別用來進行流的輸入、輸出和輸入輸出操作。

發佈了47 篇原創文章 · 獲贊 24 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章