2.4 线性表的其他变形

 

①C++实现循环链表(带头节点)

#include <iostream>
#include <cassert>  //文件操作
#include <fstream>  //对文件进行操作
///有头结点的循环链表
using namespace std;
//枚举:第一个成员默认为0,后面依次+1
enum InsMod {INF, INR};//头插还是尾插


template <typename T>
class CircLinkNode
{
public:
    T data;
    CircLinkNode<T> *link;
    CircLinkNode(CircLinkNode<T> *ptr = NULL) //建立空结点
    {
        link = ptr;
    }
    CircLinkNode(const T &item, CircLinkNode<T> *ptr = NULL) //建立非空结点
    {
        data = item;
        link = ptr;
    }
};

template <typename T>
class CircList
{
public:
    CircList();
    CircList(CircList<T> &L);//复制一个环链表
    ~CircList();

    void makeEmpty();
    int Length()const;
    CircLinkNode<T> *Search(T x);
    CircLinkNode<T> *Locate(int i);
    CircLinkNode<T> *getFirst()const
    {
        return first;
    }

    bool getData(int i,T&x);
    void setData(int i, T &x);

    bool Insert(int i, T &x);
    bool Remove(int i, T &x);

    bool IsEmpty()const;
    bool IsFull()const;

    void Sort();
    void Inverse();//不要返回

    void input(T endTag, InsMod im = INR);
    // void output();
    CircList<T> &operator = (CircList<T> &L)
    {
        T value;
        CircLinkNode<T>* pL = L.getFirst();
        CircLinkNode<T>* last;
        CircLinkNode<T>* pthis = first = new CircLinkNode<T>;
        while(pL->link != L.getFirst())
        {
            value = pL->link->data;
            pthis->link = new CircLinkNode<T>(value);
            pL = pL->link;
            pthis = pthis->link;
        }
        last = pthis ;
        pthis->link = first;

    }
    friend ostream& operator << (ostream &out, CircList<T> &L)
    {
        CircLinkNode<T> *current = L.first->link;
        while (current != L.first)
        {
            out << current->data <<' ';
            current = current->link;
        }
        out<<endl;
        return out;
    }
    friend istream& operator >> (istream &in, CircList<T> &L) //重新输入数据,向后生成
    {
        T val;
        L.makeEmpty();//先清空
        while (!in.eof())
        {
            in >> val;
            L.last->link = new CircLinkNode<T>(val);
            assert(L.last->link);
            L.last = L.last->link;
        }
        L.last->link = L.first;
        in.clear();//当以ctrl_Z结束,流关闭,必须重新打开
        return in;
    }
protected:
    CircLinkNode<T> *first, *last;
    void inputFront(T endTag);
    void inputRear(T endTag);
};

template <typename T>
CircList<T>::CircList()
{
    first = last = new CircLinkNode<T>;
    first->link = first;
}

template <typename T>
CircList<T>::CircList(CircList<T> &L)//复制一个环链表
{
    T value;
    CircLinkNode<T>* pL = L.getFirst();
    CircLinkNode<T>* last;
    CircLinkNode<T>* pthis = first = new CircLinkNode<T>;
    while(pL->link != L.getFirst())
    {
        value = pL->link->data;
        pthis->link = new CircLinkNode<T>(value);
        pL = pL->link;
        pthis = pthis->link;
    }
    last = pthis ;
    pthis->link = first;

}

template <typename T>
CircList<T>::~CircList()
{
    makeEmpty();
}

template <typename T>
void CircList<T>::makeEmpty()
{
    CircLinkNode<T>* t;
    if(first->link == first)
        return;
    while(first->link!=first)
    {
        t = first->link;
        first->link = t->link;
        delete t;
    }
    last = first->link;
}

template <typename T>
int CircList<T>::Length()const
{
    CircLinkNode<T>* t = first->link;
    int i=1;
    while(t->link != first)
    {
        t = t->link;
        i++;
    }
    return i;
}

template <typename T>
CircLinkNode<T> * CircList<T>::Search(T x)
{
    CircLinkNode<T>* t = first->link;
    int f=0;
    while(t->link != first)
    {
        if(x==t->data)
        {
            f=1;
            break;
        }
        else
            t = t->link;
    }
    if(f==1)
        return t;
    else
        return NULL;
}

template <typename T>
CircLinkNode<T> *CircList<T>::Locate(int i)
{
    if(i<0)
        return NULL;
    CircLinkNode<T>* t = first;
    int k=0;
    while(t->link!=first && k<i)
    {
        t = t->link;
        k++;
    }
    return t;
}

