本科學習資料結構時實踐比較少,因此最近開始複習,看到**既可以打基礎,又可以順便學習linux的知識。
原始**:
#include #define max_row 5
#define max_col 5
struct point stack[512];
int top = 0;
int maze[5][5] = ,
, ,
, };void push(struct point p)
struct point pop()
int is_empty()
void print_maze(void)
printf("*********\n");
}struct point predecessor[max_row][max_col] = , , , , },
, , , , },
, , , , },
, , , , },
, , , , }
};void visit(int row, int col, struct point pre)
; maze[row][col] = 2;
predecessor[row][col] = pre;
push(visit_point);
}int main()
; maze[p.row][p.col] = 2;
push(p);
while (!is_empty())
if (p.row == max_row - 1 && p.col == max_col - 1)
} else
printf("no path!\n");
return 0;
}
下面有三道習題。
文中已經分析「正向列印路徑」原理上的不可行,因此我想到的方法是:
a:把輸出到路徑壓到乙個新的堆疊中,然後pop出來——這很好理解。
b:取巧的做法——把迷宮出口(4,4)當作起點,入口(0,0)當作終點,找到的路徑(4,4)->(0,0)逆序輸出即為(0,0)->(4,4),倘若沒有路徑,那麼只會輸出「no pathing!」
b方法**更改的地方很少:
#include #define max_row 5
#define max_col 5
struct point stack[512];
int top = 0;
int maze[5][5] = ,
, ,
, };void push(struct point p)
struct point pop()
int is_empty()
void print_maze(void)
printf("*********\n");
}struct point predecessor[max_row][max_col] = , , , , },
, , , , },
, , , , },
, , , , },
, , , , }
};void visit(int row, int col, struct point pre)
; maze[row][col] = 2;
predecessor[row][col] = pre;
push(visit_point);
}int main()
; // 起點為迷宮終點
maze[p.row][p.col] = 2;
push(p);
while (!is_empty())
if (p.row == 0 && p.col == 0)
} else
printf("no path!\n");
return 0;
}
讀者會發現,這種方法最終的結果maze矩陣中出現了0,原因是:本演算法是深度優先演算法,假如第一條路徑就能夠到達終點,那麼演算法就不會再計算了。
原來predecessor儲存的是point的二維陣列,我首先想到的是將其改為二維整形資料——代表指向前乙個位置的「方向」。visit函式需要傳入這個方向值;最後逆序輸出時也需要根據方向值找到下乙個位置點。首先,四個方向巨集定義。
#include #define max_row 5
#define max_col 5
#define right 1
#define left 2
#define up 3
#define down 4
struct point stack[512];
int top = 0;
int maze[5][5] = ,
, , ,
};void push(struct point p)
struct point pop()
int is_empty()
void print_maze(void)
printf("*********\n");
}int predecessor[max_row][max_col] = ,
, , ,
};void visit(int row, int col, struct point pre, int dir)
; maze[row][col] = 2;
predecessor[row][col] = dir;
push(visit_point);
}int main()
; maze[p.row][p.col] = 2;
push(p);
while (!is_empty())
if (p.row == max_row - 1 && p.col == max_col - 1)
// p = predecessor[p.row][p.col];
printf("(%d, %d)\n", p.row, p.col);
} } else
printf("no path!\n");
return 0;
}
起先設定predecessor的初始值都是0,最終找到的路徑上點到predecessor的值則為left/up/right/down,因此沿著已知的方向依次判斷下個座標點到位置,直到preecessor值=0的起點。
更進一步,我想,predecessor和maze都是2維整形陣列,為什麼不能把兩者合併呢?於是修改如下:(為了防止資料混淆,修改原來到巨集定義)
#include #define max_row 5
#define max_col 5
#define right 3
#define left 4
#define up 5
#define down 6
struct point stack[512];
int top = 0;
int maze[5][5] = ,
, , ,
};void push(struct point p)
struct point pop()
int is_empty()
void print_maze(void)
printf("*********\n");}/*
int predecessor[max_row][max_col] = ,
, , ,
};*/
void visit(int row, int col, struct point pre, int dir)
; maze[row][col] = dir;
// predecessor[row][col] = dir;
push(visit_point);
}int main()
; maze[p.row][p.col] = 2; // 起始點的方向設定為2,代表無方向。
push(p);
while (!is_empty()) // 倘若有路徑,那麼最後pop出的p即(4,4)
if (p.row == max_row - 1 && p.col == max_col - 1)
// p = predecessor[p.row][p.col];
printf("(%d, %d)\n", p.row, p.col);
} } else // 倘若最後pop出的非(4,4),那麼就沒有路徑
printf("no path!\n");
return 0;
}
待續。。。
Linux C程式設計一站式學習
北京亞嵌教育研究中心 ps ef grep sctp grep全稱是global regular expression print,表示全域性正規表示式.gdb除錯又看一遍。迅速用起 pthread cond timedwait 條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個...
Linux C程式設計一站式學習 筆記
關於程式的討論裡提到了c語言的可移植,原本不知道為什麼,現在知道,原來是因為各種平台上都有c語言的編譯器,這就好像是一種由於廣泛使用而成為規範的東西一樣,當所有機器上都有你的編譯器的時候,你的可移植性當然強了。之前看v6shell的 就沒明白詞法和語法有什麼差別,這裡講到了詞法就是單詞 token ...
Linux C程式設計一站式學習 筆記
1變數宣告與函式宣告有一點不同,函式宣告的extern關鍵字可以省略,而變數宣告不寫extern意思完全不同,表示為定義了乙個區域性變數。2static關鍵字宣告具有internal linkage,這些函式變數作用域僅限本檔案,則不想被外部檔案所訪問的變數和函式就可以宣告為static。3用角括號...