学习算法和数据结构:栈和队列
2018-02-04 00:37
621 查看
「学习算法和数据结构系列」,栈和队列同属于线性结构
队列:FIFO(先进先出)
栈是限定仅在表尾进行插入和删除的线性表
队列是仅允许在一端插入在另一端删除的线性表
不论栈还是队列都是一种访问受限制的线性表
*补充:给定n个数,求所有可能的出栈顺序种类数;公式如下图所示:
这可以看作是卡特兰数的一个应用,证明戳这里:http://blog.sina.com.cn/s/blog_6917f47301010cno.html(文章不长,不是我写的)
栈的特有操作集:弹栈(Pop),压栈(Push)
队列的特有操作集:进队列,出队列
不论栈还是队列都可以用“数组”或者“链表”来实现(顺序存储+链式存储)
[b]栈的ADT[/b]
[b]栈的数组实现[/b]
栈插入元素(进栈)
栈删除元素(出栈)
[b]栈的链表实现(链栈)[/b]
对于链表来说,不需要实现固定好大小,而且基本上不会出现没有空间的情况(除非计算机操作系统已经濒临死机崩溃)
栈插入元素(进栈)
栈删除元素(出栈)
[b]循环队列的ADT[/b]
[b]循环队列的数组实现[/b]
循环队列初始化
循环队列长度
循环队列入队列
循环队列出队列
[b]队列的链表实现(链队列)[/b]
元素入队
元素出队
栈和队列的特点
栈:LIFO(后进先出)队列:FIFO(先进先出)
栈是限定仅在表尾进行插入和删除的线性表
队列是仅允许在一端插入在另一端删除的线性表
不论栈还是队列都是一种访问受限制的线性表
*补充:给定n个数,求所有可能的出栈顺序种类数;公式如下图所示:
这可以看作是卡特兰数的一个应用,证明戳这里:http://blog.sina.com.cn/s/blog_6917f47301010cno.html(文章不长,不是我写的)
栈和队列的代码实现
不同的数据结构说白了就是一些包含系列操作集的数据集合栈的特有操作集:弹栈(Pop),压栈(Push)
队列的特有操作集:进队列,出队列
不论栈还是队列都可以用“数组”或者“链表”来实现(顺序存储+链式存储)
[b]栈的ADT[/b]
//ADT Data 同线性表;元素具有相同的类型,相邻元素间具有前趋和后继结点 Operation InitStack(*S):初始化操作,建立一个空栈S DestroyStack(*S):若栈存在,则销毁它 ClearStack(S):将栈清空 StackEmpty(S):若栈为空,返回true,否则返回false GetTop(S, *e):若栈存在且非空,则用e返回栈顶元素 Push(*S, e):若栈S存在,插入新元素到栈S中并成为栈顶元素 Pop(*S, *e):删除栈S中的栈顶元素,并用e返回 StackLength(S):返回栈S的元素个数 endADT
[b]栈的数组实现[/b]
typedef struct { int data[MAXSIZE]; /*下标从0开始*/ int top; /*用于栈顶指针*/ }sqStack;
栈插入元素(进栈)
int Push(sqStack *S, int e) { if(S->top == MAXSIZE-1){ /*栈满*/ return -1; } S->top++; /*栈顶指针增加一*/ S->data[S->top] = e; /*将新插入的元素赋值给栈顶空间*/ return 0; }
栈删除元素(出栈)
int Pop(sqStack *S, int *e) { if(S->top == -1){ return -1; } *e = S->data[S->top]; /*将要删除的元素赋值给e*/ S->top--; /*栈顶指针减一*/ return 0; }
[b]栈的链表实现(链栈)[/b]
对于链表来说,不需要实现固定好大小,而且基本上不会出现没有空间的情况(除非计算机操作系统已经濒临死机崩溃)
typedef struct _snode { int data; struct _snode *next; }SNode, *LinkStackPtr; typedef struct { LinkStackptr top; int count; }LinkStack;
栈插入元素(进栈)
int Push(LinkStack *S, int e) { LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode)); s->data = e; s->next = S->top; S->top = s; S->count++; return 0; }
栈删除元素(出栈)
int Pop(LinkStack *S, int e) { LinkStackPtr p; if(StackEmpty(*S)){ return -1; } *e = S->top->data; p = S->top; S->top = S->top->next; free(p); S->count++; return 0; }
[b]循环队列的ADT[/b]
//ADT Data 同线性表;元素具有相同的类型,相邻元素具有前趋和后继关系 Operation InitQueue(*Q):初始化操作,建立一个空队列 DestroyQueue(*Q):若队列Q存在,则销毁它 ClearQueue(*Q):将队列Q清空 QueueEmpty(Q):若队列Q为空,则返true,否则返回false GetHead(Q, *e):若队列Q存在且非空,用e返回队列Q的队头元素 EnQueue(*Q):若队列Q存在,插入新元素e到Q中并成为队尾元素 DeQueue(*Q, *e):删除队列Q中队头元素,并用e返回其值 endADT
[b]循环队列的数组实现[/b]
typedef struct { int data[MAXSIZE]; int front; /*头指针*/ int rear; /*尾指针,若队列不变,指向队列尾元素的下一个位置*/ }sqQueue;
循环队列初始化
int InitQueue(SqQueue *Q) { Q->front = 0; Q->rear = 0; return 0; }
循环队列长度
int QueueLength(sqQueue Q) { return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; }
循环队列入队列
int EnQueue(sqQueue *Q, int e) { if((Q->rear+1) % MAXSIZE == Q->front){ /*判断队列是否已满*/ return -1; } Q->data[Q->rear] = e; /*将e的值赋给队尾元素*/ Q->rear = (Q->rear+1) % MAXSIZE; /*rear指针向后移动一位,若到最后则转到数组的头部*/ return 0; }
循环队列出队列
int DeQueue(sqQueue *Q, int e) { if(Q->front == Q->rear){ /*判断队列是否为空*/ return -1; } *e = Q->data[Q->front]; /*将队头元素赋给e*/ Q->front = (Q->front+1) % MAXSIZE; /*front指针向后移动一位,若到最后则转到数组的头部*/ return 0; }
[b]队列的链表实现(链队列)[/b]
typedef strut _qNode /*结点结构*/ { int data; struct _qNode *next; }QNode, *QueuePtr;
typedef struct /*队列的链表结构(和栈一样的套路,先隔离再整体)*/ { QueuePtr front, rear; /*队头、队尾指针*/ }LinkQueue;
元素入队
int EnQueue(LinkQueue *Q, int e) { QueuePtr s = (QueuePtr)malloc(sizeof(QNode)); if(!s){ /*内存分配失败*/ exit(OVERFLOW); } s->data = e; s->next = NULL; Q->rear->next = s; /*把拥有元素e的新结点s赋给原队尾结点的后继*/ Q->rear = s; /*把当前的s设置为队尾结点,rear指向s*/ return 0; }
元素出队
int DeQueue(LinkQueue *Q, int e) { QueuePtr p; if(Q->front == Q->rear){ return -1; } p = Q->front->next; /*将要删除的队头结点暂存给p*/ *e = p->data; /*将要删除的队头结点赋给e*/ Q->front->next = p->next; /*将原队头结点后继p->next赋给头结点后继*/ if(Q->rear == p){ /*若头结点是队尾,则删除后将rear指向头结点*/ Q->rear == Q->front; } free(p); return 0; }
相关文章推荐
- 【Java数据结构学习笔记之三】Java数据结构与算法之队列(Queue)实现
- C#数据结构和算法学习系列七----队列、队列的实现和应用
- 数据结构和算法学习第3天:队列的相关知识
- 数据结构和算法学习(一)线性表、栈和队列
- 数据结构和算法学习(4)-栈和队列
- 学习研究v_JULY_v整理的微软数据结构和算法面试题
- 神器 VisuAlgo:通过动画学习算法和数据结构
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 算法与数据结构学习 08 归并排序
- 数据结构和算法学习笔记-2
- 神器 VisuAlgo:通过动画学习算法和数据结构
- 数据结构和算法学习和理解 之 插入排序
- 【算法学习】单调队列
- 算法与数据结构基础----表,栈和队列(外加map用法)
- C 算法与数据结构 队列
- 《Delphi 算法与数据结构》学习与感悟[7]: 链表与数组的异同
- 数据结构学习笔记--队列
- 数据结构和算法:队列和栈
- 数据结构学习2---队列和栈
- C#数据结构和算法学习系列五----基础查找算法