栈和队列c实现

13 篇文章 0 订阅
4 篇文章 0 订阅
  1. 什么是栈,栈有什么特性?
    栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作.
    进行数据插入和删除操作的一端称为栈顶,另一端称为栈底.栈中元素遵循后进先出LIFO(Last In First Out)的原则.
  2. 请用C语言实现一个动态栈
    stack.h
#pragma once

typedef int STDataType;

typedef struct Stack
{
	STDataType* arr;
	int size;
	int capacity;
}Stack;
void StackInit(Stack* s, int capacity);
void StackPush(Stack* s,STDataType data);
void StackPop(Stack* s);
STDataType StackTop(Stack* s);
int StackEmpty(Stack* s);
int StackSize(Stack* s);
int StackCapacity(Stack* s);
void StackDestroy(Stack* s);
void CheckCapacity(Stack* s);

stack.c

#include "stack.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>

void StackInit(Stack* s,int capacity) {
	assert(s);
	s->arr = (STDataType*)malloc(sizeof(STDataType)*capacity);
	if (s->arr == NULL)
	{
		assert(0);
		return;
	}
	s->capacity = capacity;
	s->size = 0;
}
void StackPush(Stack* s,STDataType data) {
	assert(s);
	if (s->capacity == s->size)
	{
		CheckCapacity(s);
	}
	s->arr[s->size++] = data;
}
void StackPop(Stack* s) {
	assert(s);
	if (StackEmpty(s))
		return;
	s->size -= 1;
}
STDataType StackTop(Stack* s) {
	assert(s);
	return s->arr[s->size-1];
}
int StackEmpty(Stack* s) {
	assert(s);
	return s->size == 0;
}
int StackSize(Stack* s) {
	assert(s);
	return s->size;
}
int StackCapacity(Stack* s) {
	assert(s);
	return s->capacity;
}
void StackDestroy(Stack* s) {
	if (s->arr) {
		free(s->arr);
	}
	s->capacity = 0;
	s->size = 0;
}
void CheckCapacity(Stack* s) {
	assert(s);
	int newcapacity = 2 * s->capacity;
	STDataType* pTemp = (STDataType*)malloc(sizeof(STDataType)*newcapacity);
	if (pTemp == NULL) {
		assert(0);
		return;
	}
	for (int i = 0; i < s->size; i++) {
		pTemp[i] = s->arr[i];
	}
	free(s->arr);
	s->arr = pTemp;
	s->capacity = newcapacity;
}
int main() {
	
	Stack s;
	StackInit(&s,3);

	StackPush(&s, 1);
	StackPush(&s, 2);
	StackPush(&s, 3);
	printf("%d\n", StackSize(&s));
	printf("%d\n", StackTop(&s));

	StackPush(&s, 4);
	StackPush(&s, 5);
	printf("%d\n", StackSize(&s));
	printf("%d\n", StackTop(&s));

	StackPop(&s);
	printf("%d\n", StackSize(&s));
	printf("%d\n", StackTop(&s));

	StackDestroy(&s);

	return 0;
}

测试结果:
在这里插入图片描述

  1. 为什么将递归程序转化成循环时需要用到栈?
    函数递归和栈的特性非常相似
    递归之所以可以采用非递归方法实现是因为可以用栈的方式
    如果你采用递归时 是由系统管理函数栈
    而要写成非递归时必须由你自已来管理一个栈.
    递归的本质就是栈

  2. 什么是队列,队列有什么特性?栈和队列有什么区别?

    只允许在一端进行插入数据,在另一端进行删除数据操作的特殊线性表.
    队列具有先进先出FIFO(First In First Out).
    入队列:进行插入操作的一端称为队尾.
    出队列:进行删除操作的一端称为队头.
    栈和队列有什么区别
    队列(Queue):是限定只能在表的一端进行插入和另一端删除操作的线性表
    栈(Stack):是限定之能在表的一端进行插入和删除操作的线性表

    队列和栈的规则
    队列:先进先出
    栈:先进后出
    队列和栈的遍历数据速度
    队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快
    栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,遍历数据时需要微数据开辟临时空间,保持数据在遍历前的一致性

  3. 请用C语言实现一个队列
    Queue.h

#pragma once

typedef int QUDataType;

typedef struct QueueNode
{
	struct QueueNode* _next;
	QUDataType _data;
}QueueNode;
typedef struct Queue
{
	QueueNode* _front;
	QueueNode* _back;
}Queue;

void QueueInit(Queue* pq);
void QueueDstory(Queue* pq);

QueueNode* BuyQueueNode(QUDataType x);
void QueuePush(Queue* pq,QUDataType x);
void QueuePop(Queue* pq);

QUDataType QueueFront(Queue* pq);
QUDataType QueueBack(Queue* pq);
int QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

Queue.c

#include "Queue.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>

void QueueInit(Queue* pq) {
	assert(pq);
	pq->_front = pq->_back = NULL;
}
void QueueDstory(Queue* pq) {
	assert(pq);
	QueueNode* pDelNode = pq->_front;

	if (QueueSize(pq)) {
		QueuePop(pq);
	}
	free(pq->_front);
	free(pq->_back);
	pq->_front = pq->_back = NULL;
}

QueueNode* BuyQueueNode(QUDataType x) {
	QueueNode* PNewNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == PNewNode) {
		assert(0);
		return;
	}
	PNewNode->_data = x;
	PNewNode->_next = NULL;
	return PNewNode;
}
void QueuePush(Queue* pq, QUDataType x) {
	assert(pq);
	QueueNode* pNewNode = BuyQueueNode(x);
	if (QueueEmpty(pq)) {
		pq->_front = pq->_back = pNewNode;
	}
	else {
		pq->_back->_next = pNewNode;
		pq->_back = pNewNode;
	}
}
void QueuePop(Queue* pq) {
	assert(pq);
	if (QueueEmpty(&pq))
		return;
	QueueNode* pDelNode = pq->_front;
	if (pq->_front == pq->_back) {
		pq->_front = pq->_back = NULL;
	}
	else
	{
		pq->_front = pq->_front->_next;
	}
	free(pDelNode);
}

QUDataType QueueFront(Queue* pq) {
	assert(pq);
	return pq->_front->_data;
}
QUDataType QueueBack(Queue* pq) {
	assert(pq);
	return pq->_back->_data;
}
int QueueEmpty(Queue* pq) {
	return NULL == pq->_front;
}
int QueueSize(Queue* pq) {
	assert(pq);
	QueueNode* pCur = pq->_front;
	int size = 0;
	while (pCur) {
		size++;
		pCur = pCur->_next;
	}
	return size;
}
int main() {

	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);

	printf("front = %d\n", QueueFront(&q));
	printf("back = %d\n", QueueBack(&q));
	printf("size = %d\n", QueueSize(&q));

	QueuePop(&q);
	printf("front = %d\n", QueueFront(&q));
	printf("back = %d\n", QueueBack(&q));
	printf("size = %d\n", QueueSize(&q));

	QueueDstory(&q);
	return 0;
}

测试结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值