線性表-----鏈式描述(單鏈表)

線性表的抽象類實現適用於線性表和鏈表:函數

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

};

這是對鏈表節點結構的實現:this

//鏈表節點定義
template<class T>
struct chainNode
{
    //數據成員
    T element;
    chainNode<T> *next;

    //方法
    chainNode(){}
    chainNode(const T& element)
    {
        this->element = element;
    }
    chainNode(const T& element,chainNode<T>* next)
    {
        this->element = element;
        this->next = next;
    }
};

對線性表抽象類的實現:指針

//鏈表結構定義
template<class T>
class chain:public linearList<T>
{
public:
    //構造函數,複製構造函數和析構函數
    chain(int initialCapacity = 10);
    chain(const chain<T>&);
    ~chain();

    //抽象類中的函數
    bool empty()const;
    int size() const;
    T& get(int theIndex) const;
    int indexOf(const T &theElement) const;
    void erase(int theIndex) const;
    void insert(int theIndex, const T &theElement) const;
    void output(ostream &out) const;

protected:
    void checkIndex(int theIndex) const;//檢查索引是否有效
    chainNode<T>* firstNode;//指向鏈表第一個節點的指針
    int listSize;//線性表元素個數
};

鏈表具體類中全部函數的具體實現:code

/*
 * 鏈表結構中各類函數的具體實現
*/
//構造函數
template<class T>
chain<T>::chain(int initialCapacity)
{
    if(initialCapacity > 0)
    {
        firstNode = NULL;
        listSize = 0;
    }else
    {
        cout<<"初始化的數據量必須大於0"<<endl;
    }
}
//複製構造函數
template<class T>
chain<T>::chain(const chain<T>& theList)
{
    listSize = theList.listSize;
    if(listSize == 0)
    {
        firstNode = NULL;
        return;
    }
    //鏈表theList爲非空
    chainNode<T>* sourceNode = theList.firstNode;
    firstNode = new chainNode<T>(sourceNode->element);//複製線性表theList的首元素
    sourceNode = sourceNode->next;
    chainNode<T>* targetNode = firstNode;//當前鏈表*this的最後一個節點
    while(sourceNode != NULL)
    {
        //複製剩餘元素
        targetNode->next = new  chainNode<T>(sourceNode->element);
        targetNode = targetNode->next;
        sourceNode = sourceNode->next;
    }
    targetNode->next = NULL;//鏈表結束
}
//析構函數
template<class T>
chain<T>::~chain()
{
    //刪除鏈表全部節點
    while(firstNode != NULL)
    {
        chainNode<T>* nextNode = firstNode->next;
        delete firstNode;
        firstNode = nextNode;
    }
}


//bool empty()const;
//判斷鏈表是否爲空
template<class T>
bool chain<T>::empty() const
{
    return listSize == 0;
}

//int size() const;
//記錄線性表元素個數
template<class T>
int chain<T>::size() const
{
    return listSize;
}

//T& get(int theIndex) const;
//返回索引爲theIndex的元素
template<class T>
T& chain<T>::get(int theIndex) const
{
    checkIndex(theIndex);
    chainNode<T>* currentNode = firstNode;
    for(int i=0;i<theIndex;i++)
        currentNode = currentNode->next;
    return currentNode->element;
}

//int indexOf(const T &theElement) const;
//返回元素theElement的索引
template<class T>
int chain<T>::indexOf(const T &theElemet) const
{
    chainNode<T>* currentNode;
    currentNode = firstNode;int index=0;
    while(currentNode != NULL && currentNode->element != theElemet)
    {
        currentNode = currentNode->next;
        index++;
    }

    if(currentNode == NULL)
        return -1;
    else
        return index;
}

//void erase(int theIndex) const;
//刪除索引爲theIndex的元素
//感受書上寫的代碼比個人更加簡潔一些
template<class T>
void chain<T>::erase(int theIndex) const
{
    checkIndex(theIndex);
    chainNode<T>* currentNode = firstNode;int index = 0;
    //若是刪除的元素是首元素,索引爲0,單獨處理
    if(theIndex == 0)
    {
            currentNode = firstNode;
            firstNode = firstNode->next;
    }else
    {
        while((index) != (theIndex-1))
        {
            currentNode = currentNode->next;
            index++;
        }
        currentNode->next = currentNode->next->next;
    }
}

//void insert(int theIndex, const T &theElement) const;
//在索引爲theIndex的位置插入元素
//書上的寫法更加簡潔
template<class T>
void chain<T>::insert(int theIndex,const T& theElement) const
{
    checkIndex(theIndex);
    if(theIndex == 0)
    {
        theElement->next = firstNode->next;
        theElement = firstNode;
    }
    else
    {
        chainNode<T>* currentNode = firstNode;
        for(int i = 0;i<(theIndex-1);i++)
            currentNode = currentNode->next;
        theElement->next = currentNode->next->next;
        currentNode->next = theElement;
    }
}

//void output(ostream &out) const;
//把線性表插入輸出流out
template<class T>
void chain<T>::output(ostream &out) const
{
    //把鏈表放入輸出流
    for(chainNode<T>* currentNode = firstNode;
                        currentNode != NULL;
                        currentNode = currentNode->next)
        out<<currentNode->element<<" ";
}
//重載<<
template<class T>
ostream& operator<<(ostream& out,const chain<T>& x)
{
    x.output(out);
    return out;
}

//void checkIndex(int theIndex) const;
//檢查索引是否有效
template<class T>
void chain<T>::checkIndex(int theIndex) const
{
    if(theIndex < 0 || theIndex > listSize)
        cout<<"輸入的索引不合法!"<<endl;
    return;
}

下面是書上寫的某些函數的具體實現,我認爲書上的代碼更加簡潔,比我寫的邏輯更加清晰,能夠借鑑一下:索引

/*
 * 刪除索引爲theIndex的元素
*/
template<class T>
void chain<T>::erase(int theIndex)
{
    //檢查索引是否合法
    checkIndex(theIndex);

    //索引有效,刪除索引theIndex的元素
    chainNode<T>* deleteNode;
    //待刪除元素爲首元素
    if(theIndex == 0)
    {
        deleteNode = firstNode;
        firstNode = firstNode->next;
    }
    else
    {
        chainNode<T>* p =firstNode;
        for(int i = 0;i<theIndex-1;i++)
            p = p->next;

        deleteNode = p->next;
        p->next = p->next->next;
    }
listSize++;
    delete deleteNode;
}

/*
 * 插入元素theElement並使其索引爲theIndex
*/
template<class T>
void chain<T>::insert(int theIndex,const T& theElement)
{
    if(theIndex < 0 || theIndex > listSize)
    {
        ostringstream s;
        s<<"index = "<<theIndex<<" size"<<listSize;
        throw illegalIndex(s.str());
    }
    if(theIndex == 0)
        firstNode = new chainNode<T>(theElement,firstNode);
    else
    {
        //尋找新元素的前驅
        chainNode<T>* p = firstNode;
        for(int i = 0;i < theIndex -1;i++)
                p = p->next;
        //在p以後插入
        p->next = new chainNode<T>(theElement,p->next);
    }
    listSize++;
}
相關文章
相關標籤/搜索