首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言實現順時針打印矩陣:螺旋遍歷算法詳解與動態內存管理

     編輯:關於C

問題描述

給定行數 n、列數 m,生成一個 n×m 矩陣,按順時針螺旋順序填入 1 到 n*m,並打印矩陣。

示例(3×4):


  1  2  3  4
 10 11 12  5
  9  8  7  6

核心思路:層層剝洋蔥

矩陣可視為 min(n,m)/2 層同心矩形。每層按 上→右→下→左 四邊依次填充。

完整優化代碼


#include 
#include 

void spiral_print(int rows, int cols) {
    if (rows <= 0 || cols <= 0) return;

    // 1. 動態分配二維數組
    int **matrix = (int **)calloc(rows, sizeof(int *));
    for (int i = 0; i < rows; i++)
        matrix[i] = (int *)calloc(cols, sizeof(int));

    int layer = 0;          // 當前層 (0-based)
    int num = 1;            // 待填入數字
    int max_num = rows * cols;

    while (num <= max_num) {
        int top = layer, bottom = rows - 1 - layer;
        int left = layer, right = cols - 1 - layer;

        // 上邊:左→右
        for (int c = left; c <= right && num <= max_num; c++)
            matrix[top][c] = num++;
        top++;

        // 右邊:上→下
        for (int r = top; r <= bottom && num <= max_num; r++)
            matrix[r][right] = num++;
        right--;

        // 下邊:右→左
        for (int c = right; c >= left && num <= max_num; c--)
            matrix[bottom][c] = num++;
        bottom--;

        // 左邊:下→上
        for (int r = bottom; r >= top && num <= max_num; r--)
            matrix[r][left] = num++;
        left++;

        layer++;
    }

    // 打印
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++)
            printf("%4d", matrix[r][c]);
        putchar('\n');
    }

    // 釋放內存
    for (int i = 0; i < rows; i++) free(matrix[i]);
    free(matrix);
}

int main() {
    int n, m;
    printf("請輸入行數 列數: ");
    if (scanf("%d %d", &n, &m) == 2)
        spiral_print(n, m);
    return 0;
}

關鍵邏輯解析

邊界收縮策略

每完成一圈,四個邊界向內收縮:

  • top++、bottom--、left++、right--
  • 循環條件 num <= max_num 防止單行/單列矩陣重複填充

動態二維數組分配


int **matrix = calloc(rows, sizeof(int *));  // 行指針數組
for (int i = 0; i < rows; i++)
    matrix[i] = calloc(cols, sizeof(int));   // 每行數據區
// 釋放時逆序
for (int i = 0; i < rows; i++) free(matrix[i]);
free(matrix);

注意:這是指針數組模擬二維數組,行內存不連續。若需連續內存,用 int (*matrix)[cols] = malloc(rows * sizeof(*matrix)) (C99 VLA) 或 malloc(rows * cols * sizeof(int)) 手動計算索引。

複雜度分析

  • 時間:O(n×m) — 每個元素恰好訪問/賦值一次
  • 空間:O(n×m) — 存儲矩陣;若只打印不存,可優化至 O(1)

變體擴展

變體修改要點
逆時針螺旋順序改為:上→左→下→右
從中心向外計算中心點,層數向外擴展
不規則矩陣打印同樣邊界收縮邏輯,無需存儲
LeetCode 54/59輸入已有矩陣返回數組 / 生成矩陣

常見錯誤與調試

  • 單行/單列重複:缺少 num <= max_num 判斷導致回頭覆蓋
  • 邊界計算越界:right = cols - 1 - layer 而非 cols - layer
  • 內存洩漏:忘記釋放行指針數組或數據區
  • 輸入驗證缺失:負數、零行列導致分配失敗

總結

螺旋矩陣是考察邊界控制、循環不變量、動態內存管理的經典題目。掌握「四邊界收縮」模板,能輕鬆應對所有螺旋遍歷變體。工程上注意內存分配/釋放配對、輸入合法性檢查、邊界條件測試(1×N、N×1、1×1、0×0)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved