typedef struct{
int *base;
int *top;
int StackSize;
}SqStack;
会了顺序表和链表的话,栈就简单的多了
下面我给出的这个小例子,里面包含了顺序栈的初始化、压栈、弹栈、遍历操作
#include
#include
#define Init_size 100
#define Increment 10
typedef struct{
int *base;
int *top;
int StackSize;
}SqStack;
int InitStack(SqStack *S){//初始化
S->base=(int *)malloc(Init_size*sizeof(int));
if(!S->base) return -1;
S->top=S->base;
S->StackSize=Init_size;
return 0;
}
int Push(SqStack *S,int e){//入栈
if(S->top-S->base>=S->StackSize){//如果空间不够 增加空间
S->base=(int *)realloc(S->base,(S->StackSize+Increment)*sizeof(int));
if(!S->base) return -1;
S->top=S->base+S->StackSize;
S->StackSize+=Increment;
}
*(S->top)=e;
S->top++;
return 0;
}
int Pop(SqStack *S,int *e){//弹栈
if(S->top==S->base)return -1;
S->top--;
*e=*(S->top);
return 0;
}
int main(){
//申请一个栈 将1-10依次入栈 并依次弹栈输出
SqStack S;
InitStack(&S);
for(int i=1;i<=10;i++){
Push(&S,i);
}
int e;
while(S.base!=S.top){
Pop(&S,&e);
printf("%d ",e);
}
}
关于链栈的实现,其实前面我们在写链表的时候,最终我们优化出来的终极版本,其实就已经很像一个链式栈了。只是操作上再加以限制就好了
栈要遵循先进后出的原则:
需要注意的是,我们在弹栈的时候,也就相当于删除链表末尾元素,所以要先找到末尾元素的前驱,如果这是个双向链栈,那么我们可以直接通过top指针找到他的前驱,单向链栈的话,我们就需要遍历找到最后了。
这里我用的是单向链栈,显然用双向效率更高,有兴趣可以试试实现双向链栈。
实现代码:
#include
#include
typedef struct LDataNode{
int x;
struct LDataNode *next;//结点指针
}LDataNode;
typedef struct LHeadNode{
LDataNode *base; //栈底指针
LDataNode *top; //栈顶指针
}LHeadNode,*LinkStack;
int InitStack(LinkStack *head){//初始化链栈
*head =(LinkStack)malloc(sizeof(LHeadNode));//指向头结点的头指针
LDataNode *vhNode =(LDataNode *)malloc(sizeof(LDataNode));//首元结点
if(*head==NULL||vhNode==NULL) return -1;//申请失败
vhNode->next=NULL;
(*head)->base=vhNode;
(*head)->top=vhNode;
return 0;
}
int Push(LinkStack *head,int e){
(*head)->top->x=e;//压入栈
LDataNode *vhNode =(LDataNode *)malloc(sizeof(LDataNode));
if(vhNode==NULL) return -1;//申请失败
(*head)->top->next=vhNode;
vhNode->next=NULL;
(*head)->top=vhNode;//栈顶指针后移
return 0;
}
int Pop(LinkStack *head,int *e){
LDataNode *p=(*head)->base;//指向第1个结点
while(p!=NULL){//遍历链栈
if(p->next==(*head)->top) break;
p=p->next;
}
(*head)->top=p;//栈顶指针回退
*e=p->x;
return 0;
}
int main(){
LinkStack head;
InitStack(&head);
for(int i=1;i<=10;i++){
Push(&head,i);//依次压栈
}
int e;
for(int i=1;i<=10;i++){
Pop(&head,&e);//依次弹栈
printf("%d ",e);
}
}
注意:这里我写的三个程序,均实现的是一个十进制数转化成n进制数,n<10.
如果要转换十六进制,需要略作修改。
C语言实现
#include
#include
#define Init_size 100
#define Increment 10
typedef struct{
int *base;
int *top;
int StackSize;
}SqStack;
int InitStack(SqStack *S){//初始化
S->base=(int *)malloc(Init_size*sizeof(int));
if(!S->base) return -1;
S->top=S->base;
S->StackSize=Init_size;
return 0;
}
int Push(SqStack *S,int e){//入栈
if(S->top-S->base>=S->StackSize){//如果空间不够 增加空间
S->base=(int *)realloc(S->base,(S->StackSize+Increment)*sizeof(int));
if(!S->base) return -1;
S->top=S->base+S->StackSize;
S->StackSize+=Increment;
}
*(S->top)=e;
S->top++;
return 0;
}
int Pop(SqStack *S,int *e){//弹栈
if(S->top==S->base)return -1;
S->top--;
*e=*(S->top);
return 0;
}
//将10进制数a转换为n进制数
int conversion(int a,int n){
SqStack S;
InitStack(&S);
while(a){
Push(&S,a%n);
a/=n;
}
int e;
while(S.top!=S.base){
Pop(&S,&e);
printf("%d",e);
}
return 0;
}
int main(){
int a,n;
scanf("%d%d",&a,&n);
conversion(a,n);
}
数组模拟栈实现:
#include
int conversion(int a,int n){
int q[100];//模拟栈
int t=0,w=0;//模拟指针
while(a){
q[w++]=a%n;
a/=n;
}
while(w){
printf("%d",q[--w]);
}
}
int main(){
int a,n;
scanf("%d%d",&a,&n);
conversion(a,n);
}
C++(STL)实现
/******
author: 1900
language: C++
******/
#include
#include
#include
using namespace std;
int conversion(int a,int n){
stack<int> q;
while(a){
q.push(a%n);
a=a/n;
}
while(!q.empty()){
cout<<q.top();
q.pop();
}
return 0;
}
int main(){
int a;
cin>>a;
conversion(a,8);
}
注意:括号是字符型数据
#include
#include
#include
#define Init_size 100
#define Increment 10
typedef struct{
int *base;
int *top;
int StackSize;
}SqStack;
int InitStack(SqStack *S){//初始化
S->base=(int *)malloc(Init_size*sizeof(char));
if(!S->base) return -1;
S->top=S->base;
S->StackSize=Init_size;
return 0;
}
int Push(SqStack *S,char e){//入栈
if(S->top-S->base>=S->StackSize){//如果空间不够 增加空间
S->base=(int *)realloc(S->base,(S->StackSize+Increment)*sizeof(int));
if(!S->base) return -1;
S->top=S->base+S->StackSize;
S->StackSize+=Increment;
}
*(S->top)=e;
S->top++;
return 0;
}
int Pop(SqStack *S,char *e){//弹栈
if(S->top==S->base)return -1;
S->top--;
*e=*(S->top);
return 0;
}
int main(){
SqStack S;
InitStack(&S);
char a[100];
scanf("%s",a);
int l=strlen(a);
char e;
for(int i=0;i<l;i++){
if(a[i]=='('||a[i]=='['||a[i]=='{'){
Push(&S,a[i]);
}
else{
if(a[i]==')'&&*(S.top-1)=='('){
Pop(&S,&e);
}
else if(a[i]==']'&&*(S.top-1)=='['){
Pop(&S,&e);
}
else if(a[i]=='}'&&*(S.top-1)=='{'){
Pop(&S,&e);
}
}
}
if(S.top==S.base) printf("Yes\n");
else printf("No\n");
}
#include
#include
#include
#define Init_size 100
#define Increment 10
typedef struct{
int *base;
int *top;
int StackSize;
}SqStack;
int InitStack(SqStack *S){//初始化
S->base=(int *)malloc(Init_size*sizeof(char));
if(!S->base) return -1;
S->top=S->base;
S->StackSize=Init_size;
return 0;
}
int Push(SqStack *S,char e){//入栈
if(S->top-S->base>=S->StackSize){//如果空间不够 增加空间
S->base=(int *)realloc(S->base,(S->StackSize+Increment)*sizeof(int));
if(!S->base) return -1;
S->top=S->base+S->StackSize;
S->StackSize+=Increment;
}
*(S->top)=e;
S->top++;
return 0;
}
int Pop(SqStack *S,char *e){//弹栈
if(S->top==S->base)return -1;
S->top--;
*e=*(S->top);
return 0;
}
int LTraverse(SqStack S){
while(S.base!=S.top){
printf("%c",*(S.base));
S.base++;
}
printf("\n");
}
int main(){
char a[100];
while(scanf("%s",a)!=EOF){
SqStack S;
InitStack(&S);
int l=strlen(a);
char e;
for(int i=0;i<l;i++){
if(a[i]=='#'){
Pop(&S,&e);
}
else if(a[i]=='@'){
S.top=S.base;//清空栈
}
else{
Push(&S,a[i]);
}
}
LTraverse(S);//正序遍历整个栈
}
}
关于这个迷宫求解,建议后边学了图之后,再回过头来写,会更明白些
这里贴出一个我之前学的时候写的
两种写法:
迷宫求解解法详解
关于最后这三个问题,我先更新下边的东西,这个回过头第二遍的时候再写吧,我太懒了,要跟不上进度了。。。/大哭