• [C语言、C++]数据结构作业:用双向链表实现折返约瑟夫问题


    请使用合适的数据结构实现:使用“折返报数”方式的Joseph问题。
    所谓“折返报数”Joseph问题是指:
    (1)n(n>1)个人排成一队,从1到n依次编号;从1到m循环报数,报到m(m>1)者退出;
    (2)游戏先从编号为1的人(队头)开始依次从前向后报数,当报数到达队尾时,立即改为从后往前报数;
    (3)当从后往前报数到达队头时,立即改为从前往后报数;
    (4)如此“折返”报数,直到队列中只剩下1人为止,即为胜者;
    要求:
    (1)从键盘输入n和m;
    (2)依次输出游戏过程中退出人的编号;
    (3)输出获胜者编号;
    例:
    输入:n=5;m=3
    输出:
    3 4 2 5
    胜者:1

    1. #include
    2. using namespace std;
    3. typedef struct LinkNode {
    4. int data;
    5. LinkNode* next;
    6. LinkNode* pre;
    7. }*LinkList;
    8. void InitLinkList(LinkList& L) {
    9. L = NULL;
    10. }
    11. void CreatRear(LinkList& L,int n) {
    12. L = NULL;
    13. if (n <= 0)return;
    14. else {
    15. L = new LinkNode;
    16. cin >> L->data;
    17. L->pre = NULL; L->next = NULL;
    18. if (n > 1) {
    19. LinkNode* r = L;
    20. for (int i = 1; i < n; i++) {
    21. LinkNode* s = new LinkNode;
    22. cin >> s->data;
    23. r->next = s;
    24. s->pre = r;
    25. r = r->next;
    26. }
    27. r->next = NULL;
    28. }
    29. }
    30. }
    31. void Returning_Joseph(int n, int m) {
    32. LinkList L; InitLinkList(L);
    33. CreatRear(L, n);
    34. LinkNode* p = L; int isBack = 0;
    35. for (int i = 0; i < n - 1; i++) {
    36. int j = 0;
    37. while (j < m - 1) {
    38. if (isBack == 0) {
    39. while (p->next != NULL && j < m - 1) {
    40. p = p->next; j++;
    41. }
    42. if (p->next == NULL)isBack = 1;
    43. }
    44. if (isBack == 1) {
    45. while (p->pre != NULL && j < m - 1) {
    46. p = p->pre; j++;
    47. }
    48. if (p->pre == NULL)isBack = 0;
    49. }
    50. }
    51. cout << p->data << " ";
    52. LinkNode* r = p;
    53. if (p->next == NULL || p->pre == NULL) {
    54. if (p->next == NULL) {
    55. p = p->pre;
    56. delete(p->next);
    57. }
    58. else {
    59. p = p->next;
    60. delete(p->pre);
    61. }
    62. }
    63. else {
    64. p->pre->next = p->next;
    65. p->next->pre = p->pre;
    66. if (isBack == 0)p = p->next;
    67. else p = p->pre;
    68. r->next = NULL; r->pre = NULL;
    69. delete(r);
    70. }
    71. }
    72. cout << endl;
    73. cout << p->data << "是胜者";
    74. }
    75. int main(){
    76. Returning_Joseph(5, 3);
    77. }

    此题难点在于在约瑟夫问题的基础上摒弃了环的结构,而是改为“折返”,所以自然想到双向链表(无头),但难点在于,如何让程序知道现在是向前遍历还是向后遍历呢?

    这里我们设一个初始值 isBack==0,来判断现在是向前还是向后遍历,如果超过了边界,那么更改isBack的值进入到另一个向前遍历的分支即可,如此循环,即可实现“折返” 

  • 相关阅读:
    正则表达式=》判断中文字
    oracle 12c+ max_string_size参数
    android studio安卓模拟器高德SDK定位网络连接异常
    柯桥基础俄语口语|初级俄语学习:用联想法学习字母
    动手学深度学习(1)—— 基础知识
    JSP ssm 特殊人群防走失系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计
    java中的serializable接口作用
    java内存区域
    认识ARP协议
    pagehelper 分页写法
  • 原文地址:https://blog.csdn.net/ZDEWBYE/article/details/127704936