刚刚接触C++以及数据结构,今天做了第一次尝试用C++和数据结构解决问题,问题是基于约瑟夫环问题的简单版。

  • 先来看看约瑟夫环问题的介绍:

    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始    报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。(摘自百度百科)

    程序的输入应该由三个值组成(n, k, m),接下来程序将会自动运行,本文假设每次都从第一个人开始报数,所以是做了一些简化,但是换汤不换药。

  • 接下来将分部介绍程序的组成

    首先是头文件,命名为circle_single_linked_list.h

    基本结构:

template <typename Object>
class circleSingleLinkedList{
private: /*循环单链表的每个的节点定义
*结构简单,所以使用struct
*具体实现请看下文
*/
struct Node{
}; public: /*内嵌类iterator
*是链表中的一个位置的抽象(abtracts the notion of a position)
*类比vector<>的iterator
*在类外的调用方法为:circleSingleLinkedList<int>::iterator ....
*本文省去了对于const_iterator类型的定义
*/
class iterator{
}; public:   /*循环链表实现
*由构造函数(含默认实参),big three都没有...(程序比较简陋)
*begin()返回表头位置
*insert以及erase是实现约瑟夫环的主要手段
*循环链表只有2个数据成员, theSize存储链表节点个数, head为头指针, 指向链表中的第一个节点
*具体实现见下文
*/
circleSingleLinkedList(const Object& x = Object()){
} iterator begin()const{
} int size(){
return theSize;
} bool empty(){
return size() == ;
} iterator insert(iterator itr, const Object& x){
} iterator erase(iterator itr){
} void print(ostream& out){
} private:
int theSize;
Node* head;
};

    由于编写的是模板类,所以将类的定义,成员函数的实现,以及内嵌类的实现都放在了一个头文件中,本人刚刚接触C++,目前了解的情况是:模板类最好不要用        separate compilation,因为可能会造成complicated looking syntax,具体是什么我目前也不清楚,需要继续学习。

  • 接下来是各部分的具体实现
 struct Node{
Object data; //用于存放各个节点的数值,在约瑟夫环问题中,存放不同人的编号
Node* next; //每个单链表节点的指向下一个节点的指针 Node(const Object& d = Object(), Node* n=NULL) //默认构造函数
: data(d), next(n) {}
};

内嵌类iterator的实现

//iterator类主要包含了运算符重载:解引用,prefix++,postfix++,==,!=,具体的使用可以类比vector<>::iterator的使用方法.
1 class iterator{
public:
iterator(): current(NULL){} Object & operator*()const{
return current->data;
} iterator & operator++(){
current = current->next;
return *this;
} iterator operator++(int){
iterator old = *this;
++(*this);
return old;
} bool operator==(const iterator& rhs)const{
return current == rhs.current;
} bool operator!=(const iterator& rhs)const{
return !(*this == rhs);
} protected:  //protected一般在有继承的情况下使用,这个地方我就懒得改了
Node* current; //iterator是链表中一个具体位置的抽象, current指针用于指向所选定的节点 iterator(Node* p): current(p){} //iterator类型主要使用的构造函数 friend class circleSingleLinkedList<Object>;//使外层包含类也可以访问iterator的非public成员
};

剩下的就是循环单链表的定义,在这里我就想着重讲一下insert以及erase方法,begin()函数,默认构造函数(初始化头结点)以及print函数(输出链表各节点的data数据)这里就不提了。

insert(位置,数值),因为这是单链表,不能通过一个位置来确定它之前的位置(没有指向前一个节点的指针),所以insert是在itr所确定的元素的后面插入一个新节点,函数返回新节点处的位置.
需要注意的是,insert与erase都是的返回类型都是copy passing的,具体原因我暂时还搞不清楚.
1 iterator insert(iterator itr, const Object& x){
Node* p = itr.current;
Node* newNode = new Node(x, p->next);
p->next = newNode;
theSize++;
return iterator(newNode);
7 }

erase函数

 erase(位置),删除itr位置之后的元素,原理与insert相同,如果删除的元素师头节点,则将头节点分配给原头节点的下一个元素
