栈和队列是两种重要的线性结构,也是线性表,是操作受限的线性表;从数据类型的角度看,他们是和线性表不相同的抽象数据类型
栈
限定仅在表尾进行插入或删除操作的线性表
表尾称为栈顶,表头称为栈底,退栈的第一个元素为栈顶元素,故称为后进先出的线性表
顺序栈:用顺序表实现的栈
1.定义
#define MAXSIZE 100
typedef struct{
SElemType *top;
SElemType *base;
int stacksize;
}SqStack;
2.初始化
动态分配空间;top==base表示栈空;stacksize置为最大
Status InitStack(SqStack &S)
{
//S.base=new SElemType[MAXSIZE];
S.base=(SElemType *)malloc(S.stacksize*sizeof(SElemType));
//if(!S.base) exit(OVERFLOW);
if(S.base==NULL)
{
printf("栈的初始化失败!");
exit(0);
}
S.top==S.base;
S.stacksize=MAXSIZE;
return OK:
}
3.入栈
先判满;将新元素压入栈底,top++
Status Push(SqStack &S,SElemType S)
{
if(S.top-S.base==S.stacksize) return ERROR;
*s.top++=e;
return OK;
}
4.出栈
判空;栈顶元素--,栈顶元素出栈
/*Status Pop(SqStack &S,SElemType e)
{
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}*/
SqStack Pop(SqStack &S)
{
if(StackEmpty(S))
{
printf("栈为空栈,无法出栈!");
return S;
}
else
{
S.top--;
SElemType e=*S.top;
printf("出栈元素为%d",e);
return S;
}
}
5.取栈顶元素
SElemType GetTop(SqStack S)
{
if(S.top!=S.base)
{
return *(S.top-1);
}
}
链栈:单链表实现
1.定义
typedef struct StackNode{
ElemType data;
Struct StackNode *next;
}StackNode,*LinkStack;
//无头结点,头指针就是栈顶
2.初始化
Status InitStack(LinkStack S)
{
S=NULL;
return OK;
}
3.入栈
Status Push(LinkStack &S,SElemType e)
{
p=new StackNode;
p->data=e;
p->next=S;
S=p;
return OK;
}
4.出栈
Status Pop(LinkStack &S,SElemType &e)
{
if(S==NULL) return ERROR;
e=s->data;
p=S;//用p临时保存栈顶元素空间,以备释放
S=S->next;
delete p;
return OK;
}
5.取栈顶元素
SElemType GetTop(LinkStack S)
{
if(S!=NULL)
{
return S->data;
}
}
顺序栈基本操作整合(双指针)
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef int SElemType;
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;//栈的最大容量
}SqStack;//顺序栈
SqStack InitStack(SqStack &S)
{
S.base=(SElemType *)malloc(S.stacksize*sizeof(SElemType));
if(S.base==NULL)
{
printf("栈的初始化失败!");
exit(0);
}
S.top=S.base;
S.stacksize=MAXSIZE;
return S;
}
int StackEmpty(SqStack S)
{
if(S.top==S.base)
{
return 1;
}
else
{
return 0;
}
}
int StackFull(SqStack S)
{
if(S.top-S.base==MAXSIZE)
{
return 1;
}
else return 0;
}
SqStack Push(SqStack &S,SElemType e)
{
if(StackFull(S))
{
printf("栈满了,无法添加!");
return S;
}
else
{
*S.top=e;
S.top++;
}
return S;
}
SqStack Pop(SqStack &S)
{
if(StackEmpty(S))
{
printf("栈为空栈,无法出栈!");
return S;
}
else
{
S.top--;
SElemType e=*S.top;
printf("出栈元素为%d",e);
return S;
}
}
void DisplayStack(SqStack S)
{
if(StackEmpty(S))
{
printf("栈为空栈!\n");
return ;
}
printf("栈中元素为:");
printf("顶端[");
while(S.top!=S.base)
{
S.top--;
printf("%d",*S.top);
}
printf("]底端\n");
}
int main()
{
SqStack S;
char ch;
S=InitStack(S);
printf("Do you want to push to stack?(Y/N)");
scanf(" %c", &ch);
while (ch == 'Y' || ch == 'y')
{
int e;
scanf("%d",&e);
S = Push (S,e); /* 入栈 */
DisplayStack (S);/* 打印栈中元素 */
printf("Do you want to push to stack?(Y/N)");
scanf(" %c", &ch);
}
printf("Do you want to pop (Y/N)");
scanf(" %c", &ch);
while (ch == 'Y' || ch == 'y')
{
S = Pop (S);
DisplayStack (S);
printf("Do you want to pop (Y/N)");
scanf(" %c", &ch);
}
return 0;
}
十进制转二进制 以数组单指针顺序栈实现
#include <bits/stdc++.h>
using namespace std;
#define MaxSize 100 /* 栈最大容量 */
int top; /* 栈顶指针 */
int mystack[MaxSize]; /* 顺序栈 */
/*判栈是否为空,空返回true,非空返回false */
bool isEmpty();
/* 元素x入栈 */
void Push(int x);
/* 取栈顶元素 */
int getTop();
/* 删除栈顶元素 */
void Pop();
/* 十进制正整数转换为二进制 */
void dec2bin(int x) {
top = -1; /* 初始化栈顶指针 */
while (x) {
Push(x % 2);
x >>= 1;
}
while (!isEmpty()) {
int t = getTop();
Pop();
printf("%d", t);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
int n;
while (scanf("%d", &n) != EOF) {
dec2bin(n);
}
return 0;
}
/* 请在这里填写答案 */
/*判栈是否为空,空返回true,非空返回false */
bool isEmpty()
{
if(top==-1) return 1;
else return 0;
}
/* 元素x入栈 */
void Push(int x)
{
if(top==MaxSize-1)
{
return ;
}
else
{
top++;
mystack[top]=x;
}
}
/* 取栈顶元素 */
int getTop()
{
return mystack[top];
}
/* 删除栈顶元素 */
void Pop()
{
if(isEmpty())
{
return ;
}
else
{
top--;
}
}
链栈的基本操作
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct StackNode{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
int InitStack(LinkStack &S)
{
S=NULL;
return 1;
}
int Push(LinkStack &S,int e)
{
StackNode *p;
p=new StackNode;
p->data=e;
p->next=S;
S=p;
return 1;
}
int Pop(LinkStack &S,int &e)
{
StackNode *p;
p=new StackNode;
if(S==NULL) return 0;
e=S->data;
p=S;
S=S->next;
delete p;
return 1;
}
int GetTop(LinkStack S)
{
if(S!=NULL) return S->data;
else return -1;
}
int main()
{
LinkStack S;
InitStack(S);
int n,e;
scanf("%d",&n);
while(n--)
{
scanf("%d",&e);
Push(S,e);
}
printf("元素的出栈顺序为:");
while(S!=NULL)
{
printf("%d ",GetTop(S));
Pop(S,e);
}
return 0;
}
循环队列(顺序)
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef int QElemType;
typedef struct{
QElemType *base;
int front;
int rear;
}SqQueue;
SqQueue InitQueue(SqQueue &Q)
{
Q.base=new QElemType[MAXSIZE];
if(!Q.base)
{
printf("队列初始化失败!");
exit(0);
}
else
{
Q.front=Q.rear=0;
return Q;
}
}
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
int EnQueue(SqQueue &Q,QElemType e)
{
if((Q.rear+1)%MAXSIZE==Q.front) return 0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return 1;
}
int DeQueue(SqQueue &Q)//,QElemType &e)
{
if(Q.rear==Q.front) return 0;
//e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return 1;
}
int GetHead(SqQueue Q)
{
if(Q.front!=Q.rear)
{
return Q.base[Q.front];
}
}
int main()
{
SqQueue q;
q=InitQueue(q);
EnQueue(q,5);
EnQueue(q,4);
EnQueue(q,3);
EnQueue(q,2);
EnQueue(q,1);
printf("队列长度为:%d\n",QueueLength(q));
for(int i=0;i<QueueLength(q);i++)
{
printf("%d ",q.base[i]);
}
DeQueue(q);
DeQueue(q);
DeQueue(q);
DeQueue(q);
DeQueue(q);
return 0;
}
循环队列(链式)
/*循环队列*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAXSIZE 10
typedef struct _queue
{
int front;//队头指针
int rear;//队尾指针
int *data;//指向数据区
}queue;
//创建一个空队列
queue* createQueue();
//入队
void enQueue(queue* q, int x);
//判断队列是否已满
bool isFull(queue* q);
//出队
void deQueue(queue* q);
//得到队头元素的值
int front(queue* q);
//判断队列是否为空
bool isEmpty(queue* q);
//返回队列长度
int size(queue* q);
//销毁队列
void destroyQueue(queue* q);
//从0号位置开始输出数据区的所有元素。无效位置输出'X'
void show(queue* q);
int main(void)
{
char cmd[20];
queue *pQueue = createQueue();
int x;
scanf("%s", cmd);
while (strcmp(cmd, "END") != 0)
{
if (strcmp(cmd, "ENQUEUE") == 0)
{
if (isFull(pQueue) == true)
{
printf("FULL\n");
}
else
{
scanf("%d", &x);
enQueue(pQueue, x);
}
}
if (strcmp(cmd, "DEQUEUE") == 0)
{
if (isEmpty(pQueue) == true)
{
printf("EMPTY\n");
}
else
{
deQueue(pQueue);
}
}
if (strcmp(cmd, "GETFRONT") == 0)
{
x = front(pQueue);
printf("%d\n", x);
}
if (strcmp(cmd, "SIZE") == 0)
{
printf("SIZE = %d\n", size(pQueue));
}
if (strcmp(cmd, "SHOW") == 0)
{
show(pQueue);
}
scanf("%s", cmd);
}
destroyQueue(pQueue);
return 0;
}
//从0号位置开始输出数据区的所有元素。无效位置输出'X'
void show(queue* q)
{
if (q->front == q->rear)
return;
if (q->front < q->rear)
{
for (int i = 0; i < q->front; i++)
{
printf("X ");
}
for (int i = q->front; i < q->rear; i++)
{
printf("%d ", q->data[i]);
}
for (int i = q->rear; i < MAXSIZE; i++)
{
printf("X ");
}
}
else
{
for (int i = 0; i < q->rear; i++)
{
printf("%d ", q->data[i]);
}
for (int i = q->rear; i < q->front; i++)
{
printf("X ");
}
for (int i = q->front; i < MAXSIZE; i++)
{
printf("%d ", q->data[i]);
}
}
printf("\n");
}
/* 请在这里填写答案 */
queue* createQueue()
{
queue* Q = (queue*)malloc(MAXSIZE*sizeof(queue));
Q->data=(int *)malloc(MAXSIZE*sizeof(int));
if(!Q->data) exit(0);
Q->front=Q->rear=0;
return Q;
}
//入队
void enQueue(queue* q, int x)
{
if(isFull(q)) return ;
q->data[q->rear]=x;
q->rear=(q->rear+1)%MAXSIZE;
}
//判断队列是否已满
bool isFull(queue* q)
{
if((q->rear+1)%MAXSIZE==q->front) return true;
else return false;
}
//出队
void deQueue(queue* q)
{
if(isEmpty(q)) return ;
q->front=(q->front+1)%MAXSIZE;
}
//得到队头元素的值
int front(queue* q)
{
if(!isEmpty(q)) return q->data[q->front];
}
//判断队列是否为空
bool isEmpty(queue* q)
{
if(q->front==q->rear) return true;
else return false;
}
//返回队列长度
int size(queue* q)
{
return (q->rear - q->front + MAXSIZE) % MAXSIZE;
}
//销毁队列
void destroyQueue(queue* q)
{
free(q->data);
//delete q->data;
q->front=q->rear=0;
}