python实现约瑟夫环(链式存储结构 )_简单约瑟夫环的循环单链表实现(C++)

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

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

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

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

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

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

基本结构:

template

class circleSingleLinkedList{

private:

/*循环单链表的每个的节点定义

*结构简单,所以使用struct

*具体实现请看下文

*/

struct Node{

};

public:

/*内嵌类iterator

*是链表中的一个位置的抽象(abtracts the notion of a position)

*类比vector<>的iterator

*在类外的调用方法为:circleSingleLinkedList::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;//使外层包含类也可以访问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 iList();  //初始化循环链表,其包含一个头节点,由head指针指向,头指针指向的元素就是约瑟夫环问题中的第一个人,编号为1

int n;

cout << "n=" << endl;    //输入约瑟夫环问题中的人数n

cin >> n;

int i=;

circleSingleLinkedList::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代码实现非循环单链表

C代码实现非循环单链表, 直接上代码. # include # include # include ...

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

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

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

SClist.h #ifndef __SCLIST_H__ #define __SCLIST_H__ #include #include # ...

c语言循环单链表

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

c语言有头循环单链表

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

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

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

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

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

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

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

约瑟夫环 c&plus;&plus; 循环输入

#include #include #include #include us ...

随机推荐

使用socket方式连接Nginx优化php-fpm性能

Nginx连接fastcgi的方式有2种:TCP和unix domain socket 什么是Unix domain socket?-- 维基百科 Unix domain socket 或者 IPC ...

java中日历代码的实现

import java.util.Scanner; com.lv.calendarWatch//包名 /* * 需求:输入一个年份和月份 ,显示当前月日情况 ,星期数要对应准确 * 1.1900年1月 ...

ubuntu安装miniconda

系统:ubuntu15.04   64位 wget -c http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh chm ...

ansible笔记

ansible 资料 ansible 配置 ansible inventory配置文件 ansible模块 http://www.cnblogs.com/iois/p/6216936.html ans ...

Java实现应用程序记住用户名、密码功能

1.      从网上下载jquery.cookie.js,拷贝到应用程序中. 2.      登录页面(login.jsp)导入jquery.cookie.js

题目链接:http://poj.org/problem?id=3026 Svenskt Masterskap我程序员/ Norgesmesterskapet 2001 Description The ...

JavaScript重新介绍

本文转载自 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript 引言 为什么 ...

HTTP 请求头与请求体 - 某熊的全栈之路 - SegmentFault

本文从属于笔者的HTTP 理解与实践系列文章,对于HTTP的学习主要包含HTTP 基础.HTTP 请求头与请求体.HTTP 响应头与状态码.HTTP 缓存这四个部分,而对于HTTP相关的扩展与引申,我 ...

C&plus;&plus; 单例模式&lpar;转载&rpar;

转载:http://www.cnblogs.com/cxjchen/p/3148582.html 转载:http://blog.csdn.net/hackbuteer1/article/details ...

5 Django-2 的路由层 &lpar;URLconf&rpar;

URL 配置 (URLconf) 就像 Django 所支撑网站的目录.它的本质是 URL 与要为该 URL 调用的视图函数之间的映射表:你就是以这种方式告诉 Django,对于客户端发来的某个 UR ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值