1 iterator erase(iterator itr){
Node* p = itr.current;
if(p->next == head)
  head = head->next;
Node* old = p->next->next;
delete p->next;
p->next = old;
theSize--;
return itr;
}
  • 接下来我们来看一下main函数中的实际应用情况,也就是约瑟夫环问题。
 int main()
{
circleSingleLinkedList<int> iList();  //初始化循环链表,其包含一个头节点,由head指针指向,头指针指向的元素就是约瑟夫环问题中的第一个人,编号为1 int n;
cout << "n=" << endl;    //输入约瑟夫环问题中的人数n
cin >> n; int i=;
circleSingleLinkedList<int>::iterator iter = iList.begin();  //初始化iter指向头节点
while(i <= n){
iter = iList.insert(iter,i);  //为链表添加节点元素,每一次都添加到iter所抽象的元素的下一个,其数值为i
++i;
} iter = iList.begin();    //iter重新指向表头 int m;
cout << "m=" << endl;    //输入约瑟夫环问题中的步值m,也就是每做一次删除所数的一个步长
cin >> m; i = ;
while(iList.empty() != true){
while(i < m){      //由于erase是删除iter所指向的下一个元素,而不是删除iter,所以iter需要代表被删除元素之前的一个元素.
++iter;
++i;
}
iter = iList.erase(iter);
iList.print(cout);    //每做一次删除就输出显示整个list.
i = ;
} cout << endl; return ;
}
  • 最后结果:

        

        输入n=10, m=3, 由于我默认程序从第一个节点(1)开始数,所以第一个删除的节点是4(也就是编号为4的人),删除之后,从4的下一个节点(5)开始数3,第二个删除的元素为8,以此类推.

  • 总结:这是第一次用数据结构和C++解决实际问题,也是第一次发博文,目前对数据结构的理解是,其是对内存空间进行某种特定规律的管理的一种手段,以特殊的策略实现功能程序的优化。

             希望继续练习,熟悉更多的结构。

      2013-11-08 11:12:23

简单约瑟夫环的循环单链表实现(C++)的更多相关文章

  1. C代码实现非循环单链表

    C代码实现非循环单链表, 直接上代码. # include <stdio.h> # include <stdlib.h> # include <malloc.h> ...

  2. PTA 循环单链表区间删除 (15 分)

    本题要求实现带头结点的循环单链表的创建和单链表的区间删除.L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于m ...

  3. C语言版本:循环单链表的实现

    SClist.h #ifndef __SCLIST_H__ #define __SCLIST_H__ #include<cstdio> #include<malloc.h> # ...

  4. c语言循环单链表

    /************************************************************************* > File Name: singleLin ...

  5. c语言有头循环单链表

    /************************************************************************* > File Name: singleLin ...

  6. 【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

    所实现的循环单链表的结构例如以下图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill ...

  7. 带头结点的循环单链表----------C语言

    /***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...

  8. 循环单链表定义初始化及创建(C语言)

    #include <stdio.h> #include <stdlib.h> /** * 含头节点循环单链表定义,初始化 及创建 */ #define OK 1; #defin ...

  9. 用最简单的方式学Python单链表

    Python 实现单链表 在本博客中,我们介绍单链表这种数据结构,链表结构为基于数组的序列提供了另一种选择(例如Python列表). 基于数组的序列和链表都能够对其中的元素保持一定得顺序,但采用的方式 ...

随机推荐

  1. angularjs modal 嵌套modal的问题

    anguarjs中当遇到modal嵌套modal的时候,比如一个modal弹出啦一个modal1,关闭modal1后,modal本身的关闭功能失效,那么需要$modal来生命弹出的modal1并且关闭 ...

  2. swift把汉字转换为拼音,并且截取首字母做索引用

    var transformContents = CFStringCreateMutableCopy(nil, 0, "咋啊的看到回复阿斯顿发货发哦iasdifas")CFStrin ...

  3. 限制UITextField/UITextView的输入字数与中文输入之后的英文换行问题

    要限制一个UITextField/UITextView的输入字数,首先想到的应该是通过UITextFieldDelegate/UITextViewDelegate的代理方法来限制,那么如何来更好的限制 ...

  4. 【HDU4348】【主席树】To the moon

    Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...

  5. CPU风扇故障导致自动关机

    今天在使用电脑时,突然自动关机,重启后过一段时间又自动关机,于是打开机箱后盖,插上电源观察各个部位运行情况,发现CPU风扇不转,判断问题就是由于CPU温度太高了.于是换个风扇,再开机情况就正常了.

  6. CSS3 :nth-child() 选择器

    CSS3 :nth-child() 选择器 代码: <!DOCTYPE html> <html> <head> <style> p:nth-child( ...

  7. 搭建BCE本地开发环境

    1. 在官网下载VirtualBox & 虚拟机 http://bce.baidu.com/doc/BAE/GUIGettingStarted.html#.E4.B8.8B.E8.BD.BD. ...

  8. Cocos2d-x中Vector使用

    1.创建Vector对象 Vector().默认的构造函数. Vector(ssize_t capacity).创建Vector对象,并设置容量. Vector(const Vector<T&g ...

  9. 兼容PHP和Java的des加密解密代码分享

    这篇文章主要介绍了兼容PHP和Java的des加密解密代码分享,适合如服务器是JAVA语言编写,客户端是PHP编写,并需要des加密解密的情况,需要的朋友可以参考下 作为一个iOS工程师来解决安卓的问 ...

  10. readline函数分析

    函数功能:提示用户输入命令,并读取命令/****************************************************************************/ /* ...