【数据结构】栈和队列

8 篇文章 1 订阅
5 篇文章 0 订阅

目录

1.栈

1.1栈的概念及结构

 1.2栈的实现

 1.3实现栈的基本框架

1.3.1 StackInit()  初始化栈

1.3.2 StackDestroy() 销毁栈

1.3.3 StackPush() 入栈

1.3.4  StackPop() 出栈

 1.3.5 StackTop() 获取栈顶元素

1.3.6  StackSize()  获取栈中有效元素个数

1.3.7 StackEmpty()判空

2.完整代码

3.相关例题

4.队列

4.1队列的概念及结构

 4.2队列的实现

4.2.1 基本框架

4.2.2 QueueInit()   初始化队列

4.2.3  QueuePush()  队尾入队列

4.2.4 QueueSize() 获取队列中有效元素个数

4.2.5 QueuePop() 队头出队列

4.2.6 QueueFront() 获取队头元素

4.2.7 QueueBack() 获取队列队尾元素

4.2.8  QueueEmpty() 检测队列是否为空

4.2.9 QueueDestroy() 销毁队列

4.3完整代码


1.栈

1.1栈的概念及结构


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

 1.2栈的实现


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

// 下面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
typedef int STDataType;
#define N 10
typedef struct Stack
{
STDataType _a[N];
int _top; // 栈顶
}Stack;
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
// 栈顶
int _capacity; // 容量
}Stack;

 1.3实现栈的基本框架

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
// 栈顶
int _capacity; // 容量
}Stack;


// 初始化栈
void StackInit(Stack* pst);
// 销毁栈
void StackDestroy(Stack* pst);

// 入栈
void StackPush(Stack* pst, STDataType x);
// 出栈
void StackPop(Stack* pst);

// 获取栈顶元素
STDataType StackTop(Stack* pst);
// 获取栈中有效元素个数
int StackSize(Stack* pst);

// 检测栈是否为空,如果为空返回真,如果不为空返回NULL
bool StackEmpty(Stack* pst);

1.3.1 StackInit()  初始化栈

// 初始化栈
void StackInit(Stack* pst)
 {
		assert(pst);
		pst->_a = NULL;
		pst->_capacity = 0;
		pst->_top = 0;
  }

1.3.2 StackDestroy() 销毁栈

// 销毁栈
void StackDestroy(Stack* pst)
{
assert(pst);
	free(pst->_a);
	pst->_a = NULL;
	pst->_top = pst->_capacity = 0;
}


1.3.3 StackPush() 入栈


// 入栈
void StackPush(Stack* pst, STDataType x)
{assert(pst);
	//扩容
	if (pst->_top == pst->_capacity)
	{
		assert(pst);
		int newcapacity = pst->_capacity==0? 4:pst->_capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->_a, newcapacity * sizeof(STDataType));
        
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
        pst->_a=tmp;
        pst->_capacity=newcapacity;
	}
	pst->_a[pst->_top] = x;
	pst->_top++;
	
}

1.3.4  StackPop() 出栈


// 出栈
void StackPop(Stack* pst)
{
	assert(pst&&pst->_top>0);
	pst->_top--;
}

 1.3.5 StackTop() 获取栈顶元素

// 获取栈顶元素
STDataType StackTop(Stack* pst)
{
	assert(pst && pst->_top > 0);
	return pst->_a[pst->_top - 1];
}

1.3.6  StackSize()  获取栈中有效元素个数

// 获取栈中有效元素个数
int StackSize(Stack* pst)
{
	assert(pst);
	return pst->_top;
}

1.3.7 StackEmpty()判空

bool StackEmpty(Stack * pst)
{// 检测栈是否为空,如果为空返回真,如果不为空返回NULL
	assert(pst);
	return pst->_top == 0;
}

2.完整代码

Stack.h

#pragma once
#include<iostream>
#include<assert.h>
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;
	// 栈顶
	int _capacity; // 容量
}Stack;


// 初始化栈
void StackInit(Stack* pst);

// 销毁栈
void StackDestroy(Stack* pst);

// 入栈
void StackPush(Stack* pst, STDataType x);

// 出栈
void StackPop(Stack* pst);

// 获取栈顶元素
STDataType StackTop(Stack* pst);

// 获取栈中有效元素个数
int StackSize(Stack* pst);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* pst);

Stack.c

#include"Stack.h"
// 初始化栈
void StackInit(Stack* pst)
 {
		assert(pst);
		pst->_a = NULL;
		pst->_capacity = 0;
		pst->_top = 0;
  }

// 销毁栈
void StackDestroy(Stack* pst)
{
assert(pst);
	free(pst->_a);
	pst->_a = NULL;
	pst->_top = pst->_capacity = 0;
}


// 入栈
void StackPush(Stack* pst, STDataType x)
{
	assert(pst);
	//扩容
	if (pst->_top == pst->_capacity)
	{
		assert(pst);
		int newcapacity = pst->_capacity == 0 ? 4 : pst->_capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->_a, newcapacity * sizeof(STDataType));

		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->_a = tmp;
		pst->_capacity = newcapacity;
	}
	pst->_a[pst->_top] = x;
	pst->_top++;

}

