`
lovnet
  • 浏览: 6722490 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

java算法:堆栈ADT及实例

 
阅读更多

java算法:堆栈ADT及实例

在支持插入和删除数据项集的数据类型中,最重要的数据类型是堆栈。

堆栈:是由两个基本操作构成的ADT,插入(或压入)一个新项,以及删除(或弹出)最近插入的数据项。

例1:堆栈ADT接口

Java代码 复制代码
  1. publicinterfaceIIntStack{
  2. intintStack(intvalue);
  3. intempty();
  4. voidpush(intvalue);
  5. intpop();
  6. }

例2:中缀法:5*(((9+8)*(4*6))+7),后缀法:5 9 8 + 4 6 * * 7 + *,前缀法:* + 7 * + 9 8 * 4 6 5

后缀计法和相关的压入栈操作应用到计算机中。如:

5 5

9 5 9

8 5 9 8

+ 5 17

4 5 17 4

6 5 17 4 6

* 5 17 24

* 5 408

7 5 408 7

+ 5 415

* 2075

Java代码 复制代码
  1. publicclassPostfix{
  2. publicstaticvoidmain(String[]args){
  3. char[]a="598+46**7+*".toCharArray();
  4. intN=a.length;
  5. IIntStacks=newIntStackImpl();
  6. for(inti=0;i<N;i++){
  7. if(a[i]=='+'){
  8. s.push(s.pop()+s.pop());
  9. }
  10. if(a[i]=='*'){
  11. s.push(s.pop()*s.pop());
  12. }
  13. if((a[i]>='0')&&(a[i]<='9')){
  14. s.push(0);
  15. }
  16. while((a[i]>='0')&&(a[i]<='9')){
  17. s.push(10*s.pop()+(a[i++]-'0'));
  18. }
  19. }
  20. System.out.println(s.pop());
  21. }
  22. }

例3:中缀到后缀的转换

Java代码 复制代码
  1. publicclassInfixToPostfix{
  2. publicstaticvoidmain(String[]args){
  3. char[]a="598+46**7+*".toCharArray();
  4. intN=a.length;
  5. IIntStacks=newIntStackImpl();
  6. for(inti=0;i<N;i++){
  7. if(a[i]==')'){
  8. System.out.println(s.pop()+"");
  9. }
  10. if((a[i]=='*')||(a[i]=='+')){
  11. s.push(a[i]);
  12. }
  13. if((a[i]>='0')&&(a[i]<='9')){
  14. System.out.println(a[i]+"");
  15. }
  16. }
  17. System.out.println("");
  18. }
  19. }

栈的ADT实现

主要:数组和链表

例3:堆栈的数组实现

Java代码 复制代码
  1. classIntStack{
  2. privateint[]s;
  3. privateintN;
  4. IntStack(intmaxN){
  5. s=newint[maxN];
  6. N=0;
  7. }
  8. booleanisEmpty(){
  9. return(N==0);
  10. }
  11. voidpush(intitem){
  12. s[N++]=item;
  13. }
  14. intpop(){
  15. returns[--N];
  16. }
  17. }<SPAN></SPAN>

例4:堆栈的链表实现

Java代码 复制代码
  1. classintStack{
  2. privateNodehead;
  3. privateclassNode{
  4. intitem;
  5. Nodenext;
  6. Node(intitem,Nodenext){
  7. this.item=item;
  8. this.next=next;
  9. }
  10. }
  11. intStack(intmaxN){
  12. head=null;
  13. }
  14. booleanisEmpty(){
  15. return(head==null);
  16. }
  17. voidpush(intitem){
  18. head=newNode(item,head);
  19. }
  20. intpop(){
  21. intv=head.item;
  22. Nodet=head.next;
  23. head=t;
  24. returnv;
  25. }
  26. }


客户程序并不关心在数组实现和链表实现中栈的项是否按不同的顺序存放的。实现可自由地使用任何数据结构,只要它能保持抽象堆栈的假象。链表实现能产生栈可以无限增长的假象。而在实际中是不可能的:到达一定时候,当无法满足请求更多内存的要求时,就会抛出异常。

一般实现:定义一个接口,并实现object类型的堆栈,

Java代码 复制代码
  1. Stacks=newStack(N);
  2. s.push(a);
  3. s.push(b);
  4. a=(Item)s.pop();
  5. b=(Item)s.pop();

例5:一般堆栈

Java代码 复制代码
  1. classStack{
  2. privateObject[]s;
  3. privateintN;
  4. Stack(intmaxN){
  5. s=newObject[maxN];
  6. N=0;
  7. }
  8. booleanisEmpty(){
  9. return(M==0);
  10. }
  11. voidpush(Objectitem){
  12. s[N++]=item;
  13. }
  14. Objectpop(){
  15. Objectt=s[--N];
  16. s[N]=null;
  17. returnt;
  18. }
  19. }

例6:整数栈的适配类

Java代码 复制代码
  1. classIntStack{
  2. privateStacks;
  3. intStack(intmaxN){
  4. s=newStack(maxN);
  5. }
  6. booleanisEmpty(){
  7. returns.isEmpty();
  8. }
  9. voidpush(intitem){
  10. s.push(newInteger(item));
  11. }
  12. intpop(){
  13. return((Integer)s.pop()).intValue();
  14. }
  15. }

创建新的ADT

设计一个新的ADT:开发解决应用问题的客户程序,定义接口,验证ADT是否更容易实现客户程序,再考虑是否合理、效率实现ADT中的操作,如果不能,找到原因进行更改。多次之后,改进的客户程序和ADT,采取策略冻结接口。

例7:等价关系ADT接口,连通性问题:初始化一个抽象数据结构来跟踪给定节点数之间的联系,判断两个给定节点是否连通,并把两个节点连起来,以后就认为它们是连通的。

Java代码 复制代码
  1. classUF{
  2. UF(intN);
  3. booleanfind(intx;inty);
  4. voidunite(intx;inty);
  5. }

例8:等价关系ADT的客户

Java代码 复制代码
  1. classEquivalence{
  2. publicstaticvoidmain(String[]args){
  3. intp,q,N=100;
  4. UFinfo=newUF(N);
  5. for(In.init();!In.empty();){
  6. p=In.getInt();q=In.getInt();
  7. if(!info.find(p,q)){
  8. info.unite(p,q);
  9. System.out.println(p+"-"+q);
  10. }
  11. }
  12. }
  13. }

例9:等价关系ADT实现:加权快速合并实现接口:

Java代码 复制代码
  1. privateint[]id,sz;
  2. privateintfind(intx){
  3. while(x!=id[x]){
  4. x=id[x];
  5. }
  6. returnx;
  7. }
  8. UF(intN){
  9. id=newint[N];
  10. sz=newint[N];
  11. for(inti=0;i<N;i++){
  12. id[i]=i;
  13. sz[i]=i;
  14. }
  15. }
  16. booleanfind(intp,intq){
  17. return(find(p)==find(q));
  18. }
  19. voidunite(intp,intq){
  20. inti=find(p),j=find(q);
  21. if(i==j){
  22. return;
  23. }
  24. if(sz[i]<sz[j]){
  25. id[i]=j;sz[j]+=sz[i];
  26. }else{
  27. id[j]=i;sz[i]+=sz[j];
  28. }
  29. }

比较:把解决高层(连通性)问题的任务和解决低层(合并-查找)的问题分开了,从而使我们能独立解决这两个问题;为我们提供了把解决该问题的不同算法和数据结构进行比较的自然方式;通过该接口定义了一个方法来检查软件是否按所期望的操作;为我们提供了一种更新的表示(新数据结构或新算法)而根本不需要改变客户程序的方法;为我们提供了一个能用来构建其他算法的抽象结构。

注意:使用抽象类或接口会产生运行时开销,每个抽象方法的调用需要跟踪表中对方法的一个引用。算法与数据结构经常用于系统中关键的性能部分,不希望以此为代价获得抽象类和接口的灵活性。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics