栈与队列的区别:
栈——先入后出,后入先出;
队列——先入先出,后入后出;
应用举例:
栈:函数调用时会将临时数据压栈;函数返回时再弹出来。
队列:一般,系统中的任务和消息经常使用队列。可以按任务或消息到来的先后顺序执行。
代码实现:
背景:使用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
#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; }
如果试着将栈的大小调整为5,输出为:0 1 2 3 4 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 OK。满足超出空间上限不压栈不入队,出栈出队时若栈队为空则返回-1。