队列与栈的实现

栈的概念: 一种特殊的线性表,其只允许在固定的一端进行插入删除元素操作。

栈顶: 进行数据插入和删除操作的一端
栈底: 与栈顶相对的另一端

栈的基本操作需要遵守的原则
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

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

图示

操作

功能实现

在这里插入图片描述

实现栈(基于支持动态扩展的顺序表)

//Sysutil.h
ifndef __SYSUTIL_H___
#define __SYSUTIL_H___

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#pragma warning(disable:4996)


#endif
//Stack.h
#ifndef __STACK_H__
#define __STACK_H__

#include "Sysutil.h"
#define ElemType int
///动态增长的顺序栈
#define DEFAULT_SIZE 8
typedef struct SeqStack 
{
	ElemType* base;
	int capacity;
	int top;
}SeqStack;

void SeqStackInit(SeqStack* ps,int size);
void SeqStackPush(SeqStack* ps,ElemType x);
void SeqStackPop(SeqStack* ps);
ElemType SeqStackTop(SeqStack* ps);
int SeqStackSize(SeqStack* ps);
int SeqStackEmpty(SeqStack* ps);
void SeqStackDestroy(SeqStack* ps);
void SeqStackShow(SeqStack* ps);
static int IsFull(SeqStack* ps);
static void SeqStackInc(SeqStack* ps);

static int IsFull(SeqStack* ps) 
{
	return ps->top >= ps->capacity;
}
int SeqStackEmpty(SeqStack* ps)
{
	return 0 == ps->top;
}
static void SeqStackInc(SeqStack** pps)
{
	ElemType* q = (ElemType*)realloc((*pps)->base,sizeof(ElemType)* ((*pps)->capacity) * 2);
	if (q)
		(*pps)->base = q;
	else
		printf("扩容失败!\n");
}
void SeqStackInit(SeqStack* sp,int size)
{
	size = size > DEFAULT_SIZE ? size : DEFAULT_SIZE;
	if (sp && size > 0) {
		sp->base = (ElemType*)malloc(sizeof(ElemType) * size);
		sp->capacity = size;
		sp->top = 0;
	}
	else
		printf("栈不存在!\n");
}
void SeqStackPush(SeqStack* ps,ElemType x)
{
	if (ps) {
		if (IsFull(ps))
			SeqStackInc(&ps);
		ps->base[ps->top++] = x;
	}		
	else
		printf("栈不存在!\n");
}
void SeqStackShow(SeqStack* ps)
{
	if (ps) {
		if (SeqStackEmpty(ps))
			printf("空栈!\n");
		else {
			printf("栈底:");
			for (int i = 0; i < ps->top; i++)
				printf("%d-->", ps->base[i]);
			printf("栈顶\n");
		}	
	}
	else
		printf("栈不存在!\n");
}
void SeqStackDestroy(SeqStack* ps)
{
	free(ps->base);
	ps->capacity = ps->top = 0;
}
void SeqStackPop(SeqStack* ps)
{
	if (!SeqStackEmpty(ps))
		ps->top--;
}
int SeqStackSize(SeqStack* ps)
{
	if (!SeqStackEmpty(ps))
		return ps->top;
	else
		return 0;
}
ElemType SeqStackTop(SeqStack* ps)
{
	assert(ps && !SeqStackEmpty(ps));
	return ps->base[ps->top - 1];
}
void SeqStackMenu()
{	
	printf("##############动态顺序表栈#############\n");
	printf("##########[1]入栈     [2]出栈##########\n");
	printf("##########[3]验空     [4]计数##########\n");
	printf("##########[5]栈顶     [6]展示##########\n");
	printf("##########[7]摧毁     [0]退出##########\n");
	printf("#######################################\n");
}
#endif
//StackMain.c
#include "Stack.c"
int main()
{
	SeqStack stack;
	SeqStackInit(&stack,DEFAULT_SIZE);
	ElemType item;
	int choice = 0;
	int quit = 1;
	while (quit) {
		SeqStackMenu();
		printf("请输入想要执行的操作#");
		scanf("%d", &choice);
		switch (choice) {
		case 1:
			printf("请输入将入栈元素(-1结束)#");
			while (scanf("%d", &item), item != -1) {
				SeqStackPush(&stack, item);
			}
			SeqStackShow(&stack);
			break;
		case 2:
			SeqStackPop(&stack);
			SeqStackShow(&stack);
			break;
		case 3:
			if (!SeqStackEmpty(&stack))
				printf("非空栈!\n");
			else
				printf("空栈!\n");
			break;
		case 4:
			printf("栈目前共有[%d]个元素!\n",SeqStackSize(&stack));
			break;
		case 5:
			item = SeqStackTop(&stack);
			if(-1!= item)
				printf("栈顶元素为[%d]\n", SeqStackTop(&stack));
			else
				printf("空栈!\n");
			break;
		case 6:
			SeqStackShow(&stack);
			break;
		case 7:
			SeqStackDestroy(&stack); break;
		case 0:
			printf("再见!\n"); quit = 0; break;
		}
		system("pause");
		system("cls");
	}


	return 0;
}

