循环链表:魔术师发牌问题
魔術(shù)師發(fā)牌問題介紹
魔術(shù)師發(fā)牌問題的簡介:一位魔術(shù)師掏出一疊撲克牌,魔術(shù)師取出其中13張黑桃,洗好后,把牌面朝下。
說:“我不看牌,只數(shù)一數(shù)就能知道每張牌是什么?”魔術(shù)師口中念一,將第一張牌翻過來看正好是A;
魔術(shù)師將黑桃A放到桌上,繼續(xù)數(shù)手里的余牌,
第二次數(shù)1,2,將第一張牌放到這疊牌的下面,將第二張牌翻開,正好是黑桃2,也把它放在桌子上。
第三次數(shù)1,2,3,前面二張牌放到這疊牌的下面,取出第三張牌,正好是黑桃3,這樣依次將13張牌翻出,全部都準(zhǔn)確無誤。
求解:魔術(shù)師手中牌的原始順序是什么樣子的?
魔術(shù)師發(fā)牌問題分析
每數(shù)一張沒有翻的牌 將其放到這疊牌的下面,不就形成了一個循環(huán)鏈表嗎,將翻開的牌 就是知道點(diǎn)數(shù)的牌 放桌子上,不就是在循環(huán)鏈表中跳過已經(jīng)知道數(shù)據(jù)的結(jié)點(diǎn)么,該結(jié)點(diǎn)不算作數(shù)牌數(shù)量中。
我們只需要將魔術(shù)師翻牌的情況反映到牌的點(diǎn)數(shù),也就是我們結(jié)點(diǎn)的data數(shù)據(jù)就ok,結(jié)束條件就是數(shù)牌 數(shù)到第13次 就結(jié)束。
以下三點(diǎn)一定要明確
1、采用循環(huán)鏈表進(jìn)行數(shù)據(jù)的填充。
2、翻過得牌放桌子上,就是有數(shù)據(jù)的牌 不算作數(shù)牌數(shù)量,這一點(diǎn)一定要明確,代碼中有體現(xiàn)。
3、第13次數(shù)完 就結(jié)束了,所有牌的數(shù)據(jù)已經(jīng)填充完畢。
魔術(shù)師發(fā)牌代碼展示
代碼很詳細(xì),只要清晰知道發(fā)牌情況的本質(zhì),代碼就呼之欲出了。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define OK 1 #define ERROR 0typedef struct Node {int data;struct Node* next; } Node,*LinkList; /* 創(chuàng)建循環(huán)鏈表 */ int CreateCard(Node** circle_list, int num) {//創(chuàng)建循環(huán)鏈表頭結(jié)點(diǎn)Node* head = (Node*)malloc(sizeof(Node));Node* temp = head;// temp 移動指針,指向環(huán)中的結(jié)點(diǎn),剛開始指向頭結(jié)點(diǎn)int i = 0;//創(chuàng)建num個結(jié)點(diǎn)的循環(huán)鏈表while (i < num){//創(chuàng)建新結(jié)點(diǎn)并初始化數(shù)據(jù)Node* node = (Node*)malloc(sizeof(Node));if (node == NULL){exit(0);}node->data = 0;node->next = NULL;//將結(jié)點(diǎn)加入到鏈表中temp->next = node;temp = node;i++;}//循環(huán)結(jié)束 temp 指向最后一個結(jié)點(diǎn)//將最后一個結(jié)點(diǎn) 指向環(huán)中第一個結(jié)點(diǎn),就構(gòu)成了一個不帶頭結(jié)點(diǎn)的循環(huán)單鏈表temp->next = head->next;//循環(huán)鏈表指向第一個結(jié)點(diǎn)*circle_list = head->next;//釋放頭結(jié)點(diǎn)free(head);return OK; } /* 魔術(shù)師發(fā)牌情況體現(xiàn)到循環(huán)鏈表的結(jié)點(diǎn)數(shù)據(jù)上。 魔術(shù)師發(fā)牌問題的簡介:一位魔術(shù)師掏出一疊撲克牌,魔術(shù)師取出其中13張黑桃,洗好后,把牌面朝下。 說:“我不看牌,只數(shù)一數(shù)就能知道每張牌是什么?”魔術(shù)師口中念一,將第一張牌翻過來看正好是A; 魔術(shù)師將黑桃A放到桌上,繼續(xù)數(shù)手里的余牌, 第二次數(shù)1,2,將第一張牌放到這疊牌的下面,將第二張牌翻開,正好是黑桃2,也把它放在桌子上。 第三次數(shù)1,2,3,前面二張牌放到這疊牌的下面,取出第三張牌,正好是黑桃3,這樣依次將13張牌翻出,全部都準(zhǔn)確無誤。 求解:魔術(shù)師手中牌的原始順序是什么樣子的? */ int Magician(Node* circle_list) {//node指向循環(huán)鏈表Node* node = circle_list;//根據(jù)發(fā)牌規(guī)則,給牌賦值//第一張牌 是1node->data = 1;//數(shù)牌的數(shù)量,初始化為2 ,數(shù)牌數(shù)量<=13int cardnum = 2;while (1){//循環(huán)進(jìn)行數(shù)牌,注意已經(jīng)翻過得牌放到桌子上for (size_t i = 0; i < cardnum; i++){node = node->next;//說明此張牌有數(shù)據(jù),已經(jīng)被翻過,不算作數(shù)牌數(shù)量if (node->data != 0){i--;}}//被翻牌的牌點(diǎn)數(shù) = 數(shù)牌的數(shù)量,第二次 數(shù)2張 ,翻第二張 為黑桃2;第三次 數(shù)3張 翻第三張 為黑桃3...node->data = cardnum;//牌已經(jīng)數(shù)完了if (cardnum == 13){break;}cardnum++;}return OK; } //展示牌的點(diǎn)數(shù) int ShowCards(Node* circle_list) {Node* node = circle_list;//node為移動指針,node 開始指向循環(huán)鏈表第一個結(jié)點(diǎn)//循環(huán)鏈表遍歷完判斷,尾結(jié)點(diǎn)的指針域指向第一個結(jié)點(diǎn)while (node->next != circle_list){printf("黑桃:%d\n",node->data);node = node->next;}return OK; }int main(int argc, char *argv[]) {Node* circle_list = NULL;//創(chuàng)建13空牌CreateCard(&circle_list, 13);//根據(jù)魔術(shù)師翻牌的結(jié)果,給牌填充數(shù)據(jù)Magician(circle_list);//展示牌的點(diǎn)數(shù)ShowCards(circle_list);return 0; }魔術(shù)師發(fā)牌問題結(jié)果
總結(jié)
以上是生活随笔為你收集整理的循环链表:魔术师发牌问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Octave: 'rgb2gray' u
- 下一篇: python语法学习—打印九九乘法表