栈与队列的区别:
栈——先入后出,后入先出;
队列——先入先出,后入后出;
应用举例:
栈:函数调用时会将临时数据压栈;函数返回时再弹出来。
队列:一般,系统中的任务和消息经常使用队列。可以按任务或消息到来的先后顺序执行。
代码实现:
背景:使用C语言,在VS2008环境下,按栈与队列的原理,采用最简单易懂的方式,针对正整型(int)元素实现栈与队列。
原理:栈的存储空间使用数组构造,队列的空间又使用栈来构造,即,使用两个栈实现队列的功能。
文件:libStack.h/c;libQueue.h/c;
一、栈的源代码
libStack.h
#ifndef _LIBSTACK_H
#define _LIBSTACK_H
#ifdef __cplusplus
extern "C" {
#endif
#define STACK_MAX_LEN 2048
typedef struct tagstStack
{
int udwPc; /* 栈顶所在位置,指向空闲位置 */
int a[STACK_MAX_LEN];
}stStack;
/* 创建新的栈 */
extern stStack *stack_new();
/* 栈复位 */
extern void stack_reset(stStack *pstStack);
/* 入栈,栈满时忽略此次操作 */
extern void stack_push(stStack *pstStack,int udwTmp);
/* 出栈,栈空时返回-1 */
extern int stack_pop(stStack *pstStack);
/* 栈判空 1-空 0-非空 */
extern int stack_is_empty(stStack *pstStack);
/* 删除栈 */
extern void stack_delete(stStack *pstStack);
#ifdef __cplusplus
}
#endif
#endif
由于是C语言实现,所以必须添加extern "C"{};
libStack.c
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
#include <stddef.h>
#include "libStack.h"
/* 创建新的栈 */
stStack *stack_new()
{
stStack *p;
p = (stStack *)malloc(sizeof(stStack));
p->udwPc = 0;
return p;
}
/* 栈复位 */
void stack_reset(stStack *pstStack)
{
if (NULL == pstStack)
{
return;
}
pstStack->udwPc = 0;
}
/* 入栈,栈满时忽略此次操作 */
void stack_push(stStack *pstStack, int udwTmp)
{
if (NULL == pstStack)
{
return;
}
if (STACK_MAX_LEN > pstStack->udwPc)
{
pstStack->a[pstStack->udwPc] = udwTmp;
pstStack->udwPc++;
}
}
/* 出栈,栈空时返回-1 */
int stack_pop(stStack *pstStack)
{
if (NULL == pstStack)
{
return -1;
}
if (0 == pstStack->udwPc)
{
return -1;
}
return pstStack->a[--pstStack->udwPc];
}
/* 栈判空 1-空 0-非空 */
int stack_is_empty(stStack *pstStack)
{
if (NULL == pstStack)
{
/* 空指针默认为空栈 */
return 1;
}
return (0 < pstStack->udwPc)?0:1;
}
/* 删除栈 */
void stack_delete(stStack *pstStack)
{
if (NULL != pstStack)
{
free(pstStack);
}
}
#ifdef __cplusplus
}
#endif
本套实现只支持正整型数,负数被作为异常值处理。
二、队列的实现
这里队列完全是用上述栈实现的,目的只是练习。
libQueue.h
#ifndef _LIBQUEUE_H
#define _LIBQUEUE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "libStack.h"
#define QUEUE_MAX_LEN STACK_MAX_LEN /* 队列大小取决与栈的大小 */
typedef struct tagstQueue
{
int udwCnt;
stStack *pstStack1;
stStack *pstStack2;
}stQueue;
/* 创建新队列 */
extern stQueue *queue_new();
/* 入队,队列已满时忽略此次操作 */
extern void in_queue(stQueue *pstQueue, int udwTmp);
/* 出队,队列为空时返回-1 */
extern int out_queue(stQueue *pstQueue);
/* 删除队列 */
extern void queue_delete(stQueue *pstQueue);
/* 队列判空 1-空 0-非空 */
extern int queue_is_empty(stQueue *pstQueue);
#ifdef __cplusplus
}
#endif
#endif
libQueue.c
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
#include <stddef.h>
#include "libQueue.h"
/* 创建新队列 */
stQueue *queue_new()
{
stQueue *p;
p = (stQueue *)malloc(sizeof(stQueue));
if (NULL == p)
{
return NULL;
}
p->pstStack1 = stack_new();
if (NULL == p->pstStack1)
{
free(p);
return NULL;
}
p->pstStack2 = stack_new();
if (NULL == p->pstStack2)
{
free(p);
free(p->pstStack1);
return NULL;
}
p->udwCnt = 0;
return p;
}
/* 入队,队列已满时忽略此次操作 */
void in_queue(stQueue *pstQueue, int udwTmp)
{
if (NULL == pstQueue)
{
return;
}
if (QUEUE_MAX_LEN <= pstQueue->udwCnt)
{
return;
}
stack_push(pstQueue->pstStack1, udwTmp);
pstQueue->udwCnt++;
}
/* 出队,队列为空时返回-1 */
int out_queue(stQueue *pstQueue)
{
int ret = -1;
int tmp = 0;
if (NULL == pstQueue)
{
return -1;
}
/* 队列为空 */
if (stack_is_empty(pstQueue->pstStack1))
{
return -1;
}
/* 将栈1内容弹出并压入栈2 */
while(0 != pstQueue->pstStack1->udwPc)
{
tmp = stack_pop(pstQueue->pstStack1);
stack_push(pstQueue->pstStack2, tmp);
}
/* 取栈2顶元素出队 */
ret = stack_pop(pstQueue->pstStack2);
/* 将栈2内容压回栈1 */
while(0 != pstQueue->pstStack2->udwPc)
{
tmp = stack_pop(pstQueue->pstStack2);
stack_push(pstQueue->pstStack1, tmp);
}
pstQueue->udwCnt--;
return ret;
}
/* 删除队列 */
void queue_delete(stQueue *pstQueue)
{
if (NULL == pstQueue)
{
return;
}
if (NULL != pstQueue->pstStack2)
{
free(pstQueue->pstStack2);
}
if (NULL != pstQueue->pstStack1)
{
free(pstQueue->pstStack1);
}
free(pstQueue);
}
/* 队列判空 1-空 0-非空 */
int queue_is_empty(stQueue *pstQueue)
{
return (0 < pstQueue->udwCnt)?0:1;
}
#ifdef __cplusplus
}
#endif
这里我只写了队列的测试:
// ListStackQueue.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "libStack.h"
#include "libQueue.h"
int _tmain(int argc, _TCHAR* argv[])
{
int i,tmp;
stQueue *pstQ1 = queue_new();
stQueue *pstQ2 = queue_new();
for (i = 0; i < 20; i++)
{
in_queue(pstQ1,i);
}
for (i = 0; i < 20; i++)
{
tmp = out_queue(pstQ1);
printf("%d ",tmp);
}
printf("OK");
getchar();
return 0;
}
输出为:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 OK;实现了队列的先入先出功能。
如果试着将栈的大小调整为5,输出为:0 1 2 3 4 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 OK。满足超出空间上限不压栈不入队,出栈出队时若栈队为空则返回-1。