1.官方定义:

栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。
栈的元素必须“后进先出”。
栈的操作只能在这个线性表的表尾进行。
注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。

2.栈的顺序存储结构

  1. typedef struct
  2. {
  3. ElemType *base;
  4. ElemType *top;
  5. int stackSize;
  6. }sqStack;
  7. //比较普通的另一种声明方式
  8. typedef int ElemType;
  9. typedef struct
  10. {
  11. ElemType data[MAXSIZE];
  12. int top; // 用于标注栈顶的位置
  13. int stackSize;
  14. }

3.创建一个栈

  1. #define STACK_INIT_SIZE 100
  2. initStack(sqStack *s)
  3. {
  4. s->base = (ElemType *)malloc( STACK_INIT_SIZE * sizeof(ElemType) );
  5. if( !s->base )
  6. exit(0);
  7. s->top = s->base; // 最开始,栈顶就是栈底
  8. s->stackSize = STACK_INIT_SIZE;
  9. }

4.入栈操作

  1. #define SATCKINCREMENT 10
  2. Push(sqStack *s, ElemType e)
  3. {
  4. // 如果栈满,追加空间
  5. if( s->top s->base >= s->stackSize )
  6. {
  7. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  8. if( !s->base )
  9. exit(0);
  10. s->top = s->base + s->stackSize; // 设置栈顶
  11. s->stackSize = s->stackSize + STACKINCREMENT; // 设置栈的最大容量
  12. }
  13. *(s->top) = e;
  14. s->top++;
  15. }

5.出栈操作

  1. Pop(sqStack *s, ElemType *e)
  2. {
  3. if( s->top == s->base ) // 栈已空空是也
  4. return;
  5. *e = *--(s->top);
  6. }

6.清空一个栈

  1. ClearStack(sqStack *s){
  2. s->top = s->base;
  3. }

7.销毁一个栈

  1. DestroyStack(sqStack *s){
  2. int i, len;
  3. len = s->stackSize;
  4. for( i=0; i < len; i++ ){
  5. free( s->base );
  6. s->base++;
  7. }
  8. s->base = s->top = NULL;
  9. s->stackSize = 0;
  10. }

8.计算栈的当前容量

  1. int StackLen(sqStack s)
  2. {
  3. return(s.top s.base); // 初学者需要重点讲解
  4. }

9.队列的定义

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表。
与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础。

10.队列的链式存储结构

  1. typedef struct QNode {
  2. ElemType data;
  3. struct QNode *next;
  4. } QNode, *QueuePrt;
  5. typedef struct {
  6. QueuePrt front, rear; // 队头、尾指针
  7. } LinkQueue;

四、栈和队列 - 图1
注:
头结点不是必要的,但为了方便操作,我们加上了。
空队列时,front和rear都指向头结点。

11.创建一个队列

  1. initQueue(LinkQueue *q)
  2. {
  3. q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
  4. if( !q->front )
  5. exit(0);
  6. q->front->next = NULL;
  7. }

12.入队列操作

  1. InsertQueue(LinkQueue *q, ElemType e)
  2. {
  3. QueuePtr p;
  4. p = (QueuePtr)malloc(sizeof(QNode));
  5. if( p == NULL )
  6. exit(0);
  7. p->data = e;
  8. p->next = NULL;
  9. q->rear->next = p;
  10. q->rear = p;
  11. }

13.出队列操作

  1. DeleteQueue(LinkQueue *q, ELemType *e)
  2. {
  3. QueuePtr p;
  4. if( q->front == q->rear )
  5. return;
  6. p = q->front->next;
  7. *e = p->data;
  8. q->front->next = p->next;
  9. if( q->rear == p )
  10. q->rear = q->front;
  11. free(p);
  12. }

14.销毁一个队列

  1. DestroyQueue(LinkQueue *q)
  2. {
  3. while( q->front ) {
  4. q->rear = q->front->next;
  5. free( q->front );
  6. q->front = q->rear;
  7. }
  8. }

例题:编写一个链队列,任意输入一串字符,以#作为结束标志,然后将队列中的元素显示到屏幕上。
queue.c

15.循环队列定义

循环队列操作演示.swf (26.37KB)

16.定义一个循环队列

  1. #define MAXSIZE 100
  2. typedef struct
  3. {
  4. ElemType *base; // 用于存放内存分配基地址
  5. // 这里你也可以用数组存放
  6. int front;
  7. int rear;
  8. }

17.初始化一个循环队列

  1. initQueue(cycleQueue *q)
  2. {
  3. q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
  4. if( !q->base )
  5. exit(0);
  6. q->front = q->rear = 0;
  7. }

18.入队列操作

  1. InsertQueue(cycleQueue *q, ElemType e)
  2. {
  3. if( (q->rear+1)%MAXSIZE == q->front )
  4. return; // 队列已满
  5. q->base[q->rear] = e;
  6. q->rear = (q->rear+1) % MAXSIZE;
  7. }

19.出队列操作

  1. DeleteQueue(cycleQueue *q, ElemType *e)
  2. {
  3. if( q->front == q->rear )
  4. return ; // 队列为空
  5. *e = q->base[q->front];
  6. q->front = (q->front+1) % MAXSIZE;
  7. }

20.进制转换

Bin2Oct.c
Bin2Hex.c
Bin2Dec.c