template <typename T>
bool CircList<T>::getData(int i,T&x)
{
    if(i<=0)
        return NULL;

    CircLinkNode<T>* t = Locate(i);

    if(t==NULL)
        return false;
    x = t->data;

    return true;
}

template <typename T>
void CircList<T>::setData(int i, T &x)
{
    if(i<=0)
        return;
    CircLinkNode<T>* t = Locate(i);
    if(t==NULL)
        return;
    t->data = x;
}

template <typename T>
bool CircList<T>::Insert(int i, T &x)
{
    CircLinkNode<T> *pre = Locate(i-1);

    if(pre == NULL)
        return false;
    CircLinkNode<T> *newNode = new CircLinkNode<T>(x);
    newNode -> link = pre -> link;
    pre -> link = newNode;

    return true;
}

template <typename T>
bool CircList<T>::Remove(int i, T &x)
{
    CircLinkNode<T> *p = Locate(i-1);
    if(p == NULL || p->link == first)
        return false;
    CircLinkNode<T> *del = p->link;
    x = del->data;
    p->link = del->link;
    delete del;
    return true;
}

template <typename T>
bool CircList<T>::IsEmpty()const
{
    if(first->link = first)
        return true;
    else
        return false;
}

template <typename T>
bool CircList<T>::IsFull()const
{
    return false;
}

template <typename T>
void CircList<T>::Sort()
{
    CircLinkNode<T> *current = this->first->link;
    int temp;
    while(current->link != first)
    {
        CircLinkNode<T>* second = current->link;
        while(second != first)
        {
            if((current->data) > (second->data))
            {
                temp = current->data;
                current->data = second->data;
                second->data = temp;
            }
            second = second->link;
        }
        current = current->link;
    }
}

template <typename T>
void CircList<T>::Inverse()//不要返回
{
    CircLinkNode<T>* rear = first->link;
    T a[100];
    int len = 1;
    while(rear->link != first)
    {
        a[len] = rear->data;
        rear = rear->link;
        len++;
    }
    a[len] = rear->data;
    for(int i=1,j=len; i<j; i++,j--)
    {
        swap(a[i],a[j]);
    }
    // for(int i=1;i<=len;i++)
    //    cout<<a[i]<<' ';
    CircLinkNode<T>* t = first->link;
    for(int i=1; i<=len; i++)
    {
        t->data = a[i];
        t = t->link;
    }
}

template <typename T>
void input(T endtag, InsMod im = INR)
{

}

