前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >栈和队列的总结与应用

栈和队列的总结与应用

作者头像
发布2024-05-16 15:10:02
580
发布2024-05-16 15:10:02
举报
文章被收录于专栏:转自CSDN转自CSDN

什么是栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和 删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据也在栈顶。

就类似于在一个竖直的容器里面放木头,你最先取出来的是你最后放进去的。

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上、入数据的代价比较小。

代码:

头文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>


typedef int StDataType;

typedef struct Stack
{
	StDataType * a;
	int top;
	int capacity;
}ST;

void STinit(ST* st);
void STDestroy(ST* st);
//入栈 出栈
void STPush(ST* st, StDataType x);
void StPop(ST* st);
//读取数据
StDataType STTop(ST* st);
//判空
bool STEmpty(ST* st);
//获取数据个数
bool STSize(ST* st);

实现文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include"Stack.h"
void STinit(ST* st)
{
	assert(st);
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
}
void STDestroy(ST* st)
{
	assert(st);
	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;
}
//入栈 出栈
void STPush(ST* st, StDataType x)
{
	assert(st);
	if (st->top == st->capacity)
	{
		int newcapacity = st->capacity == 0 ? 4: st->capacity * 2;
		StDataType* tmp = (StDataType*)realloc(st->a, newcapacity * sizeof(StDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		st->a = tmp;
		st->capacity = newcapacity;
	}
	st->a[st->top++] = x;
}
void StPop(ST* st)
{
	assert(st&&st->top>0);
	st->top--;
}
//读取数据
StDataType STTop(ST* st)
{
	assert(st && st->top > 0);
	return st->a[st->top - 1];
}

//判空
bool STEmpty(ST* st)
{
	assert(st);

	return st->top == 0;
}
//获取数据个数
bool STSize(ST* st)
{
	assert(st);

	return st->top;
}

什么是队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

代码:

头文件

代码语言:javascript
复制
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode * next;
	QDataType val;
}QNode;

typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void QueueInit(Queue* p);
void QueuePush(Queue* p, QDataType x);
QDataType QueueFront(Queue* p);
QDataType QueueBack(Queue* p);
void QueuePop(Queue* p);
QDataType QueueSize(Queue* p);
bool QueueEmpty(Queue* p);
void QueueDestroy(Queue* p);

实现文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
void QueueInit(Queue* p)
{
	assert(p);
	p->phead = p->ptail = NULL;
	p->size = 0;
}
void QueuePush(Queue* p, QDataType x)//尾插
{
	assert(p);
	QNode* next = (QNode*)malloc(sizeof(QNode));
	if (next == NULL)
	{
		perror("error malloc");
		exit(1);
	}
	next->next = NULL;
	next->val = x;
	if (p->phead != NULL)
	{
		p->ptail->next = next;
		p->ptail = p->ptail->next;
	}
	else
	{
		p->phead = p->ptail = next;
	}
	p->size++;
}
//头删
void QueuePop(Queue* p)
{
	assert(p&&p->phead);
	if (p->phead->next == NULL)
	{
		free(p->phead);
		p->phead = p->ptail = NULL;
	}
	else
	{
		QNode* ptr = p->phead->next;
		free(p->phead);
		p->phead = ptr;
	}
	p->size--;
}
//读取队列的长度
QDataType QueueSize(Queue* p)
{
	assert(p);
	return p->size;
}
//摧毁队列
void QueueDestroy(Queue* p)
{
	assert(p);
	while (p->phead)
	{
		QueuePop(p);
	}
	p->phead = p->ptail = NULL;
	p->size = 0;
}

bool QueueEmpty(Queue* p)
{
	assert(p);
	return p->size == 0;
}
//查看头部元素
QDataType QueueFront(Queue* p)
{
	assert(p && p->ptail);
	return p->phead->val;
}
//查看尾部元素
QDataType QueueBack(Queue* p)
{
	assert(p && p->ptail);
	return p->ptail->val;
}

例题 :

20. 有效的括号 - 力扣(LeetCode)

代码语言:javascript
复制
typedef char StDataType;

typedef struct Stack
{
	StDataType * a;
	int top;
	int capacity;
}ST;

void STinit(ST* st);
void STDestroy(ST* st);
//入栈 出栈
void STPush(ST* st, StDataType x);
void StPop(ST* st);
//读取数据
StDataType STTop(ST* st);
//判空
bool STEmpty(ST* st);
//获取数据个数
bool STSize(ST* st);
void STinit(ST* st)
{
	assert(st);
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
}
void STDestroy(ST* st)
{
	assert(st);
	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;
}
//入栈 出栈
void STPush(ST* st, StDataType x)
{
	assert(st);
	if (st->top == st->capacity)
	{
		int newcapacity = st->capacity == 0 ? 4: st->capacity * 2;
		StDataType* tmp = (StDataType*)realloc(st->a, newcapacity * sizeof(StDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		st->a = tmp;
		st->capacity = newcapacity;
	}
	st->a[st->top++] = x;
}
void StPop(ST* st)
{
	assert(st&&st->top>0);
	st->top--;
}
//读取数据
StDataType STTop(ST* st)
{
	assert(st && st->top > 0);
	return st->a[st->top - 1];
}

//判空
bool STEmpty(ST* st)
{
	assert(st);

	return st->top == 0;
}
//获取数据个数
bool STSize(ST* st)
{
	assert(st);

	return st->top;
}
bool isValid(char* s) {
    ST st;
    STinit(&st);
    while(*s != 0)
    {
        if(*s == '{' || *s == '[' || *s == '(')
        {
            STPush(&st,*s);
        }
        else
        {
            if(STEmpty(&st))
            {
            STDestroy(&st);
            return false;
            }
            char top = STTop(&st);
            StPop(&st);
            if(top == '(' && *s != ')')
            {
                STDestroy(&st);
                return false;
            }
            if(top == '[' && *s != ']')
            {
                STDestroy(&st);
                return false;
            }  
            if(top == '{' && *s != '}')
            {
                STDestroy(&st);
                return false;
            }
        }
        s++;
    }   
    if(!STEmpty(&st))
    {
    STDestroy(&st);
    return false;
    }
    return true;
}

. - 力扣(LeetCode)

代码语言:javascript
复制
typedef int StDataType;

typedef struct Stack
{
	StDataType * a;
	int top;
	int capacity;
}ST;

void STinit(ST* st);
void STDestroy(ST* st);
//入栈 出栈
void STPush(ST* st, StDataType x);
void StPop(ST* st);
//读取数据
StDataType STTop(ST* st);
//判空
bool STEmpty(ST* st);
//获取数据个数
bool STSize(ST* st);

void STinit(ST* st)
{
	assert(st);
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
}
void STDestroy(ST* st)
{
	assert(st);
	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;
}
//入栈 出栈
void STPush(ST* st, StDataType x)
{
	assert(st);
	if (st->top == st->capacity)
	{
		int newcapacity = st->capacity == 0 ? 4: st->capacity * 2;
		StDataType* tmp = (StDataType*)realloc(st->a, newcapacity * sizeof(StDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		st->a = tmp;
		st->capacity = newcapacity;
	}
	st->a[st->top++] = x;
}
void StPop(ST* st)
{
	assert(st&&st->top>0);
	st->top--;
}
//读取数据
StDataType STTop(ST* st)
{
	assert(st && st->top > 0);
	return st->a[st->top - 1];
}

//判空
bool STEmpty(ST* st)
{
	assert(st);

	return st->top == 0;
}
//获取数据个数
bool STSize(ST* st)
{
	assert(st);

	return st->top;
}

typedef struct {
    ST s1;
    ST s2;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    STinit(&obj->s1);
    STinit(&obj->s2);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    if(!STEmpty(&obj->s1))
    {
        STPush(&obj->s1, x);
    }
    else
    {
        STPush(&obj->s2, x);
    }
}

int myQueuePop(MyQueue* obj) {
    ST* Empty = &(obj->s1);
    ST* NonEmpty = &(obj->s2);
    if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty) > 1)
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }
    int top = STTop(NonEmpty);
    StPop(NonEmpty);
    return top;
}

int myQueuePeek(MyQueue* obj) {
    ST* Empty = &(obj->s1);
    ST* NonEmpty = &(obj->s2);
    if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty) > 1)
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }
    int top = STTop(NonEmpty);
    STPush(Empty, STTop(NonEmpty));
    StPop(NonEmpty);
    return top;
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->s1) && STEmpty(&obj->s2);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->s1);
    STDestroy(&obj->s2);
    free(obj);
}

