1.官方定义:
栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。
栈的元素必须“后进先出”。
栈的操作只能在这个线性表的表尾进行。
注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。
2.栈的顺序存储结构
typedef struct{ElemType *base;ElemType *top;int stackSize;}sqStack;//比较普通的另一种声明方式typedef int ElemType;typedef struct{ElemType data[MAXSIZE];int top; // 用于标注栈顶的位置int stackSize;}
3.创建一个栈
#define STACK_INIT_SIZE 100initStack(sqStack *s){s->base = (ElemType *)malloc( STACK_INIT_SIZE * sizeof(ElemType) );if( !s->base )exit(0);s->top = s->base; // 最开始,栈顶就是栈底s->stackSize = STACK_INIT_SIZE;}
4.入栈操作
#define SATCKINCREMENT 10Push(sqStack *s, ElemType e){// 如果栈满,追加空间if( s->top – s->base >= s->stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if( !s->base )exit(0);s->top = s->base + s->stackSize; // 设置栈顶s->stackSize = s->stackSize + STACKINCREMENT; // 设置栈的最大容量}*(s->top) = e;s->top++;}
5.出栈操作
Pop(sqStack *s, ElemType *e){if( s->top == s->base ) // 栈已空空是也return;*e = *--(s->top);}
6.清空一个栈
ClearStack(sqStack *s){s->top = s->base;}
7.销毁一个栈
DestroyStack(sqStack *s){int i, len;len = s->stackSize;for( i=0; i < len; i++ ){free( s->base );s->base++;}s->base = s->top = NULL;s->stackSize = 0;}
8.计算栈的当前容量
int StackLen(sqStack s){return(s.top – s.base); // 初学者需要重点讲解}
9.队列的定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表。
与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础。
10.队列的链式存储结构
typedef struct QNode {ElemType data;struct QNode *next;} QNode, *QueuePrt;typedef struct {QueuePrt front, rear; // 队头、尾指针} LinkQueue;

注:
头结点不是必要的,但为了方便操作,我们加上了。
空队列时,front和rear都指向头结点。
11.创建一个队列
initQueue(LinkQueue *q){q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));if( !q->front )exit(0);q->front->next = NULL;}
12.入队列操作
InsertQueue(LinkQueue *q, ElemType e){QueuePtr p;p = (QueuePtr)malloc(sizeof(QNode));if( p == NULL )exit(0);p->data = e;p->next = NULL;q->rear->next = p;q->rear = p;}
13.出队列操作
DeleteQueue(LinkQueue *q, ELemType *e){QueuePtr p;if( q->front == q->rear )return;p = q->front->next;*e = p->data;q->front->next = p->next;if( q->rear == p )q->rear = q->front;free(p);}
14.销毁一个队列
DestroyQueue(LinkQueue *q){while( q->front ) {q->rear = q->front->next;free( q->front );q->front = q->rear;}}
例题:编写一个链队列,任意输入一串字符,以#作为结束标志,然后将队列中的元素显示到屏幕上。
queue.c
15.循环队列定义
16.定义一个循环队列
#define MAXSIZE 100typedef struct{ElemType *base; // 用于存放内存分配基地址// 这里你也可以用数组存放int front;int rear;}
17.初始化一个循环队列
initQueue(cycleQueue *q){q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));if( !q->base )exit(0);q->front = q->rear = 0;}
18.入队列操作
InsertQueue(cycleQueue *q, ElemType e){if( (q->rear+1)%MAXSIZE == q->front )return; // 队列已满q->base[q->rear] = e;q->rear = (q->rear+1) % MAXSIZE;}
19.出队列操作
DeleteQueue(cycleQueue *q, ElemType *e){if( q->front == q->rear )return ; // 队列为空*e = q->base[q->front];q->front = (q->front+1) % MAXSIZE;}

