栈和队列学习笔记1

第三章_栈和队列

主要参考了王道的书,主要针对考研

3.1栈

3.1.1 栈的概述

  1. 栈的定义

    只允许一端(栈顶top)操作,先进后出

    n个不同元素出栈的不同排列组合个数为(1/(n+1))C(n,2n)

  2. 栈的基本操作

    //初始化栈
    void StackInit(stack& s);
    //判断栈空
    bool isEmpty(stack s);
    //判断栈满
    bool isFull(stack s);
    //入栈,把x元素放入栈中
    bool Push(stack& s, ElementType x);
    //出栈,把出栈的元素赋值给x
    bool Pop(stack& s, ElementType& x);
    //判断栈满
    bool isFull(stack s);
    //读取栈顶元素
    int getTop(stack& s);
    

3.1.2 顺序栈

  1. 存储类型
#define MAXSIZE 6
typedef int ElementType;//定义数据类型
//定义栈的存储结构
typedef struct stack {
	ElementType data[MAXSIZE];//存放栈中的数据 
	int top;//记录栈顶的下标
}stack;
  1. 初始化

    //初始化栈
    void StackInit(stack &s)
    {
    	s.top = -1;
    }
    
  2. 判断空

//判断栈空
bool isEmpty(stack s)
{
  if (s.top == -1)
  	return true;
  return false;
}
  1. 判断满
//判断栈满
bool isFull(stack s)
{
  if (s.top == MAXSIZE-1)
  	return true;
  return false;
}
  1. 入栈
//入栈,把x元素放入栈中
bool Push(stack& s,ElementType x)
{
  //判断栈是否满了,如果是空的就不能入栈
  if (isFull(s))
  {
  	printf("栈满不能入栈\n");
  	return false;
  }
  s.top++;
  s.data[s.top] = x;
  return true;
}
  1. 出栈

    //出栈,把出栈的元素赋值给x
    bool Pop(stack& s, ElementType& x)
    {
    	//判断栈是否为空,如果是空的就不能再出栈了
    	if (isEmpty(s))
    	{
    		printf("栈空了不能出栈");
    		return false;
    	}
    	x = s.data[s.top];
    	s.top--;
    	return true;
    }
    
  2. 读取栈顶元素

    //读取栈顶元素
    int getTop(stack& s)
    {
    	if (isEmpty(s))
    	{
    		printf("栈为空,不能读取栈顶元素");
    		return -1;
    	}
    	return s.data[s.top];
    }
    
顺序栈的实现
//顺序栈的实现
#define MAXSIZE 6
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;//定义数据类型
//定义栈的存储结构
typedef struct stack {
	ElementType data[MAXSIZE];//存放栈中的数据 
	int top;//记录栈顶的下标
}stack;
//1.初始化栈
void StackInit(stack& s);
//2.判断栈空
bool isEmpty(stack s);
//3.判断栈满
bool isFull(stack s);
//4.入栈,把x元素放入栈中
bool Push(stack& s, ElementType x);
//5.出栈,把出栈的元素赋值给x
bool Pop(stack& s, ElementType& x);
//6.读取栈顶元素
int getTop(stack& s);

int main()
{
	stack s;
	StackInit(s);
	//判断栈是否为空
	printf("栈是否为空:%d\n", isEmpty(s));
	//入栈
	for (int i = 0; i < 6; i++)
	{
		Push(s, i+1);
	}
	//判断栈是否为满
	printf("栈是否为满:%d\n", isFull(s));

	//读取栈顶元素
	ElementType e = 0;
	e=getTop(s);
	printf("目前栈顶元素是%d\n\n", e);
	//出栈
	for (int i = 0; i < 6; i++)
	{
		Pop(s, e);
		printf("目前出栈的元素是%d\n", e);
		e = getTop(s);
		if (e != -1)
		printf("目前栈顶元素是%d\n\n", e);
	}
	
}

//1.初始化栈
void StackInit(stack &s)
{
	s.top = -1;
}

//2.判断栈空
bool isEmpty(stack s)
{
	if (s.top == -1)
		return true;
	return false;
}

//3.判断栈满
bool isFull(stack s)
{
	if (s.top == MAXSIZE-1)
		return true;
	return false;
}

