数据结构与算法-栈和队列

一、基本含义

参考:https://mp.weixin.qq.com/s/D9_wM42c3Czhg9-NsPFJ8Q
链表和数组是线性结构的基础,栈和队列是线性结构的应用。

1.1 栈

含义:可以将栈看成一个箱子。
作用:放置数据。
分类:静态栈(数组实现) + 动态栈(链表实现)。
在这里插入图片描述

项目含义
入栈往箱子里面放东西
出栈往箱子里面取东西
栈底箱子的底部
栈顶箱子的顶部
特性先进后出(LIFO, Last In First Out)

1.2 队列

含义:可以将队列看成小朋友排队。
作用:放置数据。
分类:静态队列(数组实现) + 动态队列(链表实现)。
在这里插入图片描述

项目含义
入队新的小朋友排队打饭了
出队小朋友打完饭,走了。
队头第一个小朋友
对尾最后一个小朋友
特性先进先出

二、代码实现

2.1 栈

2.1.1 创建节点类与栈类

本处采用链表创建动态栈。
Node.java

public class Node {    
    public int data;//数据域    
    public Node next;//指针域,指向下一个节点
    public Node() {
    }
    public Node(int data) {
        this.data = data;
    }
    public Node(int data, Node next) {
        this.data = data;
        this.next = next;
    }
}

Stack.java

public class Stack {
    public Node stackTop; // 栈顶指针
    public Node stackBottom; // 栈底指针
    public Stack(Node stackTop, Node stackBottom) {
        this.stackTop = stackTop;
        this.stackBottom = stackBottom;
    }
    public Stack() {
    }
}

2.1.2 遍历栈

含义:获取节点值。
只要栈顶元素的指针不指向栈底,那么就一直输出遍历结果。

public static void traverse(Stack stack) {
	Node stackTop = stack.stackTop;
	while (stackTop != stack.stackBottom) {
		System.out.println("栈元素值:" + stackTop.data);
		stackTop = stackTop.next;
	}
}

2.1.3 判断该栈是否为空

含义:是否有元素。
只要栈顶和栈底是同一指向,那么该栈就为空。

public static boolean isEmpty(Stack stack) {
	return ((stack.stackTop == stack.stackBottom) ? true:false);
}

2.1.4 入栈(进栈)

含义:增加新节点。
将原本栈顶指向的节点交由新节点来指向,栈顶指向新加入的节点。

public static void pushStack(Stack stack, int value) {
	Node newNode = new Node(value); // 新节点
	// 交换。
	newNode.next = stack.stackTop;// 栈顶本来指向的节点交由新节点来指向	
	stack.stackTop = newNode;// 栈顶指针指向新节点
}

2.1.5 出栈

含义:删除元素。
1、在出栈之前看看该栈是否为空,不为空才出栈…
2、将栈顶的元素的指针(指向下一个节点)赋值给栈顶指针(完成出栈)

public static void popStack(Stack stack) {
	// 栈不为空才能出栈
	if (!isEmpty(stack)) {		
		Node top = stack.stackTop;//栈顶元素		
		stack.stackTop = top.next; // 栈顶指针指向下一个节点
		System.out.println("出栈的元素是:" + top.data);
	}
}

2.1.6 清空栈

含义:删除所有元素。
栈顶指向栈底,就清空栈了。

public static void clearStack(Stack stack) {
	stack.stackTop = null; // 栈顶置空
	stack.stackBottom = stack.stackTop; // 栈底指向栈顶。
}

2.2 队列

使用数组来实现静态队列,往往实现静态队列,我们都是做成循环队列。
做成循环队列的好处是不浪费内存资源!
在这里插入图片描述
注意:
1、初始值,front = 0,rear = 0;
2、非循环队列时:入队时,rear++。出队时,front++。
3、数组长度 >= 队列长度 + 1
4、循环队列时:入队时,(rear+1)% arr.length。出队时,(front + 1) % arr.length。

2.2.1 创建队列类

Queue.java

public class Queue {    
    public int [] arrays; // 数组    
    public int front; // 指向第一个有效的元素    
    public int rear; // 指向有效数据的下一个元素(即指向无效的数据)
}
// rear并不指向最后一个有效的元素。目的:让我们分得清队头和队尾。

2.2.2 初始化队列

此时队列为空,分配了6个长度给数组(只能装5个实际的数字,rear指向的是无效的位置的)

public static void main(String[] args) {
	//初始化队列
	Queue queue = new Queue();
	queue.front = 0;
	queue.rear = 0;
	queue.arrays = new int[6];
}
// 注意:此处数组长度虽然为6,但只能装5个实际数字。
// 注意:一般情况下,队列的长度 != 数组的长度。满员时,队列的长度 + 1 = 数组的长度。原因rear指向的是无效的位置的。

2.2.3 遍历

只要front节点不指向rear节点,那么就可以一直输出

public static void traverseQueue(Queue queue) {	
	int i = queue.front;// front的位置
	while (i != queue.rear) {
		System.out.println("元素的值" + queue.arrays[i]);		
		i = (i + 1) % queue.arrays.length;//移动front
	}
}

2.2.4 判断

队列满员状态:如果rear指针和front指针紧挨着,那么说明队列就满了。
队列为空状态:只要rear和front指针指向同一个位置,那该队列就是空的了

// 队列是否满了。
public static boolean isFull(Queue queue) {
	boolean result = ((queue.rear + 1) % queue.arrays.length == queue.front)? true:false;
	return result;
}
// 队列是否为空
public static boolean isEmpty(Queue queue) {
	return (queue.rear  == queue.front) ? true:false;
}

2.2.4 入队

1、判断该队列是否满了。
2、入队的值插入到队尾中(具体的位置就是rear指针的位置)。
3、rear指针移动,再次指向无效的元素位置。

public static void enQueue(Queue queue,int value) {
	// 不是满的队列才能入队
	if (!isFull(queue)) {
		// 将新的元素插入到队尾中
		queue.arrays[queue.rear] = value;
		// rear节点移动到新的无效元素位置上
		queue.rear = (queue.rear + 1) % queue.arrays.length;
	}
}

2.2.6 出队

1、判断该队列是否为null
2、如果不为null,则出队,只要front指针往后面移就是出队了!

public static void outQueue(Queue queue) {
	if (!isEmpty(queue)) {
		int value = queue.arrays[queue.front];
		System.out.println("出队的元素是:" + value);
		// front指针往后面移
		queue.front = (queue.front + 1) % queue.arrays.length;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值