// 出栈
void StackPop(Stack* pst)
{
	assert(pst&&pst->_top>0);
	pst->_top--;
}

// 获取栈顶元素
STDataType StackTop(Stack* pst)
{
	assert(pst && pst->_top > 0);
	return pst->_a[pst->_top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* pst)
{
	assert(pst);
	return pst->_top;
}
bool StackEmpty(Stack * pst)
{// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
	assert(pst);
	return pst->_top == 0;
}

3.相关例题

 解析


bool isValid(char* s) {

    Stack s1;
    StackInit(&s1);
   while(*s)
    {//左括号入栈
        if(*s=='['||*s=='('||*s=='{')
    StackPush(&s1,*s);
    else//右括号出栈,取栈顶的左括号去匹配
    {//如果栈里面没有左括号,右括号去匹配左括号,直接返回
        if(StackEmpty(&s1))
        return false;
        char top=StackTop(&s1);
        StackPop(&s1);
       if((top=='('&&*s!=')')||(top=='{'&&*s!='}')||(top=='['&&*s!=']'))
       {
        return false;
       }
        
        
    }
    s++;
   }
//栈不为空,左括号多于右括号,不匹配
bool ret=StackEmpty(&s1);

  StackDestroy(&s1);
  return ret;
}

4.队列

4.1队列的概念及结构


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

 4.2队列的实现


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

// 链式结构:表示队列
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* _pNext;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
4.2.1 基本框架
typedef int QDataType;

// 链式结构:表示队列
typedef struct QListNode
{
	struct QListNode* next;
	QDataType val;
}QNode;

// 队列的结构
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;
// 初始化队列
void QueueInit(Queue* pq);

// 队尾入队列
void QueuePush(Queue* pq, QDataType x);
// 队头出队列
void QueuePop(Queue* pq);
// 获取队列头部元素
QDataType QueueFront(Queue* pq);
// 获取队列队尾元素
QDataType QueueBack(Queue* pq);

// 获取队列中有效元素个数
int QueueSize(Queue* pq);

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);
4.2.2 QueueInit()   初始化队列
// 初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
4.2.3  QueuePush()  队尾入队列
// 队尾入队列
void QueuePush(Queue* pq, QDataType x)
{//创建节点
	QNode* newnode =(QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
	}
	newnode->next = NULL;
	newnode->val = x;
	//尾插
	if (pq->ptail == NULL)
	{//只有头节点
		pq->phead = pq->ptail = newnode;
	}
	else
	{ 
	pq->ptail->next = newnode;
	pq->ptail = newnode;
	}
	pq->size++;
}
4.2.4 QueueSize() 获取队列中有效元素个数

// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
4.2.5 QueuePop() 队头出队列
/ 队头出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	if (pq->phead->next == NULL)//单个节点
	{
		free(pq->phead);
		pq->phead = pq->ptail;
	}
	else {
		//多个节点
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}
4.2.6 QueueFront() 获取队头元素

// 获取队列头部元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->phead->val;
}
4.2.7 QueueBack() 获取队列队尾元素
// 获取队列队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->ptail->val;
}
4.2.8  QueueEmpty() 检测队列是否为空

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* pq)
{
	return pq->size || 0;
}
4.2.9 QueueDestroy() 销毁队列
// 销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

4.3完整代码

Queue.h

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int QDataType;

// 链式结构:表示队列
typedef struct QListNode
{
	struct QListNode* next;
	QDataType val;
}QNode;

// 队列的结构
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;
// 初始化队列
void QueueInit(Queue* pq);

// 队尾入队列
void QueuePush(Queue* pq, QDataType x);
// 队头出队列
void QueuePop(Queue* pq);
// 获取队列头部元素
QDataType QueueFront(Queue* pq);
// 获取队列队尾元素
QDataType QueueBack(Queue* pq);

// 获取队列中有效元素个数
int QueueSize(Queue* pq);

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);

Queue.c

#include"Queue.h"
// 初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

// 队尾入队列
void QueuePush(Queue* pq, QDataType x)
{//创建节点
	QNode* newnode =(QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
	}
	newnode->next = NULL;
	newnode->val = x;
	//尾插
	if (pq->ptail == NULL)
	{//只有头节点
		pq->phead = pq->ptail = newnode;
	}
	else
	{ 
	pq->ptail->next = newnode;
	pq->ptail = newnode;
	}
	pq->size++;
}

// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

// 队头出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	if (pq->phead->next == NULL)//单个节点
	{
		free(pq->phead);
		pq->phead = pq->ptail;
	}
	else {
		//多个节点
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}

// 获取队列头部元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->phead->val;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->ptail->val;
}




// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* pq)
{
	return pq->size || 0;
}

// 销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熬夜苦读学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值