栈与队列更多的作为程序员的工具来使用,构思算法的辅助工具,而数组、链表等是作为数据存储工具,适用于数据库应用中做数据记录,但栈与队列不是完全的数据存储工具,他们的生命周期比较短,在程序操作执行期间他们才被创建,在完成任务后就被销毁。
栈与队列的访问是受限制的,即在特定时刻只有一个数据项可以被读取或被删除。
他们可以用数组或链表来实现,比数组、链表更加抽象。
Stack
在解析算数表达式方面的应用
对分隔符的匹配验证
大部分微处理器运用基于栈的体系结构
方法:push pop peek
Top指针,指向栈顶元素
public void push(long d) {
arrayStack[++top] = d;
}
public long pop {
return arrayStack[top--];
}
当栈是由数组实现的,需要先指定栈的大小。
入栈 出栈 O(1)
Queue
FIFO 先进先出
模拟排队,网络上数据的传递
队头(front)和队尾(rear)两个指针
队列中的数据项不总是从数组的0下标处开始
效率的提高:循环队列 指针移动 环绕式处理 (避免队列不满却不能插入新数据项的问题)
方法:
insert(long i ) {
if (rear == maxsize-1) rear=-1
arrayQue[ ++rear] = i;
}
remove() {
temp = arrayQue[front++] ;
if (front == maxsize) front = 0;
}
注意在插入和删除之前要判断队列是否为满或空
有两种判断方法:
1、通过一个数据项计数变量 nItems
2、通过front和rear来计算。 在同一时间,通过front和rear的位置来判断,队列可能是满的,也可能是空的。
→→解决方法:让数组容量比队列数据项个数的最大值还要大一,
isEmpty rear+1 == front | | front + maxsize -1 == rear
isFull rear + 2 - maxsize = front || rear +2 == front
即队列的容量为maxsize-1
插入与删除操作的时间复杂度均为O(1)
Priority Queue
通常使用堆来实现 (用数组实现插入较慢,需要比较大小和移动数据)
数组实现:
这里假设数值小的优先级高,即放在队头
注意队尾指针从不移动,总指着数值底端下标为0的单元
插入操作时间复杂度为O(N)
Insert方法需要在其中比较,找到插入的位置,其中需要移动数据
public void insert(long item) // insert item { int j; if(nItems==0) // if no items, queArray[nItems++] = item; // insert at 0 else // if items, { for(j=nItems-1; j>=0; j--) // start at end, { if( item > queArray[j] ) // if new item larger, queArray[j+1] = queArray[j]; // shift upward else // if smaller, break; // done shifting } // end for queArray[j+1] = item; // insert it nItems++; } // end else (nItems > 0) } // end insert()