栈
分类:顺序栈和链栈
- 顺序栈:利用顺序存储结构实现的栈(地址连续+依次存放自栈底到栈顶+附设指针top指示栈顶元素在顺序栈的位置)
- 链栈:利用链式存储结构实现的栈(用单链表表示+不需要附设top指针)
顺序栈和链栈比较:
异:链栈,不需要附设top指针;入栈前不需要像顺序栈那样判断栈是否满而只需要为入栈元素动态分配一个结点空间;需要在出栈后释放出栈元素的栈顶空间。
所以推荐使用链栈。
例题代码-括号匹配
#include<stdio.h>
#include<math.h>
//栈-括号匹配
//链栈
typedef struct Stacknode
{
char data;
typedef struct Stacknode *next;
};
int Initstack(Stacknode* S)
{
S=NULL;
return 1;
}
int Emptystack(Stacknode* S)
{
if(S==NULL) return 1;
else return 0;
}
void Pushstack(Stacknode* S, char e)
{
p=new Stacknode;
p->data=e;
p->next=S;
S=p;
}
void Popstack(Stacknode* S)
{
if(S!=NULL)
{
char e=S->data;
Stacknode* p;
p=S;
S=S->next;
delete p;
}
}
int Gettopstack(Stacknode* S)
{
if(S!=NULL) return S->data;
else return 0;
}
int main()
{
Stacknode* S;
int flag=1;
char ch;
if(Initstack(S)==0) printf("initial failed\n");
else
{
printf("enter the character and '#' represent over.\n");
scanf("%c",&ch);
while(ch!='#'&&flag)
{
switch(ch)
{
case '['||'(': Pushstack(S,ch);break;
case ']':
if(!Emptystack(S)&&(Gettopstack(S)=='[')) Popstack(S);
else flag=0;
break;
case ')':
if(!Emptystack(S)&&(Gettopstack(S)=='(')) Popstack(S);
else flag=0;
break;
default :break;
}
if(Emptystack(S)&&flag) printf("Correct.\n");
else printf("Failed.\n");
}
}
return 0;
}
队列
分类:顺序队列和链队列
类似顺序栈和链栈,顺序队列利用顺序存储结构,链队列利用链式存储结构
知道队列规模时可使用循环队列
原因:非循环顺序队列会出现“rear指向最后一个队列尾部位置,front指示队列倒数第二位置”,该情形下无法再继续插入新的队尾元素因为会出现溢出现象(假溢出),循环队列可以避免这个问题,但需要提前知道队列规模
图形:
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
MAXQSIZE=9,rear,front分别表示队尾和队头,Push新元素rear向上移动,Pop队头元素则front向上移动
代码示例:
#include<stdio.h>
#include<math.h>
#define MAXQSIZE 50//此处设为50,可根据题目具体要求更改
//循环队列-数字
typedef struct Queue
{
int *base;
int front;
int rear;
};
int Initqueue(Queue &Q)
{
Q.base=new int[MAXQSIZE];
if(Q.base==NULL) (printf("failed to register for space\n");return 0;)
Q.front=Q.rear=0;
return 1;
}
int Lengthqueue(Queue &Q)
{
return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
int Pushqueue(Queue &Q,int e)
{
if((Q.rear+1)%MAXQSIZE==Q.front) return 0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return 1;
}
int Popqueue(Queue &Q)
{
if(Q.rear==Q.front) return 0;
int e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return 1;
}
int Getfrontqueue(Queue &Q)
{
if(Q.front!=Q.rear) return Q.base[Q.front];
}
void Choice(Queue &Q, int num)
{
switch(num)
{
case 1:
int e;
scanf("%d",&e);
if(Pushqueue(Q,e)) printf("succeed\n");
else printf("failed\n");
break;
case 2:
if(Popqueue(Q)) printf("succeed\n");
else printf("failed\n");
break;
case 3:
pritnf("%d\n",Getfrontqueue(Q));
break;
case 4:
printf("%d\n",Lengthqueue(Q));
break;
default:break;
}
}
int main()
{
Queue *Q;
int num;
if(Initqueue(Q))
{
printf("1-push\t2-pop\t3-get front value\t4-length of the queue\t5-over\n");
num=0;
while(num!=5)
{
printf("number order\n");
scanf(" %d",&num);
Choice(Q,num);
}
}
return 0;
}
不知道队列规模时可使用链队列
原因:使用单链表表示,添加了头指针可指向的头结点;在入队前不需要判断队列是否已满,只需要为入队元素动态分配结点空间并在出队后释放出队元素所占空间;不需要提前知道队列规模
代码示例:
#include<stdio.h>
#include<math.h>
//链队列-整数入队
typedef struct Queuenode
{
int data;
typedef Queuenode *next;
}Queuenode,*Queueptr;
typedef struct Linkqueue
{
Queueptr front;
Queueptr rear;
}
void Initqueue(Linkqueue *Q)
{
Q->front=Q->rear=new Qnode;
Q->front->next=NULL;
}
void Pushqueue(Linkqueue *Q, int e)
{
p=new Queuenode;
p->data=e;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
}
int Popqueue(Linkqueue *Q)
{
int e;
if(Q->front==Q->rear) return 0;
p=new Queuenode;
p=Q->front->next;
e=p->data;
Q->front->next=p->next;
if(Q->rear==p) Q->rear=Q->front;
delete p;
return 1;
}
int Gettopqueue(Linkqueue *Q)
{
if(Q->front!=Q->rear) return Q->frontnext->data;
}
void action(Linkqueue *Q,int order)
{
switck(order)
{
case 1:
int e;
scanf("%d",&e);
Pushqueue(Q,e);
break;
case 2:
if(Popqueue(Q)) printf("succeed\n");
else printf("failed\n");
break;
case 3:
printf("%d\n",Gettopqueue(Q));
break;
default:break;
}
}
int main()
{
Linkqueue *Q;
Initqueue(Q);
int order;
printf("1-push\t2-pop\t3-get value\t4-enter over\n");
scanf("%d",&order);
while(order!=4)
{
action(order);
printf("enter the next order\n");
scanf("%d",&order);
}
return 0;
}