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

C語言二維數組動態操作:行列插入、元素交換與軌跡追蹤

     編輯:關於C

二維數組在圖像處理、棋盤遊戲、矩陣運算等場景中極為常見。本文實現一個功能完整的動態二維數組框架,支持任意位置插入行/列、元素交換、完整移動軌跡記錄,採用鏈表存儲每個邏輯位置的歷史坐標,展示指鋼操作與內存管理的深度結合。

核心數據結構

#define MAX_ROW 9
#define MAX_COL 9

// 坐標節點
typedef struct _Node { int x, y; } Node;

// 軌跡鏈表:記錄某邏輯位置歷經的所有物理坐標
typedef struct _PathNodeList {
    Node node;
    struct _PathNodeList *pNext;
} PathNodeList;

// 二維數組:每個格子掛一條軌跡鏈表
PathNodeList *g_pGrid[MAX_ROW][MAX_COL];

// 當前有效行列數
typedef struct { int row, col; } CurRowColNum;
static CurRowColNum g_size = {0};

關鍵操作實現

1. 初始化:為每個格子創建初始軌跡節點

int InitGrid(int rows, int cols) {
    if (rows > MAX_ROW || cols > MAX_COL) return -1;
    g_size.row = rows; g_size.col = cols;
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j) {
            Node n = {i, j};
            CreatePathNodelist(&g_pGrid[i][j], &n);  // 頭節點即初始位置
        }
    return 0;
}

2. 交換兩個邏輯元素(含軌跡遷移)

int SwapNode(Node a, Node b) {
    // 取得兩個邏輯位置的當前物理坐標(鏈表尾節點)
    Node *pa = GetCurPosition(g_pGrid[a.x][a.y]);
    Node *pb = GetCurPosition(g_pGrid[b.x][b.y]);

    // 將對方當前位置追加到自己的軌跡鏈表
    InsertPathNodeList(g_pGrid[a.x][a.y], pb);
    InsertPathNodeList(g_pGrid[b.x][b.y], pa);

    // 交換鏈表頭指針,完成邏輯位置映射切換
    PathNodeList *tmp = g_pGrid[a.x][a.y];
    g_pGrid[a.x][a.y] = g_pGrid[b.x][b.y];
    g_pGrid[b.x][b.y] = tmp;
    return 0;
}

3. 插入行:空行直接掛載,中間行需逐行下沉交換

int InsertRow(int insertRow) {
    if (insertRow >= g_size.row) {  // 追加到末尾
        for (int j = 0; j < g_size.col; ++j) {
            Node n = {insertRow, j};
            CreatePathNodelist(&g_pGrid[insertRow][j], &n);
        }
    } else {  // 中間插入:先在末尾創建空行,再逐行向上交換
        for (int j = 0; j < g_size.col; ++j) {
            Node n = {g_size.row, j};
            CreatePathNodelist(&g_pGrid[g_size.row][j], &n);
        }
        for (int i = g_size.row; i > insertRow; --i)
            for (int j = 0; j < g_size.col; ++j) {
                Node cur = {i-1, j}, nxt = {i, j};
                SwapNode(cur, nxt);  // 利用交換實現行下沉
            }
    }
    g_size.row++;
    return 0;
}

4. 插入列:邏輯對稱,逐列右移交換

int InsertCol(int insertCol) {
    if (insertCol >= g_size.col) { /* 追加列 */ }
    else {
        for (int i = 0; i < g_size.row; ++i) { /* 末尾創建空列 */ }
        for (int j = g_size.col; j > insertCol; --j)
            for (int i = 0; i < g_size.row; ++i) {
                Node cur = {i, j-1}, nxt = {i, j};
                SwapNode(cur, nxt);  // 列右移
            }
    }
    g_size.col++;
    return 0;
}

5. 查詢元素完整移動軌跡

int GetNodePath(Node logical, PathNodeList **ppOut) {
    if (logical.x < 0 || logical.x >= g_size.row ||
        logical.y < 0 || logical.y >= g_size.col) return -1;
    *ppOut = g_pGrid[logical.x][logical.y];
    return 0;
}

測試用例輸出

int main() {
    InitGrid(5,5);
    SwapNode((Node){3,4}, (Node){1,1});
    InsertRow(1);
    InsertCol(3);
    PathNodeList *path;
    GetNodePath((Node){4,4}, &path);
    // 輸出 (4,4) 邏輯位置的歷史軌跡
    for (; path; path = path->pNext)
        printf("(%d, %d)\n", path->node.x, path->node.y);
    DestoryGrid();
    return 0;
}

輸出將展示該邏輯位置從初始 (4,4) 經過行/列插入、交換操作後的完整物理坐標遷移路徑。

設計亮點與擴展方向

  • 邏輯/物理分離:邏輯坐標固定,物理存儲通過鏈表頭指針交換實現移動,避免大塊內存拷貝
  • 全歷史追蹤:每次位置變更自動記錄,支持撤銷、回放、調試分析
  • 固定池分配:預分配 MAX_ROW×MAX_COL 節點池可消除 malloc 開銷,適合實時系統
  • 擴展性:易於增加「刪除行/列」、「旋轉」、「子矩陣提取」等操作

總結

本框架展示了如何用 C 語言將「數據結構(鏈表)」與「業務語義(二維網格操作)」深度融合。通過指針交換代替數據搬移、鏈表記錄代替狀態機,實現了高效、可追蹤的動態二維數組操作,為棋類 AI、表格編輯器、矩陣變換等應用提供了堅實基礎。

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