学习笔记:数据结构栈和队列
一、栈和队列的共同点
栈和队列主要作为程序员构思算法的工具,不是完全的数据存储工具,生命周期比持久型的数据结构短,只有程序执行操作期间才被创建,程序执行完成,就会销毁。
特性是受限访问,即不能像数组那样直接通过下标访问元素,也不能像链表那样顺序遍历访问数据项,特定时刻只能有一个元素被访问或删除。
二、栈
1.特性
栈只允许访问一个数据项:最后插入的数据项。只有移除这个数据项才能访问倒数第二个被插入的数据项。
2.数组实现栈
简单的实现一下栈(用数组),创建、入栈、出栈、查看栈顶等方法。
public class ArrayStack {
//底层是数组,创建时要声明数组大小
int[] array;
int maxSize = 10;
//维护一个指针访问栈顶元素,数组就是下标数字
int top;
public ArrayStack() {
array = new int[maxSize];
top = -1;
}
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
top = -1;
}
//判断是否空栈
public boolean isEmpty() {
return top == -1;
}
//判断是否满栈
public boolean isFull() {
return top == this.maxSize - 1;
}
//入栈
public void push(int data) {
if (!isFull()){
array[++top] = data;
}
}
//出栈,返回栈顶元素
public int pop() {
if (!isEmpty()) {
return array[top--];
}
return 0;
}
//查看栈顶元素
public int peek() {
return array[top];
}
}
测试一下:
public class StackTest {
@Test
public void testArrayStack() {
ArrayStack stack = new ArrayStack(10);
//入栈
stack.push(14);
stack.push(23);
stack.push(65);
stack.push(12);
//出栈
System.out.println("出栈元素: "+ stack.pop());
System.out.println("出栈元素: "+ stack.pop());
//查看栈顶元素
System.out.println("栈顶元素: "+ stack.peek());
}
}
运行结果:
出栈元素: 12
出栈元素: 65
栈顶元素: 23
push()
入栈方法中将top值加一,指向原来数据项顶端上面的一个位置,并在这位置上存储一个数据项。
pop()
出栈方法返回top标识的数据项,然后再减一。尽管数据项仍在数组中,但是不能访问了,直到新元素压入栈中覆盖这个数据项
peek()
就是访问top指向的数据项,不修改栈。
3.栈的效率
入栈和出栈时间复杂度O(1);
二、队列
1.概述
队列也是一种数据结构,和栈类似,不过队列中的第一个插入的元素会最先被移除。
队列的常见操作时创建和入队、出队、查看队首方法。
public class ArrayQueue {
//数组实现队列,需要声明大小
int maxSize = 10;
int[] array;
//声明队头指针
int front;
//声明队尾指针
int near;
//记录元素个数
int num;
public ArrayQueue() {
array = new int[maxSize];
front = 0;
near = -1;
num = 0;
}
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
front = 0;
near = -1;
num = 0;
}
//判断非空
public boolean isEmpty() {
return num == 0;
}
//判断是否满
public boolean isFull() {
return num == maxSize;
}
//入队
public void insert(int data) {
if (!isFull()) {
if (near == maxSize - 1) { //循环队列
near = -1;
}
array[++near] = data;
num++;
}
}
//出队
public int remove() {
if (isEmpty()) {
return -1;
}
int temp = array[front];
if (front == maxSize -1) {
front = -1;
}
front++;
num--;
return temp;
}
//查看队首元素
public int peekFront() {
return array[front];
}
//队列数据项数量
public int size() {
return num;
}
}
测试代码:
public class QueueTest {
@Test
public void testArrayQueue() {
ArrayQueue arrayQueue = new ArrayQueue();
//测试入队方法
arrayQueue.insert(23);
arrayQueue.insert(230);
arrayQueue.insert(2300);
arrayQueue.insert(23000);
//查看队首元素
System.out.println("队首元素: "+arrayQueue.peekFront());;
//测试出队方法
System.out.println("出队元素: "+arrayQueue.remove());
System.out.println("队首元素: "+arrayQueue.peekFront());;
System.out.println("出队元素: "+arrayQueue.remove());
System.out.println("队首元素: "+arrayQueue.peekFront());;
System.out.println("元素个数:" +arrayQueue.size());
}
}
运行结果:
队首元素: 23
出队元素: 23
队首元素: 230
出队元素: 230
队首元素: 2300
元素个数:2
2.队列的效率
队列效率和栈一样,入队和出队时间复杂度都是O(1);
3.优先级队列
优先级和队列和普通队列一样,也是有队首和队尾,不过优先级队列数据项按照关键字的值有序。
public class PriorityQueue {
//数组实现队列,需要声明大小
int maxSize = 10;
int[] array;
//记录元素个数
int num;
public PriorityQueue() {
array = new int[maxSize];
num = 0;
}
public PriorityQueue(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
num = 0;
}
//判断非空
public boolean isEmpty() {
return num == 0;
}
//判断是否满
public boolean isFull() {
return num == maxSize;
}
//入队
public boolean insert(int data) {
if (isFull()) {
return false;
}
if (isEmpty()) {
array[num++] = data;
return true;
} else {
int i;
for ( i = num - 1; i >= 0; i --) {
if (array[i] < data) {
array[i+1] = array[i];
} else {
break;
}
}
array[i+1] = data;
num++;
return true;
}
}
//出队
public int remove() {
if (isEmpty()) {
return -1;
} else {
return array[--num];
}
}
//查看优先级最小的元素
public int peekMin() {
return array[num-1];
}
//队列数据项数量
public int size() {
return num;
}
}
测试代码:
@Test
public void testPriorityQueue() {
PriorityQueue priorityQueue = new PriorityQueue();
//入队
priorityQueue.insert(78);
priorityQueue.insert(32);
priorityQueue.insert(2);
priorityQueue.insert(788);
System.out.println("元素个数:" + priorityQueue.size());
//出队
System.out.println("出队元素: "+ priorityQueue.remove());
System.out.println("优先级最小的元素: "+ priorityQueue.peekMin());
System.out.println("出队元素: "+ priorityQueue.remove());
System.out.println("优先级最小的元素: "+ priorityQueue.peekMin());
System.out.println("元素个数:" + priorityQueue.size());
//查看队尾元素
System.out.println("优先级最小的元素: "+ priorityQueue.peekMin());
}
运行结果:
元素个数:4
出队元素: 2
优先级最小的元素: 32
出队元素: 32
优先级最小的元素: 78
元素个数:2
优先级最小的元素: 78
优先级队列的效率:插入的时间复杂度是O(n),删除的效率是O(1)