12.java链表栈和数组栈
栈是一个先入后出的有序列表,栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表,一端为变化的一端,称为栈顶,另一端是固定的,称为栈底。先入的元素在栈底,最后放入的元素在栈顶,删除时后放入的元素先删除,最先放入的元素最后删除。
老师在这里讲解的只有用数组模拟栈,书写类ArrayStack,其中定义一个int类型的变量top来记录栈顶索引,一个数组来记录数据,一个int类型的变量maxSize来记录栈的最大尺寸即可容纳的数据个数。
代码如下:
class ArrayStack{ public int top=-1; public int[] stack; public int maxSize; public ArrayStack(int maxSize) { this.maxSize = maxSize; stack=new int[maxSize]; } public boolean isFull(){ if(top==maxSize-1) return true; return false; } public boolean isEmpty(){ if(top==-1) return true; return false; } public void push(int value){ if(isFull()){ System.out.println("栈满,无法加入"); return; } top++;//先加栈顶再赋值 stack[top]=value; } public int pop(){ if(isEmpty()){ throw new RuntimeException("栈空,没有数据"); } int value=stack[top]; top--; return value; } public void list(){ if(isEmpty()){ System.out.println("栈空,没有数据"); } for(int i=top;i>=0;i--){ System.out.printf("stack[%d]=%d",i,stack[i]); } } }
老师留了课后作业,让我们 用链表代替数组来书写栈,在很多次的修改和斟酌以后,我的最后设想如下:首先链表的节点中有三个变量,代表编号的no变量,代表具体数据的data变量和一个ArrayStack变量next来指向下一个节点。不再额外定义链表类来管理节点,直接定义链表栈类来管理节点,其中有两个变量,代表最大可容纳数据的maxSize,和一个头节点代表链表。在原先变量top的改变上我最开始想另外定义一个节点为top来指向栈顶。但在试验后发现并没有这种必要,因为此处我使用的是头插法,所以栈顶永远都是head.next,不需另外定义。另外,在判断栈空和栈满时我发现十分麻烦,所以废物利用了一下head节点中的data变量,将其含义变为目前链表长度,这样在判断时只需要判断head.data是否为0或者maxSize即可。
java链表栈的类定义如下:
class linkstack{ public int maxSize; public linkstack(int maxSize) { this.maxSize = maxSize; } public stackNodee head=new stackNodee(0,0); public boolean isFull(){ if(head.data==maxSize){ return true; } return false; } public boolean isempty(){ if(head.data==0){ return true; } return false; } public void push(int value){ if(isFull()){ System.out.println("栈已满,无法加入"); return; } int n=head.data+1; stackNodee temp=new stackNodee(n,value); if(isempty()){ head.next=temp; head.data++; return; } temp.next=head.next; head.next=temp; head.data++; } public int pop(){ int value; if(isempty()){ throw new RuntimeException("栈空,没有数据"); }else { value=head.next.data; head.next=head.next.next; head.data--; } return value; } public void list(){ if(isempty()){ System.out.println("链表为空"); return; } stackNodee temp=head.next; for (int i=1;i<=head.data;i++){ System.out.printf("stack[%d]=%d\n",i,temp.data); temp=temp.next; } } } class stackNodee{ public int no; public int data; public stackNodee next; public stackNodee(int no, int data) { this.no = no; this.data = data; } }
这次的实验让我灵活运用了链表和栈,对此两种数据结构都有了更进一步的理解。在书写代码的过程中,我个人认为数组的方式还是要比链表的方式简单很多,有序数组自带记录了索引和数据,以及可定义数组长度,我认为还是比链表方便很多。