------------------------------------------------------------------------------
栈、队列、优先级队列
-------------------
栈《刷盘子之后摞起来的盘子,最后放进去的,最先被使用。LIFO 后进先出。栈顶栈低。PUSH入栈 POP出栈》
栈只允许访问一个数据项:即最后插入的数据项。移除这个数据项后才能访问
倒数第二个插入的数据项,以此类推。《有个top指针一直指向栈顶元素》
基本操作:
PUSH入栈 新加进来的盘子 只能放在最顶上(栈顶指针移动+1)
POP出栈 用盘子只能拿最顶上的盘子 (栈顶指针移动-1)
栈实例
1.单词逆序
字母从输入的字符串中一个一个提取出来并压入栈中。接着他们依次弹出栈,并显示出来。
因为栈具有后进先出的特性。所以字母的顺序就颠倒过来了。
2.分隔符匹配
程序不断读取字符串,每次读取一个字符。若发现他是左分隔符,则将它压入栈中。
当输入中读到一个右分隔符时,弹出栈顶的左分隔符。并且查看它是否和右分隔符匹配。
如果不匹配程序报错。
如果栈中没有左分隔符和右分隔符匹配或者存在一直没有匹配的分隔符。程序报错。
分隔符没有被匹配的表现是:栈中仍然留有分隔符。
可行性在于:最后出现的左边分隔符 需要最先匹配。这个规律符合LIFO栈的特点。
demo:a{b(c[d]e)f}
所读字符 栈中内容( _表示空栈 栈底-->栈顶)
a _
{ {
b {
( {(
c {(
[ {([
d {([
] {(
e {(
) {
f {
} _
栈的效率O(1):
(数组实现的栈) 入栈出栈的时间复杂度 都为O(1)
-------------------
**队列
有点类似栈的数据结构。队列中第一个插入的数据也会最先被移除掉。(火车站排队买票,FIFO先进先出。队头 队尾)
敲击键盘时也有一个存储键入内容的队列。同样如果使用文字处理程序敲击一个键,而
计算机有暂时要做其他的事情。敲击的内容不会丢失。它会排在队列中等待。直到文字处理程序
有时间来读取它。利用队列保证了键入内容在处理时其顺序不会改变。
基本操作:
插入:插入一个数据项,即把一个数据项放入队尾。
删除:删除一个数据项,即把从队头一个数据项。
循环队列
为了避免队列不满 却不能插入新数据的问题,可以让队尾指针绕回到数组开始的位置。这就是循环队列(又叫:缓冲环)
循环队列的环绕式处理
队列效率O(1):
和栈一样,队列中插入和移除数据的时间复杂度均为O(1)。
双端队列
双端队列就是一个两端都是结尾的队列。队列的每一端都可以插入和移除数据项。双端队列通过方法的限制可以实现栈和队列的功能。
-------------------
**优先级队列
和普通队列一样,优先级队列有一个队头和队尾,并且也是从队头移除数据项,不过在优先级队列中,数据项
按照关键字的值有序,这样关键字最小的数据项(某些实现中是关键字最大的数据项)总是在队头。
数据项插入的时候就会按照顺序插入到合适的位置以确保队列的顺序。
优先级队列用于对信件排序的例子:
每拿到一封信就根据信的优先级把他插入到没看过的邮件堆里。如果必须马上回复 就放在最上面。
如果可以等空闲时间再回复,就可以把他放在最底下。中等优先的信件就放在中间。
级别越高的放的位置就越高。邮件堆的顶端对应优先级队列的队头。
例子:
抢先式多任务操作系统中,程序排在优先级队列中,这样优先级最高的程序就会先得打时间片并得以运行。
优先级队列效率:
插入操作O(N)
删除操作O(1)
-------------------
总结:
1.栈、队列、优先级队列 这些数据结构中 只有一个数据项可以被访问。
2.栈允许访问最后一个插入的数据项(即栈顶数据),其最重要的操作 PUSH栈顶插入 和 POP 栈顶弹出
3.队列只允许访问第一个插入的数据项。其重要操作是在队尾插入数据项 、在队头移除数据项
4.队列可以基于数组 实现循环队列(循环队列的环绕式处理)
5.优先级队列只允许访问最小(或最大的)数据项。最重要操作 有序的插入新数据项 和移除关键字最小的数据项。
################################################################################
------------------------------------------------------------------------------
栈、队列、优先级队列
-------------------
栈《刷盘子之后摞起来的盘子,最后放进去的,最先被使用。LIFO 后进先出。栈顶栈低。PUSH入栈 POP出栈》
栈只允许访问一个数据项:即最后插入的数据项。移除这个数据项后才能访问
倒数第二个插入的数据项,以此类推。《有个top指针一直指向栈顶元素》
基本操作:
PUSH入栈 新加进来的盘子 只能放在最顶上(栈顶指针移动+1)
POP出栈 用盘子只能拿最顶上的盘子 (栈顶指针移动-1)
栈实例
1.单词逆序
字母从输入的字符串中一个一个提取出来并压入栈中。接着他们依次弹出栈,并显示出来。
因为栈具有后进先出的特性。所以字母的顺序就颠倒过来了。
2.分隔符匹配
程序不断读取字符串,每次读取一个字符。若发现他是左分隔符,则将它压入栈中。
当输入中读到一个右分隔符时,弹出栈顶的左分隔符。并且查看它是否和右分隔符匹配。
如果不匹配程序报错。
如果栈中没有左分隔符和右分隔符匹配或者存在一直没有匹配的分隔符。程序报错。
分隔符没有被匹配的表现是:栈中仍然留有分隔符。
可行性在于:最后出现的左边分隔符 需要最先匹配。这个规律符合LIFO栈的特点。
demo:a{b(c[d]e)f}
所读字符 栈中内容( _表示空栈 栈底-->栈顶)
a _
{ {
b {
( {(
c {(
[ {([
d {([
] {(
e {(
) {
f {
} _
栈的效率O(1):
(数组实现的栈) 入栈出栈的时间复杂度 都为O(1)
-------------------
**队列
有点类似栈的数据结构。队列中第一个插入的数据也会最先被移除掉。(火车站排队买票,FIFO先进先出。队头 队尾)
敲击键盘时也有一个存储键入内容的队列。同样如果使用文字处理程序敲击一个键,而
计算机有暂时要做其他的事情。敲击的内容不会丢失。它会排在队列中等待。直到文字处理程序
有时间来读取它。利用队列保证了键入内容在处理时其顺序不会改变。
基本操作:
插入:插入一个数据项,即把一个数据项放入队尾。
删除:删除一个数据项,即把从队头一个数据项。
循环队列
为了避免队列不满 却不能插入新数据的问题,可以让队尾指针绕回到数组开始的位置。这就是循环队列(又叫:缓冲环)
循环队列的环绕式处理
队列效率O(1):
和栈一样,队列中插入和移除数据的时间复杂度均为O(1)。
双端队列
双端队列就是一个两端都是结尾的队列。队列的每一端都可以插入和移除数据项。双端队列通过方法的限制可以实现栈和队列的功能。
-------------------
**优先级队列
和普通队列一样,优先级队列有一个队头和队尾,并且也是从队头移除数据项,不过在优先级队列中,数据项
按照关键字的值有序,这样关键字最小的数据项(某些实现中是关键字最大的数据项)总是在队头。
数据项插入的时候就会按照顺序插入到合适的位置以确保队列的顺序。
优先级队列用于对信件排序的例子:
每拿到一封信就根据信的优先级把他插入到没看过的邮件堆里。如果必须马上回复 就放在最上面。
如果可以等空闲时间再回复,就可以把他放在最底下。中等优先的信件就放在中间。
级别越高的放的位置就越高。邮件堆的顶端对应优先级队列的队头。
例子:
抢先式多任务操作系统中,程序排在优先级队列中,这样优先级最高的程序就会先得打时间片并得以运行。
优先级队列效率:
插入操作O(N)
删除操作O(1)
-------------------
总结:
1.栈、队列、优先级队列 这些数据结构中 只有一个数据项可以被访问。
2.栈允许访问最后一个插入的数据项(即栈顶数据),其最重要的操作 PUSH栈顶插入 和 POP 栈顶弹出
3.队列只允许访问第一个插入的数据项。其重要操作是在队尾插入数据项 、在队头移除数据项
4.队列可以基于数组 实现循环队列(循环队列的环绕式处理)
5.优先级队列只允许访问最小(或最大的)数据项。最重要操作 有序的插入新数据项 和移除关键字最小的数据项。
################################################################################
《1》栈
// stack.java
// demonstrates stacks
// to run this program: C>java StackApp
class StackX
{
private int maxSize; // size of stack array
private long[] stackArray;
private int top; // top of stack
//--------------------------------------------------------------
public StackX(int s) // constructor
{
maxSize = s; // set array size
stackArray = new long[maxSize]; // create array
top = -1; // no items yet
}
//--------------------------------------------------------------
public void push(long j) // put item on top of stack
{
stackArray[++top] = j; // increment top, insert item
}
//--------------------------------------------------------------
public long pop() // take item from top of stack
{
return stackArray[top--]; // access item, decrement top
}
//--------------------------------------------------------------
public long peek() // peek at top of stack
{
return stackArray[top];
}
//--------------------------------------------------------------
public boolean isEmpty() // true if stack is empty
{
return (top == -1);
}
//--------------------------------------------------------------
public boolean isFull() // true if stack is full
{
return (top == maxSize-1);
}
//--------------------------------------------------------------
} // end class StackX
class StackApp
{
public static void main(String[] args)
{
StackX theStack = new StackX(10); // make new stack
theStack.push(20); // push items onto stack
theStack.push(40);
theStack.push(60);
theStack.push(80);
while( !theStack.isEmpty() ) // until it's empty,
{ // delete item from stack
long value = theStack.pop();
System.out.print(value); // display it
System.out.print(" ");
} // end while
System.out.println("");
} // end main()
} // end class StackApp
################################################################################
《2》队列
// Queue.java
// demonstrates queue
// to run this program: C>java QueueApp
class Queue
{
private int maxSize;
private long[] queArray;
private int front;
private int rear;
private int nItems;
//--------------------------------------------------------------
public Queue(int s) // constructor
{
maxSize = s;
queArray = new long[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
//--------------------------------------------------------------
public void insert(long j) // put item at rear of queue
{
if(rear == maxSize-1) // deal with wraparound
rear = -1;
queArray[++rear] = j; // increment rear and insert
nItems++; // one more item
}
//--------------------------------------------------------------
public long remove() // take item from front of queue
{
long temp = queArray[front++]; // get value and incr front
if(front == maxSize) // deal with wraparound
front = 0;
nItems--; // one less item
return temp;
}
//--------------------------------------------------------------
public long peekFront() // peek at front of queue
{
return queArray[front];
}
//--------------------------------------------------------------
public boolean isEmpty() // true if queue is empty
{
return (nItems==0);
}
//--------------------------------------------------------------
public boolean isFull() // true if queue is full
{
return (nItems==maxSize);
}
//--------------------------------------------------------------
public int size() // number of items in queue
{
return nItems;
}
//--------------------------------------------------------------
} // end class Queue
class QueueApp
{
public static void main(String[] args)
{
Queue theQueue = new Queue(5); // queue holds 5 items
theQueue.insert(10); // insert 4 items
theQueue.insert(20);
theQueue.insert(30);
theQueue.insert(40);
theQueue.remove(); // remove 3 items
theQueue.remove(); // (10, 20, 30)
theQueue.remove();
theQueue.insert(50); // insert 4 more items
theQueue.insert(60); // (wraps around)
theQueue.insert(70);
theQueue.insert(80);
while( !theQueue.isEmpty() ) // remove and display
{ // all items
long n = theQueue.remove(); // (40, 50, 60, 70, 80)
System.out.print(n);
System.out.print(" ");
}
System.out.println("");
} // end main()
} // end class QueueApp
################################################################################
《3》优先级队列
// priorityQ.java
// demonstrates priority queue
// to run this program: C>java PriorityQApp
class PriorityQ
{
// array in sorted order, from max at 0 to min at size-1
private int maxSize;
private long[] queArray;
private int nItems;
//-------------------------------------------------------------
public PriorityQ(int s) // constructor
{
maxSize = s;
queArray = new long[maxSize];
nItems = 0;
}
//-------------------------------------------------------------
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()
//-------------------------------------------------------------
public long remove() // remove minimum item
{ return queArray[--nItems]; }
//-------------------------------------------------------------
public long peekMin() // peek at minimum item
{ return queArray[nItems-1]; }
//-------------------------------------------------------------
public boolean isEmpty() // true if queue is empty
{ return (nItems==0); }
//-------------------------------------------------------------
public boolean isFull() // true if queue is full
{ return (nItems == maxSize); }
//-------------------------------------------------------------
} // end class PriorityQ
class PriorityQApp
{
public static void main(String[] args)
{
PriorityQ thePQ = new PriorityQ(5);
thePQ.insert(30);
thePQ.insert(50);
thePQ.insert(10);
thePQ.insert(40);
thePQ.insert(20);
while( !thePQ.isEmpty() )
{
long item = thePQ.remove();
System.out.print(item + " "); // 10, 20, 30, 40, 50
} // end while
System.out.println("");
} // end main()
//-------------------------------------------------------------
} // end class PriorityQApp
------------------------------------------------------------------------------