栈
栈只允许访问一个数据项:最后插入的数据项。只有移除这个数据项后,才能访问倒数第二次插入的数据项。
java有Stack类,实现List接口,同时继承了vactor父类,很方便。如果需要自己实现,则利用的数据结构就是数组array。
但是用array实现的stack只是一个概念上的辅助工具,并不会在效率上带来多大的提高。
出栈和入栈的时间复杂度都是常数O(1).
需要实现这几个方法即可:
void push(int j) {
stackArray[++top] = j //注意这里是++top而不是top++。因为top++使指针没有指向最后一个插入的数据项了。
} --将一个元素放入stack,top永远指向最后插入的数据项。
int peek(){
return stackArray[top];
}--返回top数据项。
int pop(){
return stackArray[top--];
}--移除top数据项
栈的用途:
1,单词逆序。
public class App{
public int top = 0;
public char[] q ;
public static void main(String args[]){
App s = new App();
String w = "application";
s.q = new char[w.length()+1];
for(int i=0; i< w.length();i++){
s.push(w.charAt(i));
}
// System.out.println(Arrays.toString(s.q));
// System.out.println(s.top);
while(s.top>0){
System.out.println(s.peek());
s.pop();
}
}
public void push(char i){
q[++top] = i;
}
public void pop(){
top--;
}
public char peek(){
return q[top];
}
}
说一些题外话,对于单词逆序这个问题本身而言没有必要用stack,很简单的代码就能实现,如下。
public class Testing{
public static void main(String arg[]){
char[] x = {'t','e','s','t','i','n'};
System.out.println(Arrays.toString(rotate(x))); //而且不需要考虑字符数是奇数还是偶数
}
public static char[] rotate(char[] s){
char x = 0;
for(int i=0;i<s.length-i;i++){
x = s[i];
s[i] = s[s.length-1-i];
s[s.length-1-i] = x;
}
return s;
}
}
2, 分隔符验证。例如在java代码中,有{就一定有}和它相对应。[]也是如此。如果有嵌套,则顺序不能乱:
c{b[n}m] 这样是非法的。同理对于xml也是如此,<A><B></B>< /A>的嵌套顺序必须保证。
首先将分隔符分为左分割和右分隔符,将所有的左分隔符依次压入stack,最后压入的分隔符在最上。然后依次读出stack,和右分隔符做比较。
很简单啊~
队列 queue
queue和stack的区别就是先进先出。想想生活中实际的排队,也是最先排队的人,最先买到票或得到服务。
在计算机或网络操作系统中,各种各样的队列在安静的工作着。打印作业在打印队列中等待打印。在键盘上敲击时,也有一个存储键入内容的队列。
有时候计算机繁忙时,会发现键入内容后没有反应,过了一段时间以后,内容又一下子出现在屏幕上了。这就是因为有输入内容队列,键入的内容才没有丢失,而且顺序也不会变
通常使用数组或链表来实现队列。因为队列先进先出的特点,如果用数组来实现则需要移动数组元素,所以效率不高。因此更多的是用链表来实现。
优先级队列
优先级队列和队列的区别就是,优先级队列是按关键字排序的。而每次新数据进入队列,也会根据需要将数据插入到应该的位置,以便确保队列的顺序。
在抢占式多任务操作系统中,程序就在优先级队列中排序。
在优先级队列中,可以很快速的访问到有最小关键字或最大关键字的数据项。但是由于优先级队列需要实现数据项的有序快速插入,因此通常不使用数组来实现,而是使用堆。
堆是用一种特殊的二叉树来实现的,但我觉得用有序链表也可以。因为有序链表的查找时间复杂度是O(logN),插入是O(1),而且不需要移动其他的元素.