队列

队列: 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表

队头: 进行删除操作的一端
队尾: 进行插入操作的一端

队列的基本操作需要遵守的原则:
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则,即元素进入队列需要从队尾进入,元素出队列需要从队头出去。

出队: 栈的插入操作叫做入队,入队在队尾。
入队: 队的删除操作叫做出栈,出队在队头。

图示

在这里插入图片描述

基本功能

1

实现队(基于无头单向链表实现)

//Queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__

#include "Sysutil.h"
//#define QDataType int 
struct BTNode;
#define QDataType struct BTNode*

单向链表队列///
typedef struct QListNode
{
	struct QListNode* _next;
	QDataType _data;
}QNode;

typedef struct Queue
{
	QNode* _front;
	QNode* _rear;
}Queue;

void QueueInit(Queue* q);
void QueuePush(Queue* q, QDataType data);
void QueuePop(Queue* q);
QDataType QueueFront(Queue* q);
QDataType QueueBack(Queue* q); 
int QueueSize(Queue* q);
int QueueEmpty(Queue* q);
void QueueDestroy(Queue* q);
void QueueMenu();
static QNode* BuyNode(QDataType x);
void QueueShow();

static QNode* BuyNode(QDataType x)
{
	QNode* p = (QNode*)malloc(sizeof(QNode));
	p->_data = x;
	p->_next = NULL;
	return p;
}
void QueueInit(Queue* q)
{
	if (q) {
		q->_front = NULL;
		q->_rear = NULL;
	}
	else
		printf("队列不存在!\n");
}
void QueuePush(Queue* q, QDataType data)
{
	if (!q) {
		printf("队列不存在!\n");
		return;
	}
	else {
		QNode* s = BuyNode(data);
		if (QueueEmpty(q))
			q->_front = q->_rear = s;
		else {
			q->_rear->_next = s;
			q->_rear = s;
		}
	}
}
void QueuePop(Queue* q)
{
	if (q) {
		if (q->_front)
		{
			QNode* p = q->_front;
			q->_front = q->_front->_next;
			free(p);
			p = NULL;
		}
		else
			printf("空队列!\n");
	}
	else 
		printf("队列不存在!\n");
}
QDataType QueueFront(Queue* q)
{
	assert(q&&q->_front);
		return q->_front->_data;
}
QDataType QueueBack(Queue* q)
{
	assert(q&&q->_rear);
	return q->_rear->_data;
}
int QueueSize(Queue* q)
{
	int size = 0;
	if (q) {
		QNode* p = q->_front;
		while (p) {
			size++;
			p = p->_next;
		}
	}
	else {
		printf("队列不存在!\n");
	}
	return size;
}
int QueueEmpty(Queue* q)
{
	if (q)
		return !q->_front;
	else {
		printf("队列不存在!\n");
		return 1;
	}
}
void QueueDestroy(Queue* q)
{
	if (q) {
		QNode* p = q->_front;
		QNode* pre = p;
		while (pre) {
			p = p->_next;
			free(pre);
			pre = p;
		}
		q->_front = q->_rear = NULL;
	}
}
void QueueShow(Queue* q)
{
	if (q->_front == q->_rear && !q->_front) 
		printf("空队列!\n");
	else {
		QNode* p = q->_front;
		printf("队头:");
		while (p) {
			printf("%d<--", p->_data);
			p = p->_next;
		}
		printf("队尾\n");
	}
}
void QueueMenu()
{
	printf("##############单向链表队列#############\n");
	printf("##########[1]入队     [2]出队##########\n");
	printf("##########[3]验空     [4]计数##########\n");
	printf("##########[5]队头     [6]队尾##########\n");
	printf("##########[7]摧毁     [8]展示##########\n");
	printf("##########      [0]退出      ##########\n");
	printf("#######################################\n");
}

#endif
//QueueMain.c
#include "Queue.h"

int main()
{
	Queue Q;
	QueueInit(&Q);
	QDataType item;
	int choice = 0;
	int quit = 1;
	while (quit) {
		QueueMenu();
		printf("请输入想要执行的操作#");
		scanf("%d", &choice);
		switch (choice) {
		case 1:
			printf("请输入将入队列元素(-1结束)#");
			while (scanf("%d", &item), item != -1) {
				QueuePush(&Q, item);
			}
			QueueShow(&Q);
			break;
		case 2:
			QueuePop(&Q);
			QueueShow(&Q);
			break;
		case 3:
			if (!QueueEmpty(&Q))
				printf("非空队列!\n");
			else
				printf("空队列!\n");
			break;
		case 4:
			printf("队列目前共有[%d]个元素!\n", QueueSize(&Q));
			break;
		case 5:
			printf("队头元素为[%d]\n", QueueFront(&Q));
			break;
		case 6:
			printf("队尾元素为[%d]\n", QueueBack(&Q));
			break;
		case 7:
			QueueDestroy(&Q); break;
		case 8:QueueShow(&Q); break;
		case 0:
			printf("再见!\n"); quit = 0; break;
		}
		system("pause");
		system("cls");
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值