数据结构(C)核心知识点+易错点+代码:栈和队列(建栈,入栈,出栈,建队,入队,出队,括号的匹配,判断字符串是否对称)
一.栈(被约束的线性表)
1. 核心知识点
(1)顺序栈
相对于顺序表的定义用base-top代替length
判空:S.topS.base
判满:S.top-S.baseS.stacksize
(2)链栈
①.结构如何定义?
每个节点的定义还是链表的定义,而后还有个栈的定义,不用stacksize,base,不用指向表尾
②.如何初始化?
malloc,逆序建立,s.top指向栈顶元素
③.入、出栈操作?
入栈:逆序建立,出栈:删除s.top所指的节点
④.如何判断空栈?
s.top=NULL
⑤.栈会溢出吗?
永远不会
二. 队列
1,核心知识点
(1)顺序队列(循环队列)
这里可以联系到《离散数学》中的循环群
(2)链队列
和普通链表的形式一样,另外设置两个指针一个指向第一个节点用于出队,另一个指向最后一个节点(不是下一个)
三,易错点辨析
1.在用顺序及结构存储时,栈的大小是可以改变的,而循环队列的大小一般是不能改变的。
2。栈的特点是后进先出,但是并不是一组数据通过栈后都会逆置,只有在一次性进栈再出栈后才是,而队列无论什么过程都不会改变数据元素的顺序
四,代码(配套教材严蔚敏版)
1,栈
#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OVERFLOW -1
#define OK 1
#define TRUE 1
#define ERROR 0
typedef char SElemType;
typedef int Status;
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//建栈
Status InitStack(SqStack &S)
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
//取栈顶元素
Status GetTop(SqStack S,SElemType &e)
{
if(S.top==S.base) return ERROR;
e=*(S.top-1);
return OK;
}
//进栈
Status Push(SqStack &S,SElemType e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
//出栈
Status Pop(SqStack&S,SElemType &e)
{
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
Status StackEmpty(SqStack S)
{
if(S.top==S.base)
return TRUE;
else return ERROR;
}
//括号匹配算法
Status BracketsMarch(SqStack &S)
{
char c,e;
c=getchar();
while(c!='#')
{
if(c=='('||c=='['||c=='{'||c=='<') Push(S,c);
if(c==')'||c==']'||c=='}'||c=='>')
{
if(StackEmpty(S)) return 0;//没有左括号,只有右括号
else {
Pop(S,e);
if(e=='('&&c!=')' || e=='['&&c!=']' || e=='{'&&c!='}' ||e=='<'&&c!='>')//有左括号,但是不匹配
return 0;
}
}
c=getchar();
}
if(StackEmpty(S))//直到结束,如果匹配成功则栈空,否则则是
return 1;
else return 0;
}
/*int main()
{
int e;
SqStack S;
InitStack(S);
printf("请输入你要匹配的括号串");
e=BracketsMarch(S);
if(e==0) printf("匹配失败");
if(e==1) printf("匹配成功");
return 0;
}
*/
//判断以#结尾的字符串是否关于@对称
Status match(char a[])
{
char e;
SqStack S;
InitStack(S);
char *p=a;
for(;*p!='@';p++)
Push(S,*p);
p++;
for(;*p!='#';p++)
{
Pop(S,e);
if(e!=*p)
return 0;
}
if(StackEmpty(S))
return TRUE;
else
return ERROR;
}
int main()
{
int i;
char a[10];
scanf("%s",a);
i=match(a);
if(i=1)
printf("对称");
else
printf("不对称");
return 0;
}
2,队列
#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100
#define MAXQSIZE 100
#define OK 2
#define TRUE 1
#define ERROR 0
#define OVERFLOW -1
typedef char QElemType;
typedef int Status;
typedef struct
{
QElemType *base;
int front;
int rear;
}SqQueue;
//队列判空
Status QueueEmpty(SqQueue Q)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;
else return OK;
}
//建立队列
Status InitQueue(SqQueue &Q)
{
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base) return OVERFLOW;
Q.front=Q.rear=0;
return OK;
}
int QueneLength(SqQueue Q)
{
return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
//进队列
Status EnQueue (SqQueue &Q,QElemType e)
{
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
//出队列
Status DeQueue(SqQueue &Q,QElemType &e)
{
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
//判断以#结束的字符串是否关于@对称
Status match(char a[])
{
char *p=a,e;
SqQueue Q;
InitQueue(Q);
for(;*p!='#';)
{p++;}
p--;
for(;*p!='@';p--)
EnQueue(Q,*p);
p--;
for(p=a;*p!='@';p++)
{
DeQueue(Q,e);
if(e!=*p)
return ERROR;
}
if(QueueEmpty(Q))
return 1;
else
return 0;
}
int main()
{
int i;
char a[10];
scanf("%s",a);
i=match(a);
if(i=1)
printf("对称");
else
printf("不对称");
return 0;
}