筆記五:線性表——單鏈表表示

線性鏈表

注意: firstnode指的就是第一個節點,而不是一個指向第一個節點的指針。

代碼:

#include<iostream>
using namespace std;

template<typename T>
struct chainNode
{
    T element;
    chainNode*  next;

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

template<typename T>
class linearList
{
public:
    virtual ~linearList() {};                  //析構函數
    virtual bool empty() const = 0;         //返回true,當且僅當線性表爲空
    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) = 0;                       //刪除索引爲theIndex的元素
    virtual void insert(int theIndex, const T& theElement) = 0; //把theElement插入線性表中索引爲theIndex的位置
    virtual void output() const = 0;                //把線性表插入的輸出流out
};

template<typename T>
class Chain : public linearList<T>
{
public:
    Chain(int initialCapacity = 10);
    Chain(const Chain<T>&);
    ~Chain();

    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 insert(int theIndex, const T& theElement);
    void output() const;

private:
    int listSize;
    chainNode<T>* firstnode;
};

template<typename T> Chain<T>::Chain(int initialCapacity)
{
    if (initialCapacity < 1)
    {
        cout << "初始化容量小於1,不正確!" << endl;
        exit(-1);
    }
    firstnode = NULL;
    listSize = 0;
}

template<typename T> Chain<T>::Chain(const Chain<T>& theList)
{
    this.listSize = theList.listSize;
    if (listSize == 0)
    {
        firstnode = NULL;
        return;
    }

    chainNode<T>* pt = theList->firstnode, *curr=NULL;
    fisrtnode = new chainNode<T>(pt->element);  //複製源節點
    curr = firstnode;
    while (pt != NULL)
    {
        curr->next = new chainNode<T>(pt->element);
        pt = pt->next;
        curr = curr->next;
    }
    curr->next = NULL;


}

template<typename T> Chain<T>::~Chain()
{
    chainNode<T>* delnode = firstnode;
    while (firstnode!= NULL) 
    {
        firstnode = firstnode->next;
        delete delnode;
        delnode = firstnode;
    }
    listSize = 0;
}

template<typename T> T& Chain<T>::get(int theIndex) const
{
    if (theIndex < 0 || theIndex >= listSize)
    {
        cout << "theIndex: " << theIndex << "不正確!" << endl;
        exit(-1);
    }

    chainNode<T>* pt = firstnode;
    int num = 0;
    while (num != theIndex)
    {
        pt = pt->next;
        ++num;
    }

    return pt->element; 
}

template<typename T> int Chain<T>::indexOf(const T& theElement) const
{
    if (listSize == 0)
    {
        cout << "線性表爲空表,故返回下標-1" << endl;
        return -1;
    }

    chainNode<T>*   pt = firstnode;
    int num = 0;
    while (num < listSize)
    {
        if (pt->element == theElement)
        {
            break;
        }
        pt = pt->next;
        ++num;
    }

    if (num >= listSize)
    {
        cout << "線性鏈表中不存在該元素,故返回下標: " << endl;
        return -1;
    }
    return num;

}

template<typename T> void Chain<T>::erase(int theIndex)
{
    if (theIndex < 0 || theIndex >= listSize)
    {
        cout << "下標不在線性鏈表長度範圍內!" << endl;
        exit(-1);
    }

    chainNode<T>* pt = firstnode, *curr = NULL;
    if (theIndex == 0)  //刪除firstnode節點
    {
        curr = firstnode;
        firstnode = firstnode->next;
    }
    else{
        int num = 0;
        while (num < theIndex - 1)
        {
            pt = pt->next;
            num++;
        }
        curr = pt->next;    //theIndex指向的刪除節點
        pt->next = curr->next;  //刪除節點的前一節點轉指向刪除節點的後一節點
    }

    --listSize;
    delete curr;

}

template<typename T> void Chain<T>::insert(int theIndex, const T& theElement)
{
    if (theIndex<0 || theIndex > listSize)
    {
        cout << "節點插入的下標不正確!" << endl;
        exit(-1);
    }

    if (theIndex == 0)
    {
        firstnode = new chainNode<T>(theElement, firstnode);
    }
    else{
        chainNode<T> * pt = firstnode, *curr = NULL;
        int num = 0;
        while (num < theIndex -1)
        {
            pt = pt->next;
            num++;
        }
        curr = pt->next;    //theIndex所在的線性鏈表中的節點
        chainNode<T>* newchainNode = new chainNode<T>(theElement);
        newchainNode->next = curr;
        pt->next = newchainNode;
    }
    ++listSize;
}

template<typename T> void Chain<T>::output() const
{
    if (listSize == 0)
        cout << "線性鏈表爲空表!" << endl;
    else{
        cout << "線性鏈表輸出爲:";
        chainNode<T>* pt = firstnode;
        while (pt != NULL)
        {
            //pt = firstnode->next;
            cout << pt->element << " ";
            pt = pt->next;
        }
        cout << endl;
    }
}


int main(int argc, char* argv[])
{
    Chain<int> chain;
    chain.output();
    cout << "size = " << chain.size() << endl;
    cout << "\n****************" << endl;

    chain.insert(0, 0);
    chain.output(); 
    cout << "size = " << chain.size() << endl;
    cout << "\n****************" << endl;

    chain.insert(1, 1);
    chain.insert(2, 2);
    chain.output();
    cout << "size = " << chain.size() << endl;
    cout << "\n****************" << endl;

    chain.insert(0, 3);
    chain.insert(2, 4);
    chain.output();
    cout << "size = " << chain.size() << endl;
    cout << "\n****************" << endl;

    chain.erase(0);
    chain.erase(1);
    chain.output();
    cout << "size = " << chain.size() << endl;
    cout << "\n****************" << endl;

    cout << "when elemtn = 2 , the index is :" << chain.indexOf(2) << endl;
    cout << "\n****************" << endl;

    chain.insert(0, 3);
    chain.output();
    cout << "size = " << chain.size() << endl;
    cout << "when index = 2 , the elemnt is :" << chain.get(2) << endl;

    chain.~Chain();
    return 0;
}


運行:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章