LinuxC程式設計一站式學習 堆疊

2021-06-08 08:34:34 字數 4296 閱讀 3722

本科學習資料結構時實踐比較少,因此最近開始複習,看到**既可以打基礎,又可以順便學習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用角括號...