数据结构(四)
2016-02-21 21:51
260 查看
--接着栈。
栈的算法:出栈
压栈
不管怎么操作,栈都遵循先进后出,出栈是后进来的先出,压栈是先进来的放最底下。
下面是栈的一些算法实现代码:
![](http://img.blog.csdn.net/20160221215022266?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
栈的实际应用:函数调用
中断
表达式求值
内存分配
缓冲处理
迷宫
...
队列:与栈不同,队列是”先进先出“类型的存储结构,而且是从不同口进出。类似火车站,从一个入口进去,从另外一个出口出来。
类型:链式队列
静态队列:通常是循环队列
队列的算法:出队
入队
循环队列的讲解:1.静态队列为什么必须是循环队列
由于队列是“先进先出”,当增加一个元素时,是在rear前添加,删除 一个元素时,是删除front后面的元素。如果队列不循环,在添加和删除时,front和rear的index值都是往上增加的,会造成内存泄漏,所以静态队列必须采用循环队列。比如,一个队列现有6个元素,front是1,rear是6,(第6个是无效的,只是方便操作),增加一个元素7,那么rear就变成7了,删除1,front就变成2,原先front和rear是1和6,现在是2和7,而内存中1和6并没有被释放。
2.循环队列需要几个参数来确定
front
rear
3. 循环队列各个参数的含义
2个参数在不同场合有不同意义:
1.)队列初始化
front 和 rear 的值都是零
2.)队列非空
front代表队列第一个元素
Rear代表队列最后一个有效元素的下一个元素
3.)队列空
front和rear的值相等,但不一定是零(下面简称f和r)
4.循环队列入队伪算法
(1).将值存入r所代表的位置
(2).将r在数组的位置改为 r=(r+1)%(数组的长度),不能是r=r+1
5.循环队列出队伪算法
(1).将值存入f所代表的位置
(2).将r在数组的位置改为 f=(f+1)%(数组的长度),不能是f=f+1
6.判断循环队列是否为空
如果r和f的值相等,则该队列就一定为空
7.判断循环队列是否已满
f和r的关系是不确定的,在入队和出队过程中,f可能比r大,f可能等 于r,f可能小于r。
于是有两种方式可以实现:
(1)多增加一个标识参数
(2)定义的数组少用一个元素(通常用第二这种方法)
如果r和f的值紧挨着,则队列已满
If((r+1)%数组的长度==f)
{ 已满; }
Else
{ 未满; }
栈的算法:出栈
压栈
不管怎么操作,栈都遵循先进后出,出栈是后进来的先出,压栈是先进来的放最底下。
下面是栈的一些算法实现代码:
# include <stdio.h> # include <malloc.h> # include <stdlib.h> typedef struct Node { int data; struct Node * pNext; }NODE,* PNODE; typedef struct Stack { PNODE pTop; PNODE pBottom; }STACK,* PSTACK; //函数声明 void init(PSTACK pS);//初始化 void push(PSTACK pS,int val);//压栈 void traverse(PSTACK pS);//遍历 bool pop(PSTACK pS,int * pVal);//出栈 bool clear(PSTACK pS);//清空 int main(void) { int val; STACK S; printf("*******压栈******"); init(&S); push(&S,1); push(&S,2); push(&S,3); push(&S,4); push(&S,5); push(&S,6); traverse(&S); printf("*******出栈******"); pop(&S,&val); traverse(&S); printf("*******清空******"); clear(&S); traverse(&S); return 0; } void init(PSTACK pS) { pS->pTop=(PNODE)malloc(sizeof(NODE)); if(NULL == pS->pTop) { printf("动态内存分配失败!\n"); } else { pS->pBottom = pS->pTop; } } void push(PSTACK pS,int val) { PNODE pNew = (PNODE)malloc(sizeof(NODE)); pNew->data=val; pNew->pNext=pS->pTop; pS->pTop=pNew; return; } void traverse(PSTACK pS) { PNODE p=pS->pTop; printf("\n******遍历*******\n"); while(p!=pS->pBottom) { printf("%d ",p->data); p=p->pNext; } printf("\n"); return; } bool empty(PSTACK pS) { if(pS->pTop == pS->pBottom) { return true; } else { return false; } } bool pop(PSTACK pS,int * pVal) { if(empty(pS)) { return false; } else { PNODE r=pS->pTop; *pVal=r->data; pS->pTop=r->pNext; free(r); r=NULL; return true; } } bool clear(PSTACK pS) { if(empty(pS)) { return false; } else { PNODE p=pS->pTop; PNODE q=NULL; while(p!=pS->pBottom) { q=p->pNext; free(p); p=q; } pS->pTop=pS->pBottom; return true; } }
栈的实际应用:函数调用
中断
表达式求值
内存分配
缓冲处理
迷宫
...
队列:与栈不同,队列是”先进先出“类型的存储结构,而且是从不同口进出。类似火车站,从一个入口进去,从另外一个出口出来。
类型:链式队列
静态队列:通常是循环队列
队列的算法:出队
入队
循环队列的讲解:1.静态队列为什么必须是循环队列
由于队列是“先进先出”,当增加一个元素时,是在rear前添加,删除 一个元素时,是删除front后面的元素。如果队列不循环,在添加和删除时,front和rear的index值都是往上增加的,会造成内存泄漏,所以静态队列必须采用循环队列。比如,一个队列现有6个元素,front是1,rear是6,(第6个是无效的,只是方便操作),增加一个元素7,那么rear就变成7了,删除1,front就变成2,原先front和rear是1和6,现在是2和7,而内存中1和6并没有被释放。
2.循环队列需要几个参数来确定
front
rear
3. 循环队列各个参数的含义
2个参数在不同场合有不同意义:
1.)队列初始化
front 和 rear 的值都是零
2.)队列非空
front代表队列第一个元素
Rear代表队列最后一个有效元素的下一个元素
3.)队列空
front和rear的值相等,但不一定是零(下面简称f和r)
4.循环队列入队伪算法
(1).将值存入r所代表的位置
(2).将r在数组的位置改为 r=(r+1)%(数组的长度),不能是r=r+1
5.循环队列出队伪算法
(1).将值存入f所代表的位置
(2).将r在数组的位置改为 f=(f+1)%(数组的长度),不能是f=f+1
6.判断循环队列是否为空
如果r和f的值相等,则该队列就一定为空
7.判断循环队列是否已满
f和r的关系是不确定的,在入队和出队过程中,f可能比r大,f可能等 于r,f可能小于r。
于是有两种方式可以实现:
(1)多增加一个标识参数
(2)定义的数组少用一个元素(通常用第二这种方法)
如果r和f的值紧挨着,则队列已满
If((r+1)%数组的长度==f)
{ 已满; }
Else
{ 未满; }
相关文章推荐
- 数据结构(三)
- 数据结构(二)
- 数据结构(一)
- hdu 3577(线段树区间更新)
- 数据结构: 数组与字符串问题
- 跟我学数据结构之树
- 跟我学数据结构之数组和广义表
- 《数据结构与算法分析(c描述)》——二叉搜索树实现
- 树和递归(一)[leetcode]Balanced Binary Tree
- opencv基本数据结构
- 数据结构(9)--链队列的定义以及相关操作的实现
- 数据结构(8)--栈的应用之行编辑程序、括号匹配检验、数制转换、hanio塔问题
- 最小生成树-普里姆方法(Prim)
- 大学时数据结构课上写的排序算法
- 数据结构基础之图的遍历
- 《数据结构与算法分析(c 描述)》—— 第四章笔记
- 数据结构基础之图的存储结构
- 数据结构(7)—栈的应用之迷宫求解
- 《数据结构》进行曲(之一)---线性表的顺序表示
- 数据结构之回溯算法