數據結構-C++實現(一):數組鏈表

數據結構C++實現第一發,主要有幾部分構成,分別是一個抽象類LinearList.h、數組鏈表的頭文件ArrayList.h以及main.cpp源文件。

LinearList.h文件具體信息如下:

#ifndef INC_01_ARRAYLIST_LINEARLIST_H
#define INC_01_ARRAYLIST_LINEARLIST_H

#include 
template 
class LinearList {
public:
    virtual ~LinearList() {};
    virtual bool empty() const = 0;
    virtual int size() const = 0;
    virtual T& get(int index) const = 0;
    virtual int indexof(const T& theElement) const = 0;//first pos
    virtual void erase(int index) = 0;
    virtual void insert(int index, const T& theElement) = 0;
    virtual void output(std::ostream& out) const = 0;
};
ArrayList.h文件如下:

#ifndef INC_01_ARRAYLIST_ARRAYLIST_H
#define INC_01_ARRAYLIST_ARRAYLIST_H

#include "LinearList.h"
#include 
#include 
using namespace std;

template  void resizeCapacity(T*& a,int oldCapacity, int newCapacity);

template 
class ArrayList :public LinearList {
public:
    //iterator
    class iterator{
    public:
        //
        typedef bidirectional_iterator_tag iterator_category;
        typedef T value_type;
        typedef ptrdiff_t difference_type;
        typedef T* pointer;
        typedef T& reference;
        //construct
        iterator(T* thepos=0) { pos = thepos;}
        //operator
        T& operator*() const { return *pos;}
        T* operator->() const { return &*pos;}
        iterator& operator++()
            { ++pos; return *this;}
        iterator& operator++(int)
            { iterator old = *this; ++pos; return old;}
        iterator& operator--()
            { --pos; return *this;}
        iterator& operator--(int)
            { iterator old = *this; --pos; return old;}
        bool operator!=(const iterator rhl) const
            { return pos != rhl.pos;}
        bool operator==(const iterator rhl) const
            { return pos == rhl.pos;}
    protected:
        T* pos;
    };
    iterator begin(){ return iterator(element);}
    iterator end(){ return iterator(element+listsize);}
public:
    //construct copy destroy
    //ArrayList(int initCapacity = 10);
    ArrayList(int initCapacity = 10, int size = 0);
    ArrayList(const ArrayList&);
    ~ArrayList() { delete [] element;};
    //ADT methods
    bool empty() const override { return listsize==0;}
    int size() const override { return listsize;}
    T& get(int index) const override;
    int indexof(const T& theElement) const override ;
    void erase(int index) override ;
    void insert(int index, const T& theElement) override ;
    void output(ostream& out) const override ;
    //other
    int capacity() const { return arrayCapacity;}
    void set(int index, T var);
    void trimToSize();
    void setSize(int setSize);
    T& operator[](int);
    bool const operator==(const ArrayList &);
    bool const operator!=(const ArrayList &);
    bool const operator<(const ArrayList &);

protected:
    void checkIndex(int index) const;
    T* element;
    int arrayCapacity;
    int listsize;
    int addsize;
};
template 
ostream& operator<<(ostream& out,ArrayList& al);


template 
ArrayList::ArrayList(int initCapacity,int size)
{
    if (initCapacity < 0 || size<0)
    {
        std::cerr << "----!Initdata error!----" << std::endl;
    }
    arrayCapacity = initCapacity;
    listsize = 1;
    element = new T[arrayCapacity];
    addsize = size;
}

template 
ArrayList::ArrayList(const ArrayList &rhl)
{
    arrayCapacity = rhl.arrayCapacity;
    listsize = rhl.listsize;
    delete [] element;
    element = new T[arrayCapacity];
    copy(rhl.element,rhl.element+listsize,element);
}

template 
void ArrayList::checkIndex(int index) const
{
    if (index < 0 || index >= listsize)
    {
        cerr << "----!Index outrange!----" << endl;
    }
}

template 
T &ArrayList::get(int index) const
{
    checkIndex(index);
    return element[index];
}

template 
int ArrayList::indexof(const T &theElement) const
{
    int pos = find(element,element+listsize,theElement)-element;
    if (pos==listsize)
        return -1;
    return pos;
}

