鏈表 C++描述

        鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱爲結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操作複雜。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的複雜度,比另一種線性表順序錶快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間複雜度分別是O(logn)和O(1)。

        使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大。鏈表最明顯的好處就是,常規數組排列關聯項目的方式可能不同於這些數據項目在記憶體或磁盤上順序,數據的存取往往要在不同的排列順序中轉換。鏈表允許插入和移除表上任意位置上的節點,但是不允許隨機存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環鏈表。

#include<iostream>
using namespace std;

template <class T>
class Chain;

template <class T>
class ChainNode
{
    friend class Chain<T>;
private:
    T data;
    ChainNode<T> *next;
};

template <class T>
class Chain
{
public:
    Chain()
    {
        first = 0;
        last = 0;
    }
    ~Chain();
    void Add(T& x);
    bool IsEmpty()const{return first==0;}
    int Length()const;
    bool Find(int k, T& x)const;
    int Search(const T& x)const;
    void DeleteOfk(int k);//刪除第k個元素
    void DeleteOfx(T& x);//刪除鏈表中值爲x的幾點,如果存在
    void Insert(int k,const T& x);
    void OutPut()const;
private:
    ChainNode<T> *first;
    ChainNode<T> *last;
};

template <class T>
Chain<T>::~Chain()
{//析構函數,刪除表中的所有節點
    ChainNode<T> *next;
    while(first)
    {
        next = first->next;
        delete(first);
        first = next;
    }
}

template <class T>
void Chain<T>::Add(T& x)
{
    ChainNode<T> *node = new ChainNode<T>;
    node->data = x;
    node->next = NULL;
    if(first)
    {//每次在鏈表的尾部插入一個節點
        last->next = node;
        last = node;
    }
    else
    {//如果是空表  這新加入的節點既是頭結點也是尾節點
        first = node;
        last = node;
    }
}

template <class T>
int Chain<T>::Length()const
{//返回鏈表的長度
    ChainNode<T> *current = first;
    int len = 0;
    while(current)
    {
        len++;
        current = current->next;
    }
    return len;
}

template<class T>
bool Chain<T>::Find(int k, T& x)const
{//查找第k個元素,如果純在將其保存在x中。
//如純在返回true,不存在返回false
    if (k<1)
        return false;
    ChainNode<T> *current = first;
    int index = 1;
    while(index<k&¤t)
    {
        current = current->next;
        index++;
    }
    if (current)
    {
        x = current->data;
        return true;
    }
    else
    {
        return false;
    }
}

template<class T>
int Chain<T>::Search(const T& x)const
{//尋找x,如果發現x,返回x的地址
//如果x不存在鏈表中則返回0
    ChainNode<T> *current = first;
    int index = 1;
    while(current&¤t->data!=x)
    {
        index++;
        current = current->next;
    }
    if(current)
        return index;
    return 0;
    
}

template <class T>
void Chain<T>::DeleteOfk(int k)//刪除第k個元素
{
    T x;
    if(Find(k,x))
    {
        int index = 1;
        ChainNode<T> *current = first;
        ChainNode<T> *temp=0;
        if(k==1)
        {//刪除頭結點
            first = first->next;
            delete (current);
        }   
        else
        {
            while(k!=index)
            {
                index++;
                temp = current;//temp始終指向current的上一個節點
                current = current->next;
            }
            if(current)
            {
                temp->next = current->next;
                if(!current->next)
                {//如果刪除的是最後一個節點,則最後的一個節點應該變成temp。
                    last = temp;
                }
                delete (current); 
                
            }
            
        }
        
    }
}

template <class T>
void Chain<T>::DeleteOfx(T& x)//刪除鏈表中值爲x的幾點,如果存在
{
    int k;
    k = Search(x);
    if(k!=0)
    {
        DeleteOfk(k);
    }
    else
    {
        cout<<"刪除的數據在鏈表中不存在"<<endl;
    }
}

template <class T>
void Chain<T>::Insert(int k,const T& x)
{
    ChainNode<T> *temp = new ChainNode<T>;
    temp->data = x;
    temp->next = NULL;
    if(k==0)
    { //插入在頭結點的位置
        temp->next = first;
        first = temp;
    }
    else if(k>0&&k<=Length())
    {
        ChainNode<T> *current = first;
        int index = 1;
        while(index!=k)
        {
            index++;            
            current = current->next;
        }
        if(current)
        {
            temp->next = current->next;
            current->next = temp; 
        }
        else
        {//插入在尾節點的位置
            last = temp;
            current->next = temp;
        }
        
    }
    else
    {
        cout<<"插入數據不正確"<<endl;
    }
}

template <class T>
void Chain<T>::OutPut()const
{
    ChainNode<T> *current = first;
    while(current)
    {
        cout<<current->data<<"  ";
        current = current->next;
    }
    cout<<endl;
}

int main()
{
    Chain<int> list;
    int x;
    for(int i=0; i<5; i++)
    {
        cin>>x;
        list.Add(x);
    }
    list.OutPut();
    cout<<"length: "<<list.Length()<<endl;
    x = 0;
    if(list.Find(5,x))
    {
        cout<<"OK!!  "<<x<<endl;
    }
    int y = list.Search(x);
    cout << "y="<<y<<endl;
    list.DeleteOfk(1);
    list.OutPut();
    list.DeleteOfx(x);
    list.OutPut();
    list.Insert(0,x);
    list.OutPut();
}


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