栈
栈是限制一端进行插入和删除的线性表,可以插入和删除的一端称为栈顶,另一端成为栈底。
特点
先进后出,后进先出
实现
顺序栈采用数组实现
链式栈采用链表实现
顺序栈和链式栈的区别是存储结构不相同。
顺序栈
#include <stdio.h>
#include <stdlib.h>
#define N 5
//栈结构体定义
typedef struct
{
int data[N];
int top; //代表有效元素个数,标志着栈顶方便插入删除
}stack_t;
/*创建一个空栈*/
stack_t* create()
{
stack_t* p = (stack_t*)malloc(sizeof(stack_t));
if(NULL == p)
{
printf("p malloc failed\n");
return NULL;
}
p->top = 0; //有效元素个数为0,空栈
return p;
}
/*判断栈是否为满*/
int isFull(stack_t* p)
{
return N == p->top;
}
/*判断栈是否为空*/
int isEmpty(stack_t* p)
{
return 0 == p->top;
}
/*入栈*/
int inStack(stack_t *p,int x)
{
if(isFull(p))
{
printf("is a full stack\n");
return -1;
}
p->data[p->top] = x; //在栈顶放入数据
p->top++; //让入栈的元素变为有效数据
}
/*出栈*/
int outStack(stack_t* p)
{
if(isEmpty(p))
{
printf("is a empty stack\n");
return -1;
}
p->top--; //让栈顶元素变为无效
return p->data[p->top]; //返回出栈元素,top--之后刚好指向出栈元素
}
/*获取栈顶元素*/
int getTopValue(stack_t* p)
{
if(isEmpty(p))
{
printf("is a empty stack\n");
return -1;
}
return p->data[p->top-1];//top-1之后才指向栈顶元素
}
/*清空栈*/
void clear(stack_t* p)
{
p->top = 0; //将有效元素个数置为0
}
int main()
{
stack_t *p = create();
inStack(p,11);
inStack(p,22);
inStack(p,33);
inStack(p,44);
inStack(p,55);
inStack(p,66);
printf("top value is %d\n",getTopValue(p));
//循环出栈
while(!isEmpty(p))
{
printf("%d ",outStack(p));
}
printf("\n");
free(p);
return 0;
}
队列
限制在两端进行插入和删除操作的线性表,可以进行插入(入队)这一端称为队尾,可以进行删除(出队)的一端称为队头。
特点
先进先出,后进后出
实现
队列的实现的方式 顺序队列和链式队列。
顺序队列和链式队列的区别?
顺序队列就是顺序表(数组)来实现队列,称为循环队列,采用顺序存储方式;
链式队列就是链表来实现队列,称为链式队列,采用链式存储方式;
存储结构不一样,一个连续,一个不连续。
循环队列
本质就是采用数组来实现的,所以在内存中连续存储;
队列的最大容量为N-1,(浪费一个存储位置用于判断队列是否为满)
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct node
{
int data[N];
int rear; //队头
int front; //队尾
}queue_t;
//1.创建一个空的队列
queue_t* createEmptyQueue()
{
queue_t *p = (queue_t*)malloc(sizeof(queue_t));
if(NULL == p)
{
printf("p malloc failed\n");
return NULL;
}
p->rear = p->front = 0; //头尾赋值相同表示空队列
return p;
}
//2.判断队列是否为空,空返回1,不空返回0
int isEmpty(queue_t* p)
{
return p->rear == p->front;
}
//3.判断队列是否未满
int isFull(queue_t *p)
{
//rear == front 表示队列为空,
//所以浪费一个存储位置来判断队列是否为满,rear+1 == front
//(p->rear+1)%N 对N取余是刚好 rear在最后一个位置+1超过队列的大小
return (p->rear+1)%N == p->front;
}
//4.入队
int inQueue(queue_t *p,int x)
{
//入队之前对队列是否为满进行判断(容错判断)
if(isFull(p))
{
printf("is a full queue\n");
return -1;
}
p->data[p->rear] = x; //数据x入队rear为下标的位置
p->rear = (p->rear+1)%N; //rear+1将入队数据变得有效,%N防止出现数组越界
return 0;
}
//5.出队
int outQueue(queue_t *p)
{
if(isEmpty(p))
{
printf("is a empty queue\n");
return -1;
}
int temp = p->data[p->front];
p->front = (p->front+1)%N;
return temp;
}
//6.求队列长度
int getLen(queue_t *p)
{
if(p->rear >= p->front)
{
return p->rear - p->front;
}
else
{
return (p->rear+N) - p->front;
}
}
int main()
{
queue_t *p = create();
if(NULL == p)
return -1;
inQueue(p,11);
inQueue(p,22);
inQueue(p,33);
printf("p->rear is %d,p->front is %d\n",p->rear,p->front);
printf("getLen is %d\n",getLen(p));
while(!isEmpty(p))
{
printf("%d",outQueue(p));
}
printf("\n");
free(p);
return 0;
}
栈和队列的区别?
先回答两者的概念,在说其各自的特点。
栈是限制在一端进行插入和删除操作的,特点是先进后去,后进先出;
队列是限制在两端进行插入和删除操作的,可以入队端称为队尾,可以出队端称为队头,特点是先进先出,后进后出。