//4.入栈,把x元素放入栈中
bool Push(stack& s,ElementType x)
{
	//判断栈是否满了,如果是空的就不能入栈
	if (isFull(s))
	{
		printf("栈满不能入栈\n");
		return false;
	}
	s.top++;
	s.data[s.top] = x;
	return true;
}

//5.出栈,把出栈的元素赋值给x
bool Pop(stack& s, ElementType& x)
{
	//判断栈是否为空,如果是空的就不能再出栈了
	if (isEmpty(s))
	{
		printf("栈空了不能出栈");
		return false;
	}
	x = s.data[s.top];
	s.top--;
	return true;
}

//6.读取栈顶元素
int getTop(stack& s)
{
	if (isEmpty(s))
	{
		printf("栈为空,不能读取栈顶元素");
		return -1;
	}
	return s.data[s.top];
}

3.1.3 链栈

链栈的优点在于便于多个栈共享存储空间和提高效率,其实就是带头节点的链表进行头插法和头部删去法

3.2队列

3.2.1 队列的基本概念

  1. 定义

    一端插入,一端删除,先进先出

    插入称入队(从队尾插入),删除称出队(从队头删除)

  2. 基本操作

    
    

3.2.2 顺序队列

  1. 队列的顺序存储

分配一块连续的存储空间存放队列中的元素,头指针front和尾指针rear分别指向队头元素和队尾元素的下一个位置。

初始状态:front==rear==0

进队:队不满,rear+1

出队:队不空,front+1

这种队列判断满比较复杂,于是有了循环队列

比如增加一个size来看是否和MAXSIZE相等,或者用一个flag来标志,插入导致rearfront则为满,删除导致rearfront则为空

  1. 循环队列

    用一个额外的空间判断满:(rear+1)%MAXSIZE==front

循环队列的实现
/*循环顺序队列的实现*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 6
typedef int ElementType ;

//定义队列的数据类型
typedef struct queue
{
	ElementType* data;
	int rear;//尾指针,记录队尾后一个元素的下标
	int front;//头指针,记录队头的下标
}queue;

//1.队列的初始化
void QueueInit(queue& q);
//2.判断队列是否为空
bool isEmpty(queue q);
//3.判断队列是否已满
bool isFull(queue q);
//4.出队
bool DeQueue(queue& q, ElementType& x);
//5.入队
bool EnQueue(queue& q, ElementType e);
//6.统计队列中有多少个元素
int QueueLen(queue q);

int main()
{
	queue q;
	QueueInit(q);//初始化队列
	printf("队列是否为空:%d\n", isEmpty(q));//判空
	for(int i=0;i<MAXSIZE;i++)
		EnQueue(q,i+1);//入队

	printf("队列中有%d个元素\n", QueueLen(q));
	printf("队列是否为满:%d\n", isFull(q));//判满
	ElementType e;
	printf("sss:%d\n", q.data[4]);
	if(DeQueue(q, e))
		printf("当前出队的元素是:%d\n", e);

	printf("队列中有%d个元素\n", QueueLen(q));


}

//1.队列的初始化
void QueueInit(queue& q)
{
	q.data = (ElementType*)malloc(sizeof(ElementType) * MAXSIZE);
	q.rear = 0;
	q.front = 0;
}

//2.判断队列是否为空
bool isEmpty(queue q)
{
	return q.rear == q.front;

}

//3判断队列是否已满
bool isFull(queue q)
{
	return (q.rear + 1) % MAXSIZE == q.front;
}

//4出队,x用来存出队的元素
bool DeQueue(queue &q,ElementType& x)
{
	//队列为空不能出队
	if (isEmpty(q))
		return false;
	x = q.data[q.front];
	q.front = (q.front + 1) % MAXSIZE;
	return true;
}

//5入队
bool EnQueue(queue &q,ElementType e)
{
	if (isFull(q))//队列满了不能入队
		return false;
	q.data[q.rear] = e;
	q.rear = (q.rear + 1) % MAXSIZE;
	
	return true;
}

//6.统计队列中有多少个元素
int QueueLen(queue q)
{
	return (q.rear - q.front + MAXSIZE) % MAXSIZE;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值