数据结构与算法——循环链表的算法实现(Joseph 问题)
Joseph 问题:
如果有10 个人,按编号顺序1,2,。。。,10 顺时针方向围成一圈。从1 号开始顺时针方向1,2,。。。,9 报数,凡报数9 者出列(显然,第一个出圈为编号9 者)。
最后一个出圈者的编号是多少?
第5 个出圈者的编号是多少?z
.
代码实现
1 #include<iostream> 2 #include<string> 3 #include<stdlib.h> 4 5 using namespace std; 6 7 typedef struct _LinkNode 8 { 9 int data; //结点的数据域 10 struct _LinkNode* next; //结点的指针域 11 }LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型 12 13 void LinkPrint(LinkList* L); 14 15 bool InitList(LinkList*& L) //构造一个空的循环链表L 16 { 17 L = new LinkNode; //生成新结点作为头结点,用头指针L 指向头结点 18 if (!L)return false; //生成结点失败 19 L->next = L; //头结点的指针域指向自己 20 L->data = -1; 21 return true; 22 } 23 24 //尾插法 25 bool ListInsert_back(LinkList*& L, LinkNode* node) 26 { 27 LinkNode* last = NULL; 28 if (!L || !node) return false; 29 30 //找到最后一个节点 31 last = L; 32 while (last->next != L) last = last->next; 33 34 //新的节点链接到最尾部 35 node->next = L; 36 last->next = node; 37 38 return true; 39 } 40 41 bool Joseph(LinkList*& L, int interval) 42 { 43 //在带头结点的循环链表L 中,每个interval 个间隔循环删除节点 44 LinkList* p, * q; 45 int j = 0, i = 0; 46 int times = 0, num = 0; 47 p = L; 48 49 if (!L || p->next == L) { 50 cout << "链表为空!" << endl; 51 return false; 52 } 53 54 if (interval < 1) 55 { 56 cout << "报数淘汰口令不能小于1!" << endl; 57 return false; 58 } 59 60 do 61 { 62 i += interval; 63 while ((p->next)) //查找第i 个结点,p 指向该结点的上一个节点 64 { 65 if (p->next != L) j++; 66 if (j >= i) break; 67 p = p->next; 68 } 69 times++; 70 71 /*if (!(p->next)||(j>i))//当i>n 或i<1 时,删除位置不合理 72 return false;*/ 73 74 q = p->next; //临时保存被删结点的地址以备释放空间 75 num = q->data; 76 if (times == 5)cout << "第 5 个出圈的编号是:" << num << endl; 77 printf("cur: %d last: %d next:%d\n", q->data, p->data, q->next->data); 78 p->next = q->next; //改变删除结点前驱结点的指针域 79 delete q; //释放被删除结点的空间 80 LinkPrint(L); 81 } while (L->next != L); //链表不为空,继续报数 82 cout << "最后一个出圈的编号是:" << num << endl; 83 84 return true; 85 } 86 87 void LinkPrint(LinkList* L) //循环链表的输出 88 { 89 LinkList* p; 90 if (!L || L == L->next) { 91 cout << "链表为空!" << endl; 92 return; 93 } 94 p = L->next; 95 while (p != L) 96 { 97 cout << p->data << "\t"; 98 p = p->next; 99 } 100 cout << endl; 101 } 102 103 int main() 104 { 105 int i, x; 106 LinkList* L; 107 LinkNode* s; 108 109 //1. 初始化一个空的循环链表 110 if (InitList(L)) 111 { 112 cout << "初始化一个空的循环链表!\n"; 113 } 114 115 //2. 创建循环链表(尾插法) 116 std::cout << "尾插法创建循环链表, 插入 10 个元素..." << endl; 117 i = 0; 118 119 while ((++i) <= 10) 120 { 121 s = new LinkNode;//生成新结点 122 s->data = i; //输入元素值赋给新结点的数据域 123 s->next = NULL; 124 if (ListInsert_back(L, s)) { 125 cout << "插入成功!" << endl; 126 } 127 else { 128 cout << "插入失败!" << endl; 129 } 130 } 131 132 cout << "尾插法创建循环链表输出结果:\n"; 133 LinkPrint(L); 134 135 //3. 解答约瑟夫问题 136 Joseph(L, 9); 137 system("pause"); 138 return 0; 139 }
===================================================================================================================