栈和队列
栈
1:定义:仅能在表尾进行插入或者删除的线性表, 表头为栈底
2:若s表示进栈,x代表出栈 。若进栈顺序为1,2,3,4,为了得到出栈顺序1,3,4,2 ,(审题:在每个元素进栈的时候亦可出栈)则对应s和x的操作序列:sxssxsxx
3:已知一个栈的进栈顺序为1,2,3,…,n,其输出序列的第1个元素为i 则第j个出栈元素为:(不确定)因为进栈后可能出,出栈后有可能进
4:在实现顺序栈入栈操作前应该判断栈是否为满,出栈前应该判断是否为空
5:设链栈结构(next,data) top为指向栈顶(元素)的指针,若在链栈中入栈一个s所指结点,操作为:s->next=top,top=s;
6:将递归算法转换成对应的非递归算法 通常要使用 栈
7:两个栈共用静态空间,对头使用也存在空间溢出问题
顺序栈
typedef int SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int StackSize;
}SqStack;
//--------------初始化--------------------//
Status 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;
}
//--------------进栈--------------------//
Status Push(SqStack *S,SElemType 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++; //S->top不指示元素
return 0;
}
//--------------出栈--------------------//
Status Pop(SqStack *S,SElemType *e){//弹栈
if(S->top==S->base)return -1;//s->top 是指向栈顶
S->top--;
*e=*(S->top);
printf("%d",*e);
return 0;
}
//-----------------判断是否为空----------//
Status StackEmpty(SqStack *s){
if(s->top==s->base) return True;
else return False;
}
//---------------------进制转换---------------------//
void Conversion(int a,int n)//转换进制 10-->8
{
SqStack s;
SElemType e;
InitStack(&s);
while(a){
Push(&s,a%n);
a=a/8;
}
printf("\n转换后的进制为:");
while(!StackEmpty(&s)){
Pop(&s,&e);
printf("%2d",e);
}
}
//-------------括号匹配----------------------//
void Symbol_match()
{
SqStack s;//定义栈
InitStack(&s);
char a[100];//存储括号
scanf("%s",a);//
SElemType l=strlen(a);
char e;
int i=0;
for(;i<l;i++){
if((a[i]=='(')||(a[i]=='{')||(a[i]=='['))
{
push(&s,a[i]);//是左括号 入栈
}
else{
if(a[i]==')'&&*(s.top-1)=='(') //match success
{
pop(&s,&e);
}
if(a[i]=='}'&&*(s.top-1)=='{') //match success
{
pop(&s,&e);
}
if(a[i]=='['&&*(s.top-1)==']') //match success
{
pop(&s,&e);
}
}
}
if(s.base==s.top)printf("success");
else printf("Fail");
}
队列
typedef struct QNode{//队列所使用
int data;
}QNode,*QueuePtr;//数据结点
typedef struct QHeadNode{//队列所使用
QNode *front;
QNode *rear;
}QHeadNode,*LinkQueue; //头结点//
1:特点:先进先出
2:循环队列有队头队尾指针(front和rear)则判断队满的操作:Q.front==(Q.rear+1)%maxSize;
3:对于链式队列,执行入队操作时,头尾指针可能都要修改,因为可能是第一个结点
4:最适合做链式队列的链表是:带有队头和队尾指针的非循环单链表
5:最不适合链式队列的链表是:只带队头指针的非循环双链表
6:设循环队列容量为maxSize ,则(Q.rear-Q.front+maxSize)%maxSize可以计算队列元素的个数
7:循环队列判断队满:(Q.rear+1)%maxSize==Q.front;
8:循环队列判断队空:Q.rear==Q.front;