1. 程式人生 > >[資料結構]連結串列的實現(c++/類模板)

[資料結構]連結串列的實現(c++/類模板)

#include <iostream>
#include <cstdlib>
using namespace std;

//用struct定義LinkNode類.使用這種方法使該類失去封裝性,但簡化了描述.
//在Link類中把first封裝在了其內部,屬於該Link的所有LinkNode例項都成為Link例項的私有成員,保證不被外界直接訪問.

//結點模板的定義
template<typename Type>
struct LinkNode
{
    Type data;
    LinkNode<Type>* next;
    LinkNode(const Type& item, LinkNode<Type>* ptr=NULL)//用於初始化data和next
    {
        data = item;
        next = ptr;
    }
    /*    LinkNode(LinkNode<Type>* ptr=NULL)
        {
            next = ptr;
        }
    */
};
//單鏈表模板的定義
template<typename Type>
class List
{
private:
    LinkNode<Type>* first;//連結串列頭指標
public:
    List()//建構函式
    {
        first = NULL;
    }
    List(const List<Type>& L)//拷貝建構函式
    {
        first = NULL;
        CopyList(L);
    }
    List<Type>operator=(const List<Type>& L)//賦值運算子符號
    {
        if(this==&L)
            return *this;
        MakeEmpty();
        CopyList(L);
        return *this;
    }
    ~List()//解構函式
    {
        LinkNode<Type>* p;
        while(p)
        {
            p=first;
            first=p->next;
            delete p;
        }
    }

    //單鏈表的增刪查改
    void InputFront(const Type& elem);
    void InputRear(const Type& elem);
    bool Insert(int i, const Type& x);
    bool Remove(int i, Type& x);
    //LinkNode<Type>* Search(const Type& x);
    bool Search(const Type& x);
    LinkNode<Type>* Locate(int i);
    bool GetData(int i, Type& x)const;
    bool SetData(int i, const Type& x);

    //清空複製列表結點
    void MakeEmpty();
    void CopyList(const List<Type>& L);

    //連結串列自身狀態
    int Length() const
    {
        LinkNode<Type>* s=first;
        int count=1;
        while(s->next)
        {
            count++;
            s = s->next;
        }
        return count;
    }
    bool IsEmpty() const
    {
        return first==NULL;
    }
    bool IsFull() const
    {
        return false;
    }

    //當前指標所指向結點在連結串列中的位置
    int GetLocation(const LinkNode<Type>* iter)
    {
        LinkNode<Type>* p = first;
        int L = Length();
        int count = 0;
        while(count <= L)
        {
            count++;
            if(p==iter)
            {
                return count;
            }
            p = p->next;
        }
        return 0;
    }
    bool PutLocation(const LinkNode<Type>* iter)
    {
        LinkNode<Type>* p = first;
        int L = Length();
        int count = 0;
        while(count <= L)
        {
            count++;
            if(p==iter)
            {
                cout << count;
                return true;
            }
            p = p->next;
        }
        return false;
    }

    //排序(升序)
    /*    void Sort()
        {
            LinkNode<Type>* Max = new LinkNode<Type> (first->data);
            LinkNode<Type>* iter1;
            LinkNode<Type>* iter2 = first;
            int i;
            Type x;
             while(iter2)
            {
                iter1 = iter2;
                while(iter1)
                {
                    if(Max->data < iter1->data)
                    {
                        Max->data = iter1->data;
                        i = GetLocation(iter1);
                    }
                    iter1 = iter1->next;
                }
                if(Locate(i)!=iter2)
                {
                    Remove(i, x);
                    InputFront(Max->data);
                    //iter2 = iter2->next;
                }
                else
                {
                    iter2 = iter2->next;
                    Remove(i, x);
                    InputFront(Max->data);
                }
                Max->data = iter2->data;
            }
        }
    */
    //主要問題是 Max 和i 應該在每次內層迴圈找最大值時都應該被初始化。

    void Sort()
    {
        LinkNode<Type>* iter1;
        LinkNode<Type>* iter2 = first;
        LinkNode<Type>* Max = new LinkNode<Type> (iter2->data);
        int i=GetLocation(iter2);
        Type x;
        while(iter2)
        {
            iter1 = iter2;
            while(iter1)
            {
                if(Max->data < iter1->data)
                {
                    Max->data = iter1->data;
                    i = GetLocation(iter1);
                }
                iter1 = iter1->next;
            }
            //cout<<Max->data<<endl;
            if(Locate(i)!=iter2)
            {
                Remove(i, x);
                InputFront(Max->data);
                //iter2 = iter2->next;
            }
            else
            {
                iter2 = iter2->next;
                Remove(i, x);
                InputFront(Max->data);
            }
            //LinkNode<Type>* iter=iter2;

            if(iter2)
            {
                Max->data = iter2->data;
                i=GetLocation(iter2);
            }

        }
    }

    //輸入輸出運算子過載
    friend ostream& operator<<(ostream& out, const List<Type>& L)
    {
        LinkNode<Type>* iter = L.first;
        while(iter)
        {
            out << iter->data << " ";
            iter = iter->next;
        }
        out << endl;
        return out;
    }
    friend istream& operator>>(istream& in, List<Type>& L)
    {
        return in;
    }
};