template 
void ArrayList::erase(int index)
{
    checkIndex(index);
    copy(element+index+1,element+listsize,element+index);
    element[--listsize].~T();
    if(arrayCapacity>4*listsize)
    {
        for(int i = 4*listsize;i
void ArrayList::insert(int index, const T &theElement)
{
    ++listsize;
    checkIndex(index);
    if(listsize>=arrayCapacity)
    {
        if(addsize==0)
        {
            resizeCapacity(element, arrayCapacity, arrayCapacity * 2);
            arrayCapacity *= 2;
        }
        else
        {
            resizeCapacity(element, arrayCapacity, arrayCapacity + addsize);
            arrayCapacity += addsize;
        }
    }
    copy(element+index,element+listsize-1,element+index+1);
    element[index] = theElement;
}

template 
void ArrayList::output(ostream &out) const
{
    copy(element,element+listsize,ostream_iterator(out," "));
}

template 
void ArrayList::set(int index, T var)
{
    checkIndex(index);
    element[index] = var;
}

template 
void ArrayList::trimToSize()
{
    int edge = max(1,listsize);
    for(int i = edge+1;i
void ArrayList::setSize(int setSize)
{
    if(setSize= listsize !----";
    if(setSize<=arrayCapacity)
    {
       for(int i = setSize+1;i
T &ArrayList::operator[](int index)
{
    checkIndex(index);
    return element[index];
}

template 
bool const ArrayList::operator==(const ArrayList &rhl)
{
    if(listsize!=rhl.listsize)
        return 0;
    else
    {
        for(int i = 0;i
bool const ArrayList::operator!=(const ArrayList &rhl)
{
    return !(*this==rhl);
}

template 
bool const ArrayList::operator<(const ArrayList &rhl)
{
    int index = min(listsize,rhl.listsize);
    for(int i = 0;i=rhl.element[i])
            return 0;
    }
    if(listsize
ostream &operator<<(ostream &out, ArrayList &al)
{
    al.output(out);
    return out;
}

template 
void resizeCapacity(T*& a,int oldCapacity, int newCapacity)
{
    if(newCapacity<0)
    {
        cerr << "----!newCapacity must be>=0!----";
    }
    T* tmp = new T[newCapacity];
    int num = min(oldCapacity,newCapacity);
    copy(a,a+num,tmp);
    delete [] a;
    a = tmp;
}

#endif //INC_01_ARRAYLIST_ARRAYLIST_H
簡單的測試如下:

#include <iostream>
#include "ArrayList.h"

template <typename T>
void resizeLength2D(T**& a,int oldRow,int oldCol,int newRow,int newCol)
{
    T** tmp = new T*[newRow];
    int r = min(oldRow,newRow);
    int c = min(oldCol,newCol);
    for(int i = 0;i<newRow;i++)
        tmp[i] = new T[newCol];
    for(int i = 0;i<r;i++)
    {
        copy(a[i],a[i]+c,tmp[i]);
    }
    for(int i = 0;i<oldRow;i++)
        delete [] a[i];
    delete [] a;
    a = tmp;
}


int main()
{

    ArrayList<int> ia(5);
    ia.insert(0,1);ia.insert(0,2);ia.insert(0,3);ia.set(3,0);
    std::cout << ia << std::endl;
    for(auto i = ia.begin();i!=ia.end();++i)
        std::cout << *i << " ";
    ArrayList<int> ib(ia);
    cout << (ia!=ib) << endl;

    /*
    //test resizelength2d
    int** a;
    a = new int* [3];
    for(int i =0;i<3;i++)
        a[i] = new int[3];
    resizeLength2D(a,3,3,4,4);
     */
    return 0;
}
這裏我對ArrayList類裏的函數做一些說明;

element代表存儲元素,arrayCapacity表示容量大小,listsize表示數組實際大小,capacity是要比listsize大的,相當於留有一些裕量,這一點和stl的vector類似。addsize表示listsize達到一定大小後,單次對capacity擴容的大小。checkIndex()函數後續用於檢測索引值是否有效。

然後是public部分,內嵌類iterator爲數組鏈表定義了迭代器,begin()以及end()的設置與stl的容器相同。

構造函數ArrayList()中有兩個參數,一個代表預先給capacity的大小,另一個設置的是單次擴容值,如果缺省,則默認每次擴容時將capacity翻倍。析構函數,清空element元素。

接下來時覆寫抽象類成員函數的部分,empty()函數返回當前數組是否爲空,爲空返回true;size()函數返回當前的數組大小,這裏的大小時listsize,不是容量。get()函數返回指定索引處的值;indexof()返回目標值的第一個索引,若目標不在數組中,返回-1;erase()擦除指定index的數據,相應更改數組大小與容量;insert()在指定索引處插入值;output()函數將數組元素依次輸出;

接下來是非構造拷貝析構函數、同時也不是覆寫的成員函數。capacity()函數返回容量值,set()設定指定索引處的值;trimToSize()函數將容量設置爲與listsize大小一i樣;setSize()函數使得數組大小等於指定大小。

最後是幾個運算符的重載,應該能看懂。另外,還有一個輸出流的運算符的重載,定義在類外。

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