int main()
{
    CircList<int> list;
    ifstream fin("list.txt");
    assert(fin);
    fin >> list;
    cout << "The initial list:" << list << endl;

    // cout << list.Length()<<endl;

    list.Inverse();
    cout << "Inverse the list:" << list << endl;

    // cout << "========================================
";
    int i, elem;
    // cout << "Test the Insert, Remove and Search function:
";
    // cout << "Each test will terminate by an invaid input.";
    //cout << "
----------------------------------------
";


    while (1)
    {
        cout << "Insert(int i, T &elem):";
        // cout << "Input the index i and data elem to insert: ";
        cin >> i >> elem;
        if (!cin) //流不正常
        {

            cin.clear();//恢复正常
            cin.ignore(100,'
');
            break;
        }
        if (i < 0)
            break;
        if (list.Insert(i, elem))
            cout << "successful!
";
        else
            cout << "failed!
";
        cout << "
After inserted
" << list << endl;

    }

    // cout << "----------------------------------------
";
    cout << "Remove(int i, T &elem):";
    while (1)
    {
        // cout << "Input the index i in which you want to remove: ";
        cin >> i;
        if (!cin)
        {
            cin.clear();
            cin.ignore(100,'
');
            break;
        }
        if (i < 0)
            break;
        if (list.Remove(i, elem))
            cout << "The element " << elem << " has been removed!
";
        else
            cout << "Remove failed!
";
        cout << "
After removed
" << list << endl;
    }


    //  cout << "----------------------------------------
";
    cout << "Search(T &elem):
";
    while (1)
    {
        //   cout << "Input the element you want to search: ";
        cin >> elem;
        if (!cin)
        {
            cin.clear();
            cin.ignore(100,'
');
            break;
        }
        if (elem < 0)
            break;
        CircLinkNode<int> *p = list.Search(elem);
        if (p)
            cout << "The element " << elem << " is in the list.
";
        else
            cout << "The element is not exist!
";
    }


    list.Sort();
    cout << "sort:  " << list << endl;

    cout << "setdata: ";
    int n, m;
    cin>>n>>m;
    list.setData(n,m);
    cout << "After:" << list << endl;

    cout << "getdata: ";
    int n1, m1;
    cin>>n1;
    list.getData(n1,m1);
    cout << "the data is:" << m1 << endl;


    CircList<int> list1=list;
    
    cout << "copy the list :"list1 <<endl;


    cout << "
----------------------------------------
";
    cout << "End test!" << endl;

    return 0;
}

#调试结果#

②用C++实现双向循环链表DLL(有头结点)

#include <iostream>
///带头结点的双向循环链表DLL
using namespace std;

template<typename Type>
struct DoubleLinkNode
{
    Type data;
    DoubleLinkNode<Type>* lLink;
    DoubleLinkNode<Type>* rLink;
    DoubleLinkNode(DoubleLinkNode<Type>* pre=NULL,DoubleLinkNode<Type>*suc=NULL)
    {
        lLink=pre;
        rLink=suc;
    }
    DoubleLinkNode(const Type& elem, DoubleLinkNode<Type>* pre=NULL,DoubleLinkNode<Type>* suc=NULL)
    {
        data=elem;
        lLink=pre;
        rLink=suc;
    }
};

template<typename Type>
class CircleDoubleLinkedList
{
private:
    DoubleLinkNode<Type>* first;

public:
    CircleDoubleLinkedList();
    ~CircleDoubleLinkedList();

    void CopyList(const CircleDoubleLinkedList<Type>& lst);
    void GetHead()const
    {
        return first;
    }
    CircleDoubleLinkedList(const CircleDoubleLinkedList<Type>& lst);
    CircleDoubleLinkedList<Type>& operator=(const CircleDoubleLinkedList<Type>& lst);

    void MakeEmpty();
    bool Insert(int loc, const Type& elem,int sign);
    bool Remove(int loc, Type& elem, int sign);

    DoubleLinkNode<Type>* Search(const Type& elem, int sign) const;
    DoubleLinkNode<Type>* Locate(int loc, int sign);

    bool GetData(int loc, Type& elem, int sign) const;
    bool SetData(int loc, const Type& elem, int sign);

   // void InputRear(const Type& elem);
    void OutPut(int sign=0);
};

template<typename Type>
CircleDoubleLinkedList<Type>::CircleDoubleLinkedList()
{
    first = new DoubleLinkNode<Type>;
    first->lLink = first->rLink = first;
}

template<typename Type>
void CircleDoubleLinkedList<Type>::MakeEmpty()
{
    DoubleLinkNode<Type>* p,*q;  //两个,一个是负责往后指,一个负责删除
    p = q = first->rLink;

    while(p != first)
    {
        p = p->rLink;
        delete q;
        q = p;
    }
    first->lLink = first->rLink = first;

}

template<typename Type>
CircleDoubleLinkedList<Type>::~CircleDoubleLinkedList()
{
    MakeEmpty();
}

//template<typename Type>
//void CircleDoubleLinkedList<Type>::InputRear(const Type& elem)
//{

//}

template<typename Type>
void CircleDoubleLinkedList<Type>::CopyList(const CircleDoubleLinkedList<Type>& lst)
{
    DoubleLinkNode<Type>* p = lst.GetHead();
    DoubleLinkNode<Type>* n = first = new DoubleLinkNode<Type>;
    Type t;
    DoubleLinkNode<Type>* pp = p->rLink;

    while(pp != p)
    {
        t = pp->data;
        n->rLink = new DoubleLinkNode<Type>(t);
        n = n->rLink;
        pp = pp->rLink;
    }

    n->rLink = first->lLink;
    return;
}

template<typename Type>
CircleDoubleLinkedList<Type>::CircleDoubleLinkedList(const CircleDoubleLinkedList<Type>& lst)
{
    CopyList(lst);
}

template<typename Type>
CircleDoubleLinkedList<Type>& CircleDoubleLinkedList<Type>::operator=(const CircleDoubleLinkedList<Type>& lst)
{
    CopyList(lst);
    return* this;
}

template<typename Type>
DoubleLinkNode<Type>* CircleDoubleLinkedList<Type>::Locate(int loc, int sign)
{
    if(loc < 0)
        return NULL;

    DoubleLinkNode<Type>* newN = first;
    int k = 0;
    if(sign==0)
    {
        while(newN!=first && k<loc)
        {
            newN = newN->rLink;
            k++;
        }
    }
    else
    {
        while(newN!=first && k<loc)
        {
            newN = newN->lLink;
            k++;
        }
    }

    return newN;
}

template<typename Type>
bool CircleDoubleLinkedList<Type>::Insert(int loc, const Type& elem,int sign)
{
    DoubleLinkNode<Type>* newN = new DoubleLinkNode<Type>(elem);
    DoubleLinkNode<Type>* sub;
    DoubleLinkNode<Type>* pre = first;

    for(int i=1; i<loc; i++)
    {
        if(sign == 0)
            pre = pre->rLink;
        else
            pre = pre->lLink;
        if(pre == first)
            return false;
    }

    if(sign == 0)
    {
        sub = pre->rLink;
        sub->lLink = newN;
        newN->rLink = sub;
        pre->rLink = newN;
        newN->lLink = pre;
    }
    else
    {
        sub = pre->lLink;
        sub->rLink = newN;
        newN->lLink = sub;
        pre->lLink = newN;
        newN->rLink = pre;
    }
    return true;
}

template<typename Type>
bool CircleDoubleLinkedList<Type>::Remove(int loc, Type& elem, int sign)
{
    DoubleLinkNode<Type>* iter = first;
    DoubleLinkNode<Type>* pre,*suc;  //每一个都要加*
    for(int i=1; i<=loc; i++)
    {
        if(sign == 0)
            iter = iter->rLink;
        else
            iter = iter->lLink;
        if(iter == first)
            return false;
    }

    if(sign == 0)
    {
        pre=iter->lLink;
        suc=iter->rLink;
        pre->rLink=suc;
        suc->lLink=pre;
    }
    else
    {
        pre=iter->rLink;
        suc=iter->lLink;
        pre->lLink=suc;
        suc->rLink=pre;
    }
    delete iter;
    return true;
}

template<typename Type>
DoubleLinkNode<Type>* CircleDoubleLinkedList<Type>::Search(const Type& elem, int sign) const
{
    DoubleLinkNode<Type>* t = first;
    Type v;

    if(sign == 0)
        while(t->rLink != first)
        {
            v = t->rLink->data;
            if(v == elem)
                return t->rLink;
            t = t->rLink;
        }
    else
        while(t->lLink != first)
        {
            v = t->lLink->data;
            if(v == elem)
                return t->lLink;
            t = t->lLink;
        }
    return t;
}

template<typename Type>
bool CircleDoubleLinkedList<Type>::GetData(int loc, Type& elem, int sign) const
{
    DoubleLinkNode<Type>* iter = first;
    for(int i=1; i<loc; i++)
    {
        if(sign == 0)
            iter = iter->rLink;
        else
            iter = iter->lLink;
        if(iter == first)
            return false;
    }
    if(sign == 0)
        elem = iter->rLink->data;
    else
        elem = iter->lLink->data;
    return true;
}

template<typename Type>
bool CircleDoubleLinkedList<Type>::SetData(int loc, const Type& elem, int sign)
{
    DoubleLinkNode<Type>* iter = first;
    for(int i=1; i<loc; i++)
    {
        if(sign == 0)
            iter = iter->rLink;
        else
            iter = iter->lLink;
        if(iter == first)
            return false;
    }
    if(sign == 0)
        iter->rLink->data = elem;
    else
        iter->lLink->data = elem;
    return true;
}

template<typename Type>
void CircleDoubleLinkedList<Type>::OutPut(int sign)
{
    DoubleLinkNode<Type>* iter = first;
    if(sign == 0)
    {
        iter = iter->rLink;
        while(iter != first)
        {
            cout << iter->data << ' ' ;
            iter = iter->rLink;
        }
        cout<<endl;
    }
    else
    {
        iter = iter->lLink;
        while(iter != first)
        {
            cout << iter->data << ' ' ;
            iter = iter->lLink;
        }
        cout<<endl;
    }
}


int main()
{
    CircleDoubleLinkedList<int> lst;
    cout<<"数字1-10进行尾插:"<<endl;
    for(int i=1; i<=10; i++)
    {
        lst.Insert(i,i,1);
    }
    cout << "正向输出:";
    lst.OutPut(0);
    cout << "反向输出:";
    lst.OutPut(1);
    cout<<endl;

    cout << "是否可以正向搜索第五个数字:";
    if(lst.Search(5,0))
    {
        cout<<"yes"<<endl;
    }
    else
    {
        cout<<"no"<<endl;
    }
    cout<<endl;

    cout << "把正向第10个数字设置为100:";
    lst.SetData(10,100,0);
    lst.OutPut(0);
    cout<<endl;

    cout << "反向第3个数字为:";
    int x;
    lst.GetData(3,x,1);
    cout<<x<<endl;
    cout<<endl;

    cout << "从头开始一个一个删除:" <<endl;
    int val;
    for(int i=10; i>0; i--)
    {
        lst.Remove(i,val,1);
        lst.OutPut(0);
    }
    cout<<endl;

    return 0;
}

#运行结果#

原文地址:https://www.cnblogs.com/syzyaa/p/13751641.html