template<typename Type>
void List<Type>::InputFront(const Type& elem)
{
    LinkNode<Type>* NewNode = new LinkNode<Type>(elem);
    if(NewNode==NULL)
    {
        cout << "建立結點失敗" << endl;
    }
    NewNode->next = first;
    first = NewNode;
}
template<typename Type>
void List<Type>::InputRear(const Type& elem)
{
    LinkNode<Type>* NewNode = new LinkNode<Type>(elem);
    if(NewNode==NULL)
    {
        cout << "建立結點失敗" << endl;
    }
    if(first==NULL)
    {
        first = NewNode;
    }
    else
    {
        LinkNode<Type>* rear = first;
        while(rear->next)
        {
            rear = rear->next;
        }
        rear->next = NewNode;
    }
}
template<typename Type>
bool List<Type>::Insert(int i, const Type& x)
{
    LinkNode<Type>* newNode = new LinkNode<Type>(x);
    if(i<1)
    {
        cout << "Location error" << endl;
        return false;
    }
    if(i==1)
    {
        newNode->next = first;
        first = newNode;
        return true;
    }
    else
    {
        LinkNode<Type>* pre = first;
        for(int j=1; j<i-1; j++)
        {
            pre=pre->next;
            if(pre==NULL)
                break;
        }
        if(pre==NULL)
        {
            cout << "Location error" << endl;
            return false;
        }
        newNode->next  = pre->next;
        pre->next = newNode;
        return true;
    }
}

template<typename Type>
bool List<Type>::Remove(int i, Type& x)
{
    LinkNode<Type>* del;
    LinkNode<Type>* pre;
    if(i<1)
    {
        cout << "Location error" << endl;
        return false;
    }
    if(i==1)
    {
        del = first;
        first = del->next;
        x = del->data;
        delete del;
        return true;
    }
    else
    {
        pre = first;
        for(int j=1; j<i-1; j++)
        {
            pre = pre->next;
            if(pre==NULL)
                break;
        }
        if(pre==NULL)
        {
            cout << "Location error" << endl;
            return false;
        }

        del = pre->next;
        x = del->data;
        pre->next = del->next;
        delete del;
        return true;
    }
}
template<typename Type>
//LinkNode<Type>* List<Type>::Search(const Type& x)
/*{
    LinkNode<Type>* iter = first;
    while(iter)
    {
        if(iter->data == x)
            return iter;
        iter = iter->next;
    }
    return iter;
}*/
bool List<Type>::Search(const Type& x)
{
    LinkNode<Type>* iter = first;
    while(iter)
    {
        if(iter->data == x)
        {
            PutLocation(iter);
            return true;
        }
        iter = iter->next;
    }
    cout << "Not found";
    return false;
}
template<typename Type>
LinkNode<Type>* List<Type>::Locate(int i)
{
    LinkNode<Type>* iter = first;
    int count = 0;
    while(iter)
    {
        count++;
        if(count == i)
        {
            return iter;
        }
        else
        {
            iter=iter->next;
        }
    }
    return iter;
}
template<typename Type>
bool List<Type>::GetData(int i, Type& x)const
{
    if(i<1)
    {
        cout << "Location error" << endl;
        return false;
    }
    else
    {
        LinkNode<Type>* nd = Locate(i);
        if(nd==NULL)
        {
            cout << "Location error" << endl;
            return false;
        }
        else
        {
            x = nd->data;
            return true;
        }
    }

}
template<typename Type>
bool List<Type>::SetData(int i, const Type& x)
{
    if(i<1)
    {
        cout << "Location error" << endl;
        return;
    }
    else
    {
        LinkNode<Type>* nd = Locate(i);
        if(nd==NULL)
        {
            cout << "Location error" << endl;
            return false;
        }
        else
        {
            nd->data = x;
            return true;
        }
    }
}

template<typename Type>
void List<Type>::MakeEmpty()
{
    LinkNode<Type>* del;
    while(first)
    {
        del = first;
        while(del->next)
        {
            del = del->next;
        }
        delete del;
    }
    return;
}
template<typename Type>
void List<Type>::CopyList(const List<Type>& L)
{
    if(L.first==NULL)
    {
        MakeEmpty();
    }
    else
    {
        LinkNode<Type>* iter = first;
        while(iter)
        {
            InputRear(iter->data);
            iter = iter->next;
        }
    }
}
/*
int main()
{
    List<int> lst;
    //int elem;
    //LinkNode<int>* nd;
    //srand(time(NULL));
    for(int i=0; i<10; i++)
    {
        lst.Insert(i+1,rand()%100);
    }
    cout << lst << endl;
    lst.Sort();
    cout<< lst <<endl;
    //lst.Remove(3,elem);
    //cout<<lst;
    //nd=lst.Search(3);
    //cout<<nd->data;
    return 0;
}
*/
int main()
{
    List<int> L1;
    int n1;
    int x, i;
    cin >> n1;
    for(int i = 0; i < n1; i++)
    {
        int num;
        cin >> num;
        L1.Insert(i+1,num);
    }

    cin >> x >> i;//在i位置插入值為x的結點
    L1.Insert(i, x);
    cout << L1;

    cin >> i;//要刪除的數字的位置
    L1.Remove(i, x);
    cout << L1;

    cin >> x;//要查詢的數字x
    L1.Search(x);
    cout << endl;

    L1.Sort();
    cout << L1;

    int n2;
    cin >> n2;
    for(int i = 0; i < n2; i++)
    {
        int num;
        cin >> num;
        L1.InputFront(num);
    }
    L1.Sort();
    cout << L1;

    return 0;
}