日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数独解、多解(数据结构、栈、回溯法)

發布時間:2024/1/8 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数独解、多解(数据结构、栈、回溯法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ?首先因為個人原因前段時間在解一個數獨,因為很難解不出來,再加上我王哥的啟發,就想的寫個程序來解決這類問題,于是就有了這篇文章。。。還有最近在學數據結構,里面很多東西用的都是比較繁瑣的解決辦法,比如鏈式存儲,鏈棧之類的,但這樣思路比較清晰。

? ? ? ? ? ? ? ?1.程序大致思路

? ? ? ? ?將數組元素全部初始化為0,然后將空位的行列入棧,然后開始給棧頂元素的空位逐步++;每次++都要判斷這個數填在這個空位合不合適,合適的話入棧下一個元素,否則就出棧,這樣就回溯到了上一個空位,繼續++,這樣當最后一個空位解決后,就出現了數獨的第一個解,然后解決多解的話,將此時的棧頂元素出棧,給棧頂元素++,將指針指向上一個空位,利用goto語句來實現數獨的多解;

? ? ? ? ? ? ? 2.代碼改進思路

? ? ? ? ? 如果不用數據結構的鏈棧知識的話,可將棧直接簡化成 s[M],top來進行出入棧操作,這樣代碼的行數將大大減少。

? ? ? ? ? ? ? 3.程序功能:

? ? ? ? ? 可以進行數獨的解(多解)。

? ? ? ? ? ?如果出現解比較多的數獨,機器運行時間比較長;

? ? ? ? ? ? ? 4.關鍵代碼解析

?????????利用while進入循環(注:因為循環條件是p->next!=NULL,如果循環條件是p!=NULL的話,當指針p指向鏈表的最后一個元素的話,進入這條語句,最后一個空位肯定合適,所以指針p還會往后移一個,所以就找不到p的位置了,也就無法回溯(p=p->before);所以解決辦法就是p->next!=NULL,并且存鏈表的時候在末端多存一個垃圾值);循環里面入棧,然后進行do while先從0++一次,然后通過qualified函數判斷空位能不能填這個數字,能的話返回0跳出循環,不能繼續do while。然后通過if判斷,是通過怎樣的方式跳出循環的:if跳出循環后a[row1][list1]<10就證明,這個數字可以填在此時的空位,則指針往后移動,下一個入棧,else則說明1-9沒有合適的數字填到這個空位,則給這個空位初始化為0,出棧,將指針回調,繼續循環。

? ? ? ? ? ? ? ? ? 5.程序源代碼:

#include<stdio.h> #include<malloc.h> #include<stdlib.h>int a[9][9]={0};typedef struct nood {int row;int list;struct nood *next; }LinkList;typedef struct Stack //申明一個棧 {LinkList *top;LinkList *bottom; }LinkStack;typedef struct nood_1 // 申明一個雙鏈表 {int row;int list;struct nood_1 *next;struct nood_1 *before; }DulLinkList;void init_Stack(LinkStack *s) // 棧的初始化 {s->top=(LinkList *)malloc(sizeof(LinkList));s->bottom=s->top;s->top->next=NULL; }DulLinkList *init_DulLinkList(DulLinkList *head) //雙鏈表的初始化 {head=(DulLinkList *)malloc(sizeof(DulLinkList));head->next=NULL;head->before=NULL;return head; }void push_Stack(LinkStack *s,int row1,int list1) //入棧操作 {LinkList *p;p=(LinkList *)malloc(sizeof(LinkList));p->row=row1;p->list=list1;p->next=s->top;s->top=p; }void push_DulLinkList(DulLinkList *head,int row1,int list1) //把數獨空位的行列保存到雙鏈表里方便操作 {DulLinkList *p,*r;r=head;while(r->next!=NULL){r=r->next;}p=(DulLinkList *)malloc(sizeof(DulLinkList));p->row=row1;p->list=list1;r->next=p;p->before=r;p->next=NULL; }int empty_Stack(LinkStack *s) //棧的判空 {if(s->top==s->bottom)return 1;else return 0; }void pull_Stack(LinkStack *s,int *row1,int *list1) // 出棧操作 {LinkList *p;p=s->top;*row1=p->row;*list1=p->list;s->top=p->next;free(p); }void print_shudu() //打印此時數獨的結果 {int i,j;printf("數獨結果為:\n");for(i=0;i<9;i++){for(j=0;j<9;j++){if(a[i][j]==0){printf("| "); }elseprintf("|%2d ",a[i][j]);if(j==8)printf("|");}printf("\n\n");} }int qualified(int x,int row,int list) //判斷填的數字在這個空位的 行、 列 、九宮格是否合適 { int i,j,f1,f2;for(i=0;i<row;i++)if(a[i][list]==x)return 1;for(i=row+1;i<9;i++)if(a[i][list]==x)return 1;for(i=0;i<list;i++)if(a[row][i]==x)return 1;for(i=list+1;i<9;i++)if(a[row][i]==x)return 1;f1=row-row%3;f2=list-list%3;for(i=f1;i<f1+3;i++){for(j=f2;j<f2+3;j++){if((i!=row)||(j!=list)){if(a[i][j]==x)return 1;}}}return 0; }int jie(LinkStack *s,DulLinkList *head) //利用回溯法開始對數獨的空位逐個解決 {int i,j,row1,list1,flag=1,c1,c2;DulLinkList *p,*q;q=head;p=head->next; f1: while(p->next!=NULL){push_Stack(s,p->row,p->list);row1=s->top->row;list1=s->top->list;do{a[row1][list1]++;}while(a[row1][list1]<10 && qualified(a[row1][list1],row1,list1));if(a[row1][list1]<10){p=p->next;}else{a[row1][list1]=0;pull_Stack(s,&c1,&c2);p=p->before;}}if(p!=q){printf("這個數獨的第%d個解為:\n",flag);print_shudu();}if(p==q)return 0;else{pull_Stack(s,&c1,&c2);a[c1][c2]++;p=p->before;flag++;goto f1;} }int main() {LinkStack S;DulLinkList *L;int i,j;init_Stack(&S);L=init_DulLinkList(L);printf("please enter a sudoku :\n");for(i=0;i<9;i++){for(j=0;j<9;j++){scanf("%d",&a[i][j]);if(a[i][j]==0){push_DulLinkList(L,i,j); }}}push_DulLinkList(L,-1,-1);system("CLS");print_shudu();if(jie(&S,L)==0)printf("這個數獨無解\n"); }

? ? ? ? ? ? ? ? ? ? ?6.程序待解決的問題:

? ? 出現無解,他會直接退出程序,并不會提示,程序的時間復雜度也比較高

? ? ? ? ? ? ? ? ? ? ?7.數獨提供樣例:

3 0 6 4 5 1 8 7 9 0 4 5 7 0 9 2 0 0 7 0 9 2 0 0 1 4 5 0 0 3 5 4 7 6 9 0 0 0 0 0 9 0 0 1 2 6 0 8 0 2 3 4 0 0 5 0 1 0 0 2 9 6 4 8 6 4 0 0 5 7 2 3 9 7 2 3 6 4 0 8 0 0 0 0 5 0 0 9 2 7 2 3 0 1 7 9 0 6 0 0 0 0 0 4 0 0 3 5 1 0 3 4 0 0 0 0 0 0 0 0 0 0 8 0 0 0 8 0 0 0 0 2 0 0 0 0 1 4 7 2 0 0 0 6 6 0 0 9 3 1 7 0 0 0 7 2 8 0 4 0 0 00 0 0 0 0 0 0 0 0 0 8 0 0 7 0 0 3 0 0 0 0 0 0 0 0 0 0 7 0 0 0 1 0 0 0 3 0 0 0 0 0 6 0 0 0 0 0 2 0 0 0 4 0 0 0 0 0 0 5 0 0 0 0 0 4 0 0 6 0 0 9 0 6 0 0 0 0 0 3 0 0

這里特別感謝我王哥的幫助,沒他就沒這些思路和BUG的解決,程序也有太多問題,如果有大佬發現問題或者有更好的解決辦法的話滴滴我,感謝感謝!!!

總結

以上是生活随笔為你收集整理的数独解、多解(数据结构、栈、回溯法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。