簡單易懂的實現螺旋矩陣


最近在研究螺旋矩陣,一直網上搜,基本上都是只有代碼,也沒有什么解釋,有解釋的也看不太懂,於是自己仔細想了想,終於弄出來了,下面是解題的思路。

其實最初的算法,一定是由數學衍生過來的,自己想一想,我要你畫一個5*5的螺旋矩陣,你會怎么畫,每個人估計都是這樣

第一步:  1  2  3  4  5      //先畫一行

第二步:  1  2  3  4  5      //再畫一列 

                 6

                 7 

                 8

                 9


第三步:  1  2  3  4  5        //再這樣畫一行

                 6

                 7

                 8

     13  12 11  10   9

 再以此類推,我說的一定沒錯吧。

同樣的算法呢,也是類似這樣實現的。第一行,先依次輸入n個數,再豎着輸入n-1個,再橫着輸入n-1,再反豎着輸入n-2個數

        到第二圈了,同樣的,橫行輸入n-1-1個數字,也是同樣的類似步驟

 

下面我來寫一寫代碼,然后加上注釋,來理解一下這個代碼。

有些人說,要考慮n為奇數,和偶數,其實先不建議考慮,直接就先用n等於5來考慮,到時候偶數的時候會發現就一樣了。

package com.cidp.juZhen;
/**
 * 
 * 1	2	3	4	5
 * 16	17	18	19	6
 * 15	24	25	20	7
 * 14	23	22	21	8
 * 13	12	11	10	9
 * 
 * @author zzloyxt
 *
 */
public class LuoXuanZhen {
	public static void main(String[] args) {
		int n = 5; //表示定義一個5*5的矩陣,求螺旋矩陣
		int count = 1;  //表示模擬我們的畫數步驟,先從1開始畫,先畫一行
		int shu[][] = new int[n][n];  
		//要畫到哪行結束呢,是不是得要有3圈,即n/2+1 這種重復的4個方向的步驟,即使最后一圈只有25,但也是類似的
		
		//定義循環的步驟,要循環n/2+1次
		for(int i=0;i<n/2+1;i++) {
			//先從行開始遍歷,這時候一定要找關系,仔細想想
			for(int j=i;j<=n-i-1;j++) {
				shu[i][j] = count++; 
			}
			
			//遍歷一豎
			for(int j=i+1;j<=n-i-1;j++) {
				shu[j][n-i-1] = count++;
			}
			
			//遍歷底層一行
			for(int j=n-i-2;j>=i;j--) {
				shu[n-i-1][j] = count++;
			}
			
			//遍歷左邊一豎
			for(int j=n-i-2;j>=i+1;j--) {
				shu[j][i] = count++;
			}
		}
		
		//輸出這個矩陣
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				System.out.print(shu[i][j] + "\t");
			}
			System.out.println();
		}
	}

}

 這個就是具體的思路,還有不懂的歡迎留言

 

我后來發現一個弊端,就是這種方式只能實現  方形螺旋矩陣,就是行 = 列的情況,而我下面的方法更加的通用,就是任意指定的行和列都行

 

 

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
/*
	實現如下  給定行m和列n 的螺旋矩陣 
        1 	2       3   4   5   6
       	18	19      20  21  22  7
       	17	28	29  30  23  8
       	16 	27	26  25  24  9
       	15      14      13  12  11  10
*/

int m,n;

int main(){
	m = 5;  //5行 
	n = 6;  //6列 
	int maritx[m+1][n+1] = {0};  // 從1,1,開始,第0行,第0列不使用 
	int now = 1;
	int U = 1,D = m,L = 1,R = n;  // 上下左右的邊界 
	int i = 1,j = 1;    //從 數組1,1位置開始 
	while(now <= m*n){
		//先從左到右寫行 
		while(now <= m*n && j < R){
			maritx[i][j] = now++;
			j++;
		}
		//最右邊列,從上到下寫
		while(now <= m*n && i < D){
			maritx[i][j] = now++;
			i++;
		}
		//最后一行,從右到左 
		while(now <= m*n && j > L){
			maritx[i][j] = now++;
			j--;
		}
		//最后左邊列,從下往上 
		while(now <= m*n && i > U){
			maritx[i][j] = now++;
			i--;
		}
		U++,D--,L++,R--;
		i++,j++;
		
		
		//防止m = n 是正方形的情況最后一個數字
		if(now == m*n) {
			maritx[i][j] = now++;
		}
	} 
	
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			printf("%d\t",maritx[i][j]);
		}
		printf("\n");
	}
	
	return 0;
}

  

運行結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM