循环链表:拉丁方阵问题
生活随笔
收集整理的這篇文章主要介紹了
循环链表:拉丁方阵问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
拉丁方陣問題介紹
拉丁方陣是一種n×n的方陣,方陣中恰有n種不同的元素,每種元素恰有n個,并且每種元素在一行和一列中 恰好出現一次。著名數學家和物理學家歐拉使用拉丁字母來作為拉丁方陣里元素的符號,拉丁方陣因此而得名。例如下面是一個3×3的拉丁方陣:
1 2 3
2 3 1
3 1 2
拉丁方陣問題分析
矩陣的第一行是 1 2 3 從第一個元素開始到最后一個元素。
矩陣的第二行是 2 3 1 從第二個元素開始到 循環1圈的最后一個元素。
矩陣的第三行是 1 2 3 從第三個元素開始到 循環1圈的最后一個元素。
不難找出規律:矩陣的第n行,元素是從第n個元素 循環遍歷完一圈的數據。
那我們自己推導2 ?5 ?8 ?10的拉丁方陣是
2?5?8?10
5?8?10?2
8?10?2?5
10?2?5?8
符合拉丁方陣的要求吧。
從代碼角度來實現,主要思路如下:
1、用循環鏈表來接受n個不同的數據。
2、矩陣第i行數據,是從循環鏈表的第i個位置的數據遍歷完整個循環鏈表 將其數據取出。
拉丁方陣代碼展示
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define OK 1 #define ERROR 0typedef struct Node {int data;struct Node* next; } Node, *LinkList; /* 創建循環鏈表 */ int CreatCircleList(Node** circle_list,int n) {printf("請輸入%d個不同的數字:",n);int i = 0;//創建頭結點Node* head = (Node*)malloc(sizeof(Node));Node* temp = head;//temp 移動指針,剛開始指向頭結點while (i < n){int data=0;scanf("%d",&data);//創建結點并初始化數據Node* node = (Node*)malloc(sizeof(Node));node->data = data;node->next = NULL;//將結點添加到循環鏈表中temp->next = node;temp = node;i++;}//循環結束 temp指向最后一個結點,讓其指向第一個結點,形參循環列表temp->next = head->next;//循環鏈表指向第一個結點*circle_list = head->next;//釋放頭結點free(head);return OK;} //獲取循環鏈表長度 int LengthCircleList(Node* circle_list) {if (circle_list == NULL){return 0;}int i = 1;Node* node = circle_list;//node為移動指針,node 開始指向循環鏈表第一個結點//循環鏈表遍歷完判斷,尾結點的指針域指向第一個結點while (node->next != circle_list){node = node->next;i++;}return i; } /* 顯示拉丁方陣 */ int ShowLatin(Node* latin_list) {int len = LengthCircleList(latin_list);Node* first = latin_list;for (size_t i = 0; i < len; i++){Node* node = first;int j = 0;/*找到開始結點第一行 開始結點為 循環鏈表第1個位置結點第二行 開始結點為 循環鏈表第2個位置結點第N 行 開始結點為 循環鏈表第n個位置結點*/while(j < i){node = node->next;j++;}Node * begin = node;int k = 0;//遍歷完這個循環列表while(k<len){printf("%d\t",begin->data); begin = begin->next;k++;}printf("\n");}return OK; } //銷毀鏈表釋放內存 int DestroyCricleList(Node* circle_list) {if (circle_list == NULL){return ERROR;}Node* node = circle_list;//node為移動指針,node 開始指向循環鏈表第一個結點//循環鏈表遍歷完判斷,尾結點的指針域指向第一個結點while (node->next!= circle_list){Node* temp = node;node = node->next;free(temp);}//釋放最后一個結點free(node);return OK; }int main(int argc, char *argv[]) {Node* circle_list = NULL;while (1){printf("請輸入拉丁方陣的階數(0退出):");int n = 0;scanf("%d", &n);if (n == 0){break;}CreatCircleList(&circle_list,n);ShowLatin(circle_list);DestroyCricleList(circle_list);}circle_list = NULL;return 0; }
拉丁方陣結果展示
總結
以上是生活随笔為你收集整理的循环链表:拉丁方阵问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java内部类详解(Mark)
- 下一篇: oracle中的日期查询在mybatis