資料結構C語言版(第二章迷宮)
阿新 • • 發佈:2018-12-08
轉自未空blog
//我剛開始對STACK的記憶體分配那有點問題,後來用這個程式碼除錯了下,感覺有點明白了, 地址由高到低分配,然後程式碼中的base和top剛開始指向地址最低的地方,記憶體不夠時重新在原有基礎上新增記憶體,top指向原有的棧頂,然後繼續存入資料
/* #include<stdio.h> #include<iostream> #include<limits.h> #include<stdlib.h> #include<iomanip> #define STACK_INIT_SIZE 1 #define STACKINCREMENT 10 #define OK 1 #define TRUE 1 #define FALSE 0 #define OVERFLOW -1 #define ERROR 0 #define MAXLENGTH 25; using namespace std; typedef int Status; typedef int MazeType[25][25]; typedef int ElemType; struct PosType{ int x; int y; }; struct SElemType{ //這個是棧的元素 int ord; //通道塊的序號 PosType seat; //通道塊在迷宮的座標位置 int direc; //方向 }; PosType curpos; //定義當前位置 PosType direction[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; //定義四個方向 typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; Status InitStack(SqStack &L) //構建一個棧 { L.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); //動態分配記憶體 if (!L.base) exit(OVERFLOW); L.top = L.base; cout << endl << L.top << " " << L.base << endl << endl; L.stacksize = STACK_INIT_SIZE; //初始化長度為0 return OK; } Status Push(SqStack &L, SElemType &e) //棧中插入元素e { if(L.top - L.base >= L.stacksize) { cout << "先前" << L.base << "&" << L.top << endl; L.base = (SElemType*)realloc(L.base, (L.stacksize+1)* sizeof(SElemType)); cout <<"擴大記憶體" << L.base << endl; cout << L.stacksize << endl; L.top = L.base + L.stacksize; cout << " 22222222"<< L.top << endl; L.stacksize += 1; } *L.top++ = e; //L.top++; // L.stacksize++; return OK; } Status Pop(SqStack &L, SElemType &e) { if (L.top == L.base) return ERROR; e = *--L.top; // cout << L.top << "測試" << endl; // L.stacksize--; return OK; } Status IsStackEmpty(SqStack S) { if (S.top == S.base) return true; else return false; } MazeType maze; int i, j, m, n; //m,n表示行數列數 void PrintMaze() //輸出迷宮 { int i, j; for (i = 0; i < m; i++){ for (j = 0; j < n; j++) cout << setw(3) << maze[i][j]; cout << endl; } } PosType Start, End; //入口和出口分別用begin 和and 表示 Status InitMaze() //設定迷宮 { cin >> m >> n; //迷宮m行n列 for (i = 0; i < m; i++) for (j = 0; j < n; j++){ maze[i][j] = 1; //通道用1表示 } for (i = 0; i < n; i++){ maze[0][i] = 0; //迷宮0表示牆 maze[m - 1][i] = 0; //第一行加最後一行全部0 } for (j = 0; j < m; j++){ //第一列最後一列全部0 maze[j][0] = 0; maze[j][n - 1] = 0; } cout << "迷宮的初始結構如下: " << endl; PrintMaze(); cout << "請輸入迷宮的牆數:" << endl; int num; int x1, y1; cin >> num; cout << "請輸入迷宮的牆的座標:" << endl; for (i = 0; i < num; i++){ cin >> x1 >> y1; maze[x1][y1] = 0; } cout << "請輸入入口的座標:" << endl; cin >> Start.x >> Start.y; cout << "請輸入出口的座標: " << endl; cin >> End.x >> End.y; PrintMaze(); return 0; } int curstep = 1; //走到第幾個格子了,初值在入口處為一 Status CanPass(PosType b) { cout << maze[b.x][b.y] << endl; if (maze[b.x][b.y] == 1) return OK; else return ERROR; } void FootPrint(PosType b) //把某個點b變成足跡 { maze[b.x][b.y] = curstep; //走過以後做個標記-1 } Status NextPos(PosType &e, int direc) { curpos.x += direction[direc].x; curpos.y += direction[direc].y; return OK; } Status MarkPrint(PosType b) { maze[b.x][b.y] = -1; return OK; } Status MazePath(PosType start, PosType end) { curpos = start; //初始化位置 SqStack S; InitStack(S); cout << S.base << " " << S.stacksize << " " << S.top << endl; SElemType e; do{ if (CanPass(curpos)){ //如果當前位置能通過 FootPrint(curpos); //那就在這個點留下足跡 e.ord = curstep; //棧元素e的編號為curstep e.seat = curpos; //通道塊在迷宮的座標位置為當前位置 e.direc = 0; //然後把方向初始化為向東 Push(S, e); cout << "Push" <<S.top << "測試" << endl;//滿足要求e入棧 curstep++; cout << curstep << " " << curpos.x << "," << curpos.y << endl; if (curpos.x == end.x&&curpos.y == end.y) return TRUE; NextPos(curpos, e.direc); } else{ //當前位置不能通過 if (!IsStackEmpty(S)){ Pop(S, e); curstep--; while (e.direc == 3 && !IsStackEmpty(S)) //前一個位置在最後一個方向且不是空棧 { MarkPrint(e.seat); Pop(S, e); cout << "POP" << S.top << "測試" << endl; curstep--; } if (e.direc < 3){ e.direc++; Push(S, e); curstep++; curpos = e.seat; NextPos(curpos, e.direc); } } } } while (!IsStackEmpty(S)); return false; } int main() { InitMaze(); if (MazePath(Start, End)){ cout << "迷宮的一條路徑如下:" << endl; PrintMaze(); } else cout << "Error!" << endl; return 0; }*/
這個當時有個小細節有錯.....改了挺長時間的
#include<stdio.h> #include<iostream> #include<limits.h> #include<stdlib.h> #include<iomanip> #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define TRUE 1 #define FALSE 0 #define OVERFLOW -1 #define ERROR 0 #define MAXLENGTH 25; using namespace std; typedef int Status; typedef int MazeType[25][25]; typedef int ElemType; struct PosType{ int x; int y; }; struct SElemType{ //這個是棧的元素 int ord; //通道塊的序號 PosType seat; //通道塊在迷宮的座標位置 int direc; //方向 }; PosType curpos; //定義當前位置 PosType direction[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; //定義四個方向 typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; Status InitStack(SqStack &L) //構建一個棧 { L.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); //動態分配記憶體 if (!L.base) exit(OVERFLOW); L.top = L.base; L.stacksize = 0; //初始化長度為0 return OK; } Status Push(SqStack &L, SElemType &e) //棧中插入元素e { *L.top++ = e; //L.top++; L.stacksize++; return OK; } Status Pop(SqStack &L, SElemType &e) { if (L.top == L.base) return ERROR; e = *--L.top; L.stacksize--; return OK; } Status IsStackEmpty(SqStack S) { if (S.top == S.base) return true; else return false; } MazeType maze; int i, j, m, n; //m,n表示行數列數 void PrintMaze() //輸出迷宮 { int i, j; for (i = 0; i < m; i++){ for (j = 0; j < n; j++) cout << setw(3) << maze[i][j]; cout << endl; } } PosType Start, End; //入口和出口分別用begin 和and 表示 Status InitMaze() //設定迷宮 { cin >> m >> n; //迷宮m行n列 for (i = 0; i < m; i++) for (j = 0; j < n; j++){ maze[i][j] = 1; //通道用1表示 } for (i = 0; i < n; i++){ maze[0][i] = 0; //迷宮0表示牆 maze[m - 1][i] = 0; //第一行加最後一行全部0 } for (j = 0; j < m; j++){ //第一列最後一列全部0 maze[j][0] = 0; maze[j][n - 1] = 0; } cout << "迷宮的初始結構如下: " << endl; PrintMaze(); cout << "請輸入迷宮的牆數:" << endl; int num; int x1, y1; cin >> num; cout << "請輸入迷宮的牆的座標:" << endl; for (i = 0; i < num; i++){ cin >> x1 >> y1; maze[x1][y1] = 0; } cout << "請輸入入口的座標:" << endl; cin >> Start.x >> Start.y; cout << "請輸入出口的座標: " << endl; cin >> End.x >> End.y; PrintMaze(); return 0; } int curstep = 1; //走到第幾個格子了,初值在入口處為一 Status CanPass(PosType b) { cout << maze[b.x][b.y] << endl; if (maze[b.x][b.y] == 1) return OK; else return ERROR; } void FootPrint(PosType b) //把某個點b變成足跡 { maze[b.x][b.y] = curstep; //走過以後做個標記-1 } Status NextPos(PosType &e, int direc) { curpos.x += direction[direc].x; curpos.y += direction[direc].y; return OK; } Status MarkPrint(PosType b) { maze[b.x][b.y] = -1; return OK; } Status MazePath(PosType start, PosType end) { curpos = start; //初始化位置 SqStack S; InitStack(S); cout << S.base << " " << S.stacksize << " " << S.top << endl; SElemType e; do{ if (CanPass(curpos)){ //如果當前位置能通過 FootPrint(curpos); //那就在這個點留下足跡 e.ord = curstep; //棧元素e的編號為curstep e.seat = curpos; //通道塊在迷宮的座標位置為當前位置 e.direc = 0; //然後把方向初始化為向東 Push(S, e); //滿足要求e入棧 curstep++; cout << curstep << " " << curpos.x << "," << curpos.y << endl; if (curpos.x == end.x&&curpos.y == end.y) return TRUE; NextPos(curpos, e.direc); } else{ //當前位置不能通過 if (!IsStackEmpty(S)){ Pop(S, e); curstep--; while (e.direc == 3 && !IsStackEmpty(S)) //前一個位置在最後一個方向且不是空棧 { MarkPrint(e.seat); Pop(S, e); curstep--; } if (e.direc < 3){ e.direc++; Push(S, e); curstep++; curpos = e.seat; NextPos(curpos, e.direc); } } } } while (!IsStackEmpty(S)); return false; } int main() { InitMaze(); if (MazePath(Start, End)){ cout << "迷宮的一條路徑如下:" << endl; PrintMaze(); } return 0; }