資料結構---堆疊
阿新 • • 發佈:2018-12-11
簡單介紹堆疊(特點:先進後出)的基本運算
#include <stdio.h> #include <stdlib.h> #define maxsize 1000 typedef struct //順序棧結構 { int data[maxsize]; int top; }SeqStack; SeqStack *Init_SeqStack()//置空順序棧 { SeqStack *s; s=(SeqStack*)malloc(sizeof(SeqStack)); s->top=-1; return s; } int Empty_SeqStack(SeqStack *s)//判斷棧是否空 { if(s->top==-1)return 1; else return 0; } int Push_SeqStack (SeqStack *s,int x)//入棧 { if(s->top==maxsize-1)return 0;//判斷棧滿,若棧滿,不可入棧,否則會空間溢位 else { s->top++; s->data[s->top]=x; return 1; } } int Pop_SeqStack(SeqStack *s,int *x)//出棧,地址傳遞,防資料丟失 { if(s->top==-1)return 0;//判斷棧空,可出棧 else { *x=s->data[s->top];//儲存下移前棧頂資料,用指標地址傳遞 s->top--;//棧頂位置下移 reutrn 1; } } int Top_SeqStack(SeqStack *s,int *x)//取棧頂元素 { if(s->top==-1)return 0; else { *x=*x=s->data[s->top]; return 1; } }
鏈棧的基本操作有判棧空和入棧,相對順序棧用的較少
typedef struct snode//鏈棧結構 { int data; struct snode *next; }StackNode,*LinkStack; LinkStack *top;//定義棧頂指標變數 int Empty_LinkStack(LinkStack top) { if(top==NULL)return 1; else return 0; } LinkStack Push_LinkStack(LinkStack top,int x)//入棧 { StackNode *p; p=(SeqStack*)malloc(sizeof(SeqStack)); p->data=x; p->next=top; top=top->next; top=p; }
堆疊的應用例項(運用堆疊“先進後出”的特點)
數制轉換問題
將十進位制數N轉換為r進位制數,其轉換方法利用輾轉相除法
void conversionn(int N,int r)//呼叫棧的基本操作實現數制轉換 { SeqStack *s; int x; s=Init_SeqStack(); while(N!=0) { Push_SeqStack(SeqStack *s,N%r); N=N/r; } if(!Empty_SeqStack(s)) { Pop_SeqStack(SeqStack *s,&x); printf("%d",x); } } void conversionn(int N,int r)//自定義順序棧實現數制轉換 { int S[maxsize],top=-1;//定義一個順序棧並初始化 int x; while(N!=0) { S[++top]=N%r;//餘數入棧 N=N/r;//商作為被除數繼續 } while(top!=-1) { x=S[top--]; printf("%d",x); } }
利用棧實現迷宮問題
這是實驗心理學的一個有名實驗,我們採取回溯法解決該問題。
(1)設迷宮為m行,n列,將迷宮看成一個maze[m][n]的陣列,maze[i][j]=0表示可走,maze[i][j]=1表示不可走,中間的點有八個方向可走,四角則一個方向,四邊有五個方向,為使問題簡化,我們可把迷宮看成m+2行,n+2列,則所有點都有八個方向可選擇,新增四周均設1不可走,與迷宮四周都是牆相一致。
(2)八個方向我們用含資料x,y的結構move表示,由x軸正方向為開始,順時針進行這八個方向的試探
(3)到達新點我們還需要一個方向序號d表示,若無路可走我們需返回到前一點
(4)為避免到達重複點而進入死迴圈,我們將到達的點進行標記,置maze[i][j]=-1
下面為核心部分演算法
#define m 6
#define n 8
typedef struct //移動結構
{
int x;
int y;
}item;
typedef struct //移動結構
{
int x;
int y;
int d;
}data;
item move[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
int path(int maze[m+2][n+2],item move[8])
{
SeqStack *s;
data temp;
int x,y,d,i,j;int tempx,tempy,tempd;
temp.x=1;temp.y=1;temp.d=-1;
Push_SeqStack(s,temp);//入口進棧
while(!Empty_SeqStack(s))
{
Pop_SeqStack(s,&temp);
x=temp.x;y=temp.y;d=temp.d+1;//回到上一座標位置進行下一座標試探
while(d<8)//當還有方向可試
{
i=x+move[d].x;j=y+move[d].y;//新點座標
if(maze[i][j]==0)
{
tempx=x;tempy=y;tempd=d;//記錄當前座標及位置
Push_SeqStack(s,temp);
x=i;y=j;maze[x][y]=-1;//到達新點
if(x==m&&y==n)return 1;//是出口則迷宮有路
else d=0;//不是出口繼續試探
}
else d++;
}
}
return 0;
}