数据结构第四章(栈和队列)

Lesson4–栈和队列

【本节目标】

1.栈

2.队列

3.栈和队列面试题

一. 栈
1.1栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的的一端进行插入和删除操作的一端称为栈顶,另一端称为栈底
遵循:“先进后出的原则”
压栈:栈的插入数据叫做进栈/压栈,入数据在栈顶
出栈:栈的删除叫做出栈。出数据也在栈顶
在这里插入图片描述
1.2 栈的实现
栈的实现一般可以使用数组或者链表来实现,但是相对而言数组的结构实现更优一点。因为数组再尾部插入数据的代价比较小
在这里插入图片描述

//Stack.h
#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
//这里也分静态栈和动态栈,但是这里我们以动态栈为主要

typedef int STDataType;
 typedef struct stack
{
	int* a; //这里我们的栈是用数组实现的
	int top; //栈底
	int capacity;//栈中的真实数据
}ST;//给结构体重新命名

 void STInit(ST*ps);//向栈插入数据
 void STDestory(ST* ps);//重置

 void STPush(ST* ps,STDataType x);//插入数据
 void STPop(ST* ps);//删除数据
 int STsize(ST* ps);//栈中数据个数
 bool STEmpty(ST* ps); //栈中数据是不是为空
 STDataType STTop(ST* ps);//栈顶数据

//Stack.c
#define _CRT_SECURE_NO_WARNINGS
#include"Stack.h"
void STInit(ST* ps)//向栈插入数据
{
	//这里我们先栈中插入元素,需要保证栈不是NULL;
	assert(ps);
	ps->a = (STDataType *)malloc(sizeof(STDataType) * 4);//开辟四个整形的空间
		if (ps->a==NULL)
		{
			perror("malloc fail");
		}
		ps->capacity = 4;
		ps->top = 0;//top 是指向栈顶元素的下一个位置
		//ps->top = -1 top 是栈顶元素位置
}
void STDestory(ST* ps)//重置(销毁栈)
{
	assert(ps);
	
	  free(ps->a);
		ps->a = NULL;
		ps->top = 0;
		ps->capacity = 0; 
}

void STPush(ST* ps, STDataType x)//插入数据
{
	assert(ps);

	//我们在头插的时候需要考虑扩容的问题 
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType *)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			//exit(-1);
			return ;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = x;
	ps->top++;

}
void STPop(ST* ps)//删除数据
{
	assert(ps);
	assert(!STEmpty(ps));//不等于空就删,等于空就停止
	//if (ps->top == NULL)
	//{
	//	return 0;
	//}
	//else
	//{
	//	ps->top--;//这里我们就遵从了栈的后进先出
	//}
	ps->top--;//这里我们就遵从了栈的后进先出
	
}
int STsize(ST* ps)//栈中数据个数
{
	assert(ps);
	return ps->top;
}
bool STEmpty(ST* ps) //栈中数据是不是为空
{
	assert(ps);
	return ps->top == 0;

}
STDataType STTop(ST* ps)//返回栈顶数据
{
	assert(ps);
	assert(!(STEmpty(ps)));//为空就不能访问了
	return ps->a[ps->top - 1];
		
}
//text.c
#define _CRT_SECURE_NO_WARNINGS
#include"Stack.h"
 void test1()
{
	 ST st;//创建栈
	 STInit(&st);//初始化栈
	 STPush(&st, 1);
	 STPush(&st, 2);
	 STPush(&st, 3);
	 STPush(&st, 4);
	 STPush(&st, 5); //插入数据
	 //while (ps.top!=0)
	 while (!STEmpty(&st))//不为空的时候我们才来访问
	 {

		 printf("%d ", STTop(&st)); //访问栈区中的元素
		 STPop(&st); //删除头元素
	 }

	 STDestory(&st); //删除栈

}


  void test2()
 {
	  ST st;//创建栈
	  STInit(&st);//初始化栈
	  STPush(&st, 1);
	  printf("%d\n", STTop(&st)); //访问栈区中的元素
	  STPop(&st); //删除头元素

	  STPush(&st, 2);
	  printf("%d\n", STTop(&st)); //访问栈区中的元素
	  STPop(&st); //删除头元素

	  STPush(&st, 3);
	  printf("%d\n", STTop(&st)); //访问栈区中的元素

	  STPush(&st, 4);
	  printf("%d\n", STTop(&st)); //访问栈区中的元素
	  STPop(&st); //删除头元素

	  STPush(&st, 5); //插入数据
	  printf("%d\n", STTop(&st)); //访问栈区中的元素

 }

int main()
{
	test1();// 顺序插入,倒叙删除
	//test2();//插入一个删除一个,或者插入两个删除
	return 0;
}

二、队列

//queue.h
#pragma once
//这里我们来实现队列的
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef char QDatatype;
typedef struct QueueNode //链表
{
	struct QueueNode* next;//说明其本质是指向吸引一个结构体的指针
	QDatatype data;
}QNode;
typedef struct queue
{
	QNode* head;//定义就是为了方便后期的操作
	QNode* tail;//
	int size;//确定队列中的元素
}Queue;


void QueueInit(Queue * pq);//初始化
void QueueDestory(Queue* pq);//重制
void QueuePush(Queue* pq,QDatatype x);//插入
void Queuepop(Queue* pq);//删除
int QueueSize(Queue* pq);//队列中的个数
bool QueueEmpty(Queue* pq);//判断队列是否为空
QDatatype QueueFront(Queue* pq);//头数值
QDatatype QueueBack(Queue* pq);//尾数值


//queue.c
#define _CRT_SECURE_NO_WARNINGS
#include"queue.h"
void QueueInit(Queue* pq)//初始化
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QueueDestory(Queue* pq)//重制
{
	assert(pq);
	QNode* cur = pq->head;//保存一下头指针
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->size = NULL;
	pq->size = 0;
}
void QueuePush(Queue* pq ,QDatatype x)//插入
{
	//插入一个结点我们就需要来malloc
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return ;
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->head == NULL)
	{
		//起始结点为NULL
		assert(pq->tail == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;//尾插
		pq->tail = newnode;//更新尾节点
	}
	pq->size++;
}
void Queuepop(Queue* pq)//删除
{
	assert(pq);
	assert(pq->head != NULL);//判断是后为空,不为空才有删的必要
	if (pq->head->next == NULL)
	{
		//只有一个结点
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;

}
int QueueSize(Queue* pq)//队列中的个数
{
	assert(pq);
	return pq->size;
}
bool QueueEmpty(Queue* pq)//判断队列是否为空
{
	assert(pq);
	return pq->size == 0;
}
QDatatype QueueFront(Queue* pq)//头数值
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}
QDatatype QueueBack(Queue* pq)//尾数值
{
	assert(pq);
	//这里我们就可以很好的利用了我们创建尾结点的作用
	return pq->tail->data;
}

//text.c
#define _CRT_SECURE_NO_WARNINGS
#include"queue.h"

int main()
{
	Queue q;//创建一个点
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	QueuePush(&q, 6);

	printf("%d\n", QueueFront(&q));//拿出头
	printf("%d\n", QueueBack(&q));//拿出尾
	printf("%d\n", QueueSize(&q));//拿出队列中的个数
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));//拿出头
		Queuepop(&q); //删除
	}
	printf("\n");
	printf("%d\n", QueueSize(&q));

	return 0;
}

//以上就是对列的实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值