232. 用栈实现队列 - 力扣(LeetCode)

代码语言:javascript
复制
typedef int StDataType;

typedef struct Stack
{
	StDataType * a;
	int top;
	int capacity;
}ST;

void STinit(ST* st);
void STDestroy(ST* st);
//入栈 出栈
void STPush(ST* st, StDataType x);
void StPop(ST* st);
//读取数据
StDataType STTop(ST* st);
//判空
bool STEmpty(ST* st);
//获取数据个数
int STSize(ST* st);

void STinit(ST* st)
{
	assert(st);
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
}
void STDestroy(ST* st)
{
	assert(st);
	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;
}
//入栈 出栈
void STPush(ST* st, StDataType x)
{
	assert(st);
	if (st->top == st->capacity)
	{
		int newcapacity = st->capacity == 0 ? 4: st->capacity * 2;
		StDataType* tmp = (StDataType*)realloc(st->a, newcapacity * sizeof(StDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		st->a = tmp;
		st->capacity = newcapacity;
	}
	st->a[st->top++] = x;
}
void StPop(ST* st)
{
	assert(st&&st->top>0);
	st->top--;
}
//读取数据
StDataType STTop(ST* st)
{
	assert(st && st->top > 0);
	return st->a[st->top - 1];
}

//判空
bool STEmpty(ST* st)
{
	assert(st);

	return st->top == 0;
}
//获取数据个数
int STSize(ST* st)
{
	assert(st);

	return st->top;
}

typedef struct {
    ST s1;
    ST s2;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    STinit(&obj->s1);
    STinit(&obj->s2);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    if(!STEmpty(&obj->s1))
    {
        STPush(&obj->s1, x);
    }
    else
    {
        STPush(&obj->s2, x);
    }
}

int myQueuePop(MyQueue* obj) {
    ST* Empty = &(obj->s1);
    ST* NonEmpty = &(obj->s2);
    if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty) > 1)
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }
    int top = STTop(NonEmpty);
    StPop(NonEmpty);
     if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty))
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }

    return top;
}

