循环链表

来源:互联网 发布:软件系统安全策略 编辑:程序博客网 时间:2024/06/06 17:23

单向循环链表的结点定义及实现如下面代码所示

#ifndef CIRCULAR_NODE_CLASS#define CIRCULAR_NODE_CLASStemplate <class T>class CNode{private:    CNode<T> *link;public:    T data;    //构造函数    CNode(void);    CNode (const T& item);    //链表更新方法    void InsertAfter(CNode<T> *p);    CNode<T> *DeleteAfter(void);    //获取下一结点地址    CNode<T> *NextNode(void) const;};    //初始化结点使其指向自身template <class T>CNode<T>::CNode(void){    link = this;}//初始化结点使其指向自身, 并且初始化数据域template <class T>CNode<T>::CNode(const T& item){    link = this;    data = item;}//返回下一结点地址template <class T>CNode<T> *CNode<T>::NextNode(void) const{    return link;}//在当前结点后插入*ptemplate<class T>void CNode<T>::InsertAfter(CNode<T> *p){    p->link = link;    //将当前结点的后继作为p的后继, 然后将当前结点指向p    link = p;}//删除当前结点的后继, 并且返回其地址template <class T>CNode<T> *CNode<T>::DeleteAfter(void){    CNode<T> *tempPtr = link;  //暂存被删结点    if (link == this)    //如果被删结点是自身, 返回 NULL        return NULL;    link = tempPtr->link; //使当前结点指向被删结点的后继    return tempPtr;   //返回被删结点地址}#endif

将两个带头结点的单向循环链表LA和LB合并为一个单向循环链表,其头指针为LA

//此算法将两个采用头指针的循环单向链表的首尾连接起来template <class T>CNode<T> * merge_1( CNode<T> * LA, CNode<T>* LB){       CNode<T> *p, *q;    p = LA;    q = LB;    while (p->NextNode() != LA)        p = p->NextNode();    //找到表LA的表尾, 用p指向它    while (q->NextNode() != LB)         q = q->NextNode();    //找到表LB的表尾, 用q指向它    q->InsertAfter(LA);   //修改表LB 的尾指针, 使之指向表LA 的头结点    p->InsertAfter(LB->next);//修改LA的尾指针, 使之指向LB的第一个结点    delete LB;    return (LA);}

时间复杂度为O(n)

若在尾指针表示的单向循环链表上实现

//此算法将两个采用尾指针的循环链表首尾连接起来template <class T>CNode<T> * merge_2( CNode<T> * RA, CNode<T>* RB ){       CNode<T> *p;    p = RA->NextNode(); //保存链表RA的头结点地址    RA->InsertAfter(RB->next->next);//RB的开始结点链到RA的终端结点后    delete RB->NextNode();//释放链表RB的头结点    RB->InsertAfter(p);//链表RA的头结点链到链表RB的终端结点之后    return  RB;//返回新循环链表的尾指针}

时间复杂度为O(1)


约瑟夫问题

#include "cnode.h"//约瑟夫问题算法void Josephus(CNode<int> *list, int n, int m){    CNode<int> *prevPtr = list, *currPtr = list->NextNode();        CNode<int> *deletedNodePtr;        //依次删除元素直到只剩一个元素    for (int i=0; i < n-1; i++)     {        for (int j=0; j < m-1; j++)         {            //指针前移            prevPtr = currPtr;            currPtr = currPtr->NextNode();                        //如果是头结点, 再移一次            if (currPtr == list)             {                prevPtr = list;                currPtr = currPtr->NextNode();            }        }        cout << "Delete person " << currPtr->data << endl;                //记录被删结点, 并且指针下移        deletedNodePtr = currPtr;        currPtr = currPtr->NextNode();                prevPtr->DeleteAfter();        delete deletedNodePtr;                //如果是头结点, 再移一次        if (currPtr == list)         {            prevPtr = list;            currPtr = currPtr->NextNode();        }    }        cout << endl << "Person " << currPtr->data         << " wins the cruise." << endl;        //删除剩余结点即头结点    deletedNodePtr = list->DeleteAfter();    delete deletedNodePtr;}


0 0
原创粉丝点击