【实验目的】
帮助学生熟练掌握线性表的基本操作在顺序和链式两种存储结构上的实现,其中以各种链表的操作和应用作为重点内容。
【实验内容及要求】
- 问题描述:约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m的值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
- 基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
- 测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)。
- 实现提示:程序运行后,首先要求用户指定初始报数上限值,然后读取各人的密码。可设n≤30。此题所用的循环链表中不需要“头结点”,请注意空表和非空表的界限。
【实验代码】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
| #include <iostream> using namespace std;
struct circularList { int number; int passward; circularList *next; };
circularList * createList(int n); int getLength(circularList *); int getIndex(circularList *, circularList *); circularList * deleteList(circularList *, int);
int main() { int m, n; cout << "请输入报数初始上限值:" << endl; cin >> m; cout << "请输入参与报数的总人数" << endl; cin >> n;
if(n < 1 || m < 1) { cout << "人数或初始报数值非法!" << endl; return 0; }
circularList * josephRing; josephRing = createList(n); circularList * head = josephRing;
while(true) { if(getLength(josephRing) == 1) { deleteList(head,1); cout << "报数完毕!" << endl; break; }
for(int i = 0; i < m - 1; i++) { josephRing = josephRing->next; }
m = josephRing->passward;
if(getIndex(head,josephRing) == 1) { josephRing = head = deleteList(head,getIndex(head,josephRing)); } else { josephRing = deleteList(head,getIndex(head,josephRing)); } }
return 0; }
circularList * createList(int n) { circularList * head, * q, * p; head = q = NULL;
cout << "请依次输入每个人的密码: " << endl; for(int i = 0; i < n; i++) { q = new circularList; q->number = i + 1; cin >> q->passward;
if(head == NULL) { head = q; } else { p->next = q; } p = q; } p->next = head; cout << "循环链表创建成功! " << endl;
return head; }
int getLength(circularList * head) { circularList * p = head; int n = 0;
if(p->next == head) { return 1; }
while(true) { n++; p = p->next; if(p->next == head) { n++; break; } } return n; }
int getIndex(circularList * head, circularList * jos) { int n = 0; circularList * p = head;
if(p->next == head) { return 1; }
while(true) { if(p == jos) { n++; break; } n++; p = p->next; } return n; }
circularList * deleteList(circularList * head, int n) { circularList * p = head, * q; if(n < 0 || n > getLength(head)) { cout << "索引超出范围,删除失败!" << endl; return head; }
if(n == 1) { for(int i = 0; i < getLength(head) - 1; i++) { p = p->next; } q = p->next; p->next = q->next; head = p->next; } else { while(n-- > 2) { p = p->next; } q = p->next; p->next = q->next; }
cout << q->number << " " << "出列!" << endl; delete q;
return p->next; }
|