int myQueuePeek(MyQueue* obj) {
    ST* Empty = &(obj->s1);
    ST* NonEmpty = &(obj->s2);
    if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty) > 1)
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }
    int top = STTop(NonEmpty);
    STPush(Empty, STTop(NonEmpty));
    StPop(NonEmpty);
    if(!STEmpty(&obj->s1))
    {
        NonEmpty = &(obj->s1);
        Empty = &(obj->s2);
    }
    while(STSize(NonEmpty))
    {
        STPush(Empty, STTop(NonEmpty));
        StPop(NonEmpty);
    }
    return top;
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->s1) && STEmpty(&obj->s2);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->s1);
    STDestroy(&obj->s2);
    free(obj);
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

. - 力扣(LeetCode)

代码语言:javascript
复制
typedef struct {
	int* arr;
	int phead;
	int tail;
	int k;
} MyCircularQueue;

//检查队列是否空了
bool Empty(MyCircularQueue* obj)
{
	return obj->tail == obj->phead;
}
//检查队列是否为满的
bool Full(MyCircularQueue* obj)
{
	return (obj->tail + 1 + obj->k + 1) % (obj->k + 1) == obj->phead;
}

MyCircularQueue* myCircularQueueCreate(int k) {
	int* ptr = (int*)malloc((k+1) * sizeof(int*));//创建出K+1 个空间 多出的空间用于判断
	if (ptr == NULL)
	{
		perror("error malloc");
		exit(1);
	}
	MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
	obj->arr = ptr;
	obj->phead = obj->tail = 0;
	obj->k = k;
	return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//插
	if (Full(obj))
	{
		return false;
	}
	else//插入元素
	{
		obj->arr[obj->tail] = value;
		obj->tail = (++obj->tail) % (obj->k + 1);
        return true;
	}
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {//删除元素
	if (Empty(obj))
	{
		return false;
	}
	else
	{
		obj->phead = (++obj->phead) % (obj->k + 1);
        return true;
	}
}

int myCircularQueueFront(MyCircularQueue* obj) {
	if (Empty(obj))
	{
		return -1;
	}
	else
	{
		return obj->arr[obj->phead];
	}
}

int myCircularQueueRear(MyCircularQueue* obj) {
	if (Empty(obj))
	{
		return -1;
	}
	else
	{
		return obj->arr[(obj->tail -1 + obj->k + 1) % (obj->k + 1)];
	}
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
	return Empty(obj);
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
	return Full(obj);
}

void myCircularQueueFree(MyCircularQueue* obj) {
	free(obj->arr);
	free(obj);
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-05-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是栈
  • 什么是队列
  • 例题 :
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档