一.队列:从队尾加入元素,从队头出元素。
size:记录队列总大小。head指针(指向队头)和tail指针(指向队尾后的一个空地址)(排队买票)
循环队列:多了一个count(记 录有多少个元素)为了解决队列的家溢出问题
用顺序表实现队列:
#include<stdlib.h> #include<stdio.h> typedef struct vector{ int *data; int size; }vector; vector *GetNewvector(int n){ vector *p=(vector*)malloc(sizeof(vector)); p->data=malloc(sizeof(int)*n); p->size=n; return p; } int insertvector(vector*p,int val,int pos){ if(pos<0||pos>=p->size)return 0; p->data[pos]=val;return 1; } int vectorseek(vector *q,int pos){ if(pos<0||pos>=q->size)return 0; return q->data[pos]; } void clearvector(vector*q){ if(q==NULL)return; free(q->data); free(q); } typedef struct queue{ vector*data; int size,count,head,tail; }queue; queue * GetNewqueue(int n){ queue*p=(queue*)malloc(sizeof(queue)); p->data= GetNewvector(n); p->size=n; p->head=p->tail=p->count=0; return p; } void Clearqueue(queue*q){ if(q==NULL)return; else clearvector(q->data); free(q); } int push(queue*q,int val){ if(q->count==q->size)return 0; insertvector(q->data,val,q->tail); q->tail++; if(q->tail==q->size)q->tail=0; q->count++;return 1; } int empty(queue*q){ return q->count==0; } int pop(queue*q){ if(empty(q))return 0; q->head++; q->count--; return 1; } int front(queue*q){ return vectorseek(q->data,q->head); } void outputqueue(queue*q){ for(int i=0;i<q->count;i++)printf("%3d", vectorseek(q->data,(q->head+i)%q->size)); printf("\n"); } int main(){ int val; queue*new= GetNewqueue(5); for(int i=0;i<5;i++){ scanf("%d",&val); push(new,val);} outputqueue(new); printf("%d\n", front(new)); pop(new); outputqueue(new); Clearqueue(new); } 二.栈:先进入,后出来(队列不改变元素间的顺序,而栈会改变。)
出栈:栈顶指针向下移动一位;
入栈:栈顶指针向上移动一位。
pop push top(对应front 查看栈首元素)
用数组去实现栈。
#include<stdlib.h> #include<stdio.h> typedef struct stuck{ int *data; int size,top;}stuck; stuck* initstuck(int n){ stuck*p=(stuck*) malloc(sizeof(stuck)); p->data=(int *)malloc(sizeof(int)*n); p->size=n; p->top=-1; return p; } int push(stuck*p,int val){ if(p->top+1==p->size)return 0; p->top++; p->data[p->top]=val;return 1; } int isempty(stuck*p){ return p->top==-1; } int top(stuck*p){ if(isempty(p))return 0; return p->data[p->top]; } int pop(stuck*p){ if(isempty(p))return 0; p->top-=1; return 1; } void output(stuck*p){ for(int i=p->top;i>=0;i--)printf("%3d",p->data[i]); printf("\n\n"); } void clear(stuck*p){ if(p==NULL)return; free(p->data); free(p); } int main(){ int a; stuck*p= initstuck(5); for(int i=0;i<5;i++){ scanf("%d",&a); push(p,a); output(p); } pop(p); output(p); clear(p); return 0; }
对栈的深入理解:对包含关系的处理--从括号匹配问题说起。
1.对于只有一种括号的情况:
在任意位置上左括号数量>=右括号的数量。
在最后一个位置上,左括号数量==右括号数量
只需要记录左括号与右括号的数量;
改写:遇到右括号就-1,遇到右括号就+1;
推广一下,这是什么意思,-1就代表发生一件事,+1就代表解决了一件事情。
栈:适合处理具有完全包含关系的问题。
总结: