栈和队列
栈(stack)是一种后进先出(Last In First Out,LIFO)的数据结构。用栈做辅助可以实现深度优先算法。
队列(queue)是一种先进先出(First In First Out,LIFO)的数据结构。用队列做辅助可以实现广度优先算法。
一. 栈和队列的定义和简单操作的实现
栈的实现
- 通过链表实现
/*
* 定义一个结点类
*/
public class Node {
Node next;
int data;
public Node(int data){
this.data = data;
}
}
/*
* 通过链表定义一个栈类,并且定义各种对栈操作的方法
*/
public class Stack1 {
public Node head; //头指针
int size = 0; //栈的容量
int count = 0; //栈内元素个数
//构造函数,生成一个指定容量的空栈
public Stack1(int size){
head = null;
this.size = size;
}
//push方法(讲一个元素压入栈中)
public void push(int data){
if(isFull()){
System.out.println("此栈已满!");
}else{
Node node = head;
head = new Node(data);
head.next = node;
count += 1;
}
}
//pop方法(将栈顶元素推出)
public void pop(){
head = head.next;
count -= 1;
}
//peek方法(查看栈顶元素)
public int peek(){
if(this.isEmpty()){
System.out.println("此栈为空!");
}else{
System.out.println("栈顶元素为:" + head.data);
}
return head.data;
}
//判断栈是否为空
public boolean isEmpty(){
if(count == 0)
return true;
return false;
}
//判断栈是否已满
public boolean isFull(){
if(count == size)
return true;
return false;
}
//遍历栈
public void ShowAllElement(){
Node node = head;
for(int i = 0; i < count;i++){
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
}
- 通过数组实现
/*
* 通过数组定义一个栈类,并且定义各种对栈操作的方法
*/
public class Stack2 {
int size; //栈的容量
public int []stack;
int top; //栈顶位置
//构造函数,生成一个指定大小的空栈
Stack2(int size){
this.size = size;
stack = new int[size];
top = -1;
}
//push方法(讲一个元素压入栈中)
public void push(int data){
if(isFull()){
System.out.println("此栈已满!");
}else{
top += 1;
stack[top] = data;
}
}
//pop方法(将栈顶元素推出)
public void pop(){
if(isEmpty()){
System.out.println("此栈为空!");
}else{
stack[top] = 0;
top -= 1;
}
}
//peek方法(查看栈顶元素)
public int peek(){
System.out.println(stack[top] + " ");
return stack[top];
}
//判断栈是否为空
public boolean isEmpty(){
if(top == -1)
return true;
return false;
}
//判断栈是否为空
public boolean isFull(){
if(top == size-1)
return true;
return false;
}
//遍历栈
public void showAllElement(){
for(int i = top; i >= 0;i--){
System.out.print(stack[i] + " ");
}
System.out.println();
}
}
队列的实现
- 通过链表实现
/*
* 定义一个结点类
*/
public class Node {
Node next;
int data;
public Node(int data){
this.data = data;
}
}
/*
* 通过链表定义一个队列类,并且定义各种对队列操作的方法
*/
public class Queue1 {
public Node head; //头指针
public Node tail; //尾指针
int size; //队列的最大长度
int count; //队列内元素个数
//定义一个指定最大长度的队列
public Queue1(int size){
head = null;
tail = head;
this.size = size;
count = -1;
}
//进队方法(往队列中添加一个元素)
public void enqueue(int data){
if(isFull()){
System.out.println("此队列已满!");
}else{
count += 1;
Node node = new Node(data);
if(head == null){
head = node;
}else{
tail.next = node;
}
tail = node;
}
}
//出队方法(移除最早进入队列的元素并返回出队的元素)
public void dequeue(){
if(isEmpty()){
System.out.println("此队列为空!");
}else{
head = head.next;
count -= 1;
}
}
//p判断队列是否为空
public boolean isEmpty(){
if(count == -1)
return true;
return false;
}
//判断队列是否已满
public boolean isFull(){
if(count == size-1)
return true;
return false;
}
//遍历队列
public void showAllElement(){
Node node = head;
if(isEmpty()){
System.out.println("此队列为空!");
}else{
while(node != null){
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
}
}
- 通过数组实现
/*
* 通过数组定义一个栈类,并且定义各种对栈操作的方法
*/
public class Queue2 {
int size; //队列最大长度
int []queue;
int head; //最初进入队列的元素位置
public Queue2(int size){
this.size = size;
queue= new int[size];
head = -1;
}
//进队方法(往队列中添加一个元素)
public void enqueue(int data){
if(isFull()){
System.out.println("此队列已满!");
}else{
head += 1;
int temp = head;
for(int i = head; i > 0; i--){
queue[temp] = queue[temp - 1];
temp -= 1;
}
queue[0] = data;
}
}
//出队方法(移除最早进入队列的元素并返回出队的元素)
public void dequeue(){
if(isEmpty()){
System.out.println("此队列为空!");
}else{
queue[head] = 0;
head -= 1;
}
}
//判断队列是否为空
public boolean isEmpty(){
if(head == -1)
return true;
return false;
}
//判断队列是否已满
public boolean isFull(){
if(head == size-1)
return true;
return false;
}
//遍历队列
public void showAllElement(){
if(isEmpty()){
System.out.println("此队列为空!");
}else{
for(int i = head; i >= 0; i--){
System.out.print(queue[i] + " ");
}
System.out.println();
}
}
}
二. 面试中常见的栈和队列相关问题
(没有实现的,后续一一补充)
实现一个栈,要求Push(入栈),Pop(出栈),Min(返回最小值的操作)的时间复杂度为O(1)。
使用两个栈实现一个队列。
使用两个队列实现一个栈。
按照升序来输出栈内元素。
给定一个字符串,它只包含如下的字符:’(‘、’)’、’{‘、’}’、’[‘和’]’,判断输入的字符串是否是一个有效的圆括号字符串。例如,“(([]))”是有效的,而“(}”和“((”则不是。
给定一个二叉树,使用栈实现中序遍历。
不用递归实现汉诺塔问题