循环链表
来源:互联网 发布:软件系统安全策略 编辑:程序博客网 时间: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
- 循环链表实现循环队列
- 循环链表与循环队列
- 循环链表
- 循环链表
- 双向循环链表
- 双向循环链表
- 循环链表实验
- 链表::循环链表
- 双向循环链表
- 双向循环链表
- 循环链表
- 循环链表
- 循环链表
- 循环链表建立
- 数据结构 循环链表
- 双向循环链表
- 循环链表详解
- 循环链表
- Linux成长之路(二)——Linux目录结构和对文件的基本操作
- 拖拽案例
- C++中的纯虚函数
- zookeeper、dubbo整合搭建rpc(基于springMVC)
- 24. Swap Nodes in Pairs
- 循环链表
- BeautifulSoup安装
- HandsFree——OpenRE库学习(二)
- 53. 使 Ajax 可缓存(14)
- hduoj1239
- Java进阶(四十七)Socket通信
- csv.Error: line contains NULL byte解决方法
- SQL Server全文检索
- 《书都不会读,你还想成功》读书笔记