1. 程式人生 > >資料結構 筆記:靜態單鏈表的實現

資料結構 筆記:靜態單鏈表的實現

單鏈表的一個缺陷

-觸發條件

·長時間使用單鏈表物件頻繁增加和刪除資料元素

-可能的結果

·堆空間產生大量的記憶體碎片,導致系統執行緩慢

新的線性表

設計思路:

在單鏈表的內部增加一片預留的空間,所有Node物件都在這片空間中動態建立和動態銷燬。

靜態單鏈表的實現思路

-通過模板定義靜態單鏈表類

-在類中定義固定大小的空間

-重寫create和destroy函式,改變記憶體的分配和歸還方式

-在Node類中過載operator new,用於在指定記憶體上建立物件

template<typename T,int N>
class StaticLinkList:public LinkList<T>
{
protected:
    typedef typename LinkList<T>::Node Node;

    struct SNode : public Node
    {
        void* operator new(unsigned int size,void* loc)
        {
            (void)size;
            return loc;
        }
    };

    unsigned char m_space[sizeof(SNode) * N];
    int m_used[N];

    Node* create()
    {
        SNode* ret = NULL;

        for(int i=0;i<N;i++)
        {
            if(!m_used[i])
            {
                if(!m_used[i])
                {
                    ret = reinterpret_cast<SNode*>(m_space) + i;
                    ret = new(ret)SNode();
                    m_used[i] = 1;
                    break;
                }
            }
        }
        return ret;

        return NULL;
    }

    void destroy(Node* pn)
    {
        SNode* space = reinterpret_cast<SNode*>(m_space);
        SNode* psn = dynamic_cast<SNode*>(pn);

        for(int i = 0; i < N ;i++)
        {
            if(psn == (space + i))
            {
                m_used[i] = 0;
                psn->~SNode();
            }
        }
    }
public:
    StaticLinkList()
    {
        for(int i = 0;i<N;i++)
        {
            m_used[i] = 0;
        }
    }

    int capacity()
    {
        return N;
    }
};

LinkList中封裝create和destroy函式的意義是什麼?

為靜態單鏈表(StaticLinkList)的實現做準備。StaticLinkList與LinkList的不同僅在於連結串列結點記憶體分配的不同;

因此,將僅有的不同封裝與父類和子類的虛擬函式中

總結:

順序表和單鏈表相結合後衍生出靜態單鏈表

-靜態單鏈表是LInkList的子類,擁有單鏈表的所有操作

-靜態單鏈表在預留的空間中建立結點物件

-靜態單鏈表適合於頻繁增刪資料元素的場合(最大元素個數固定)