队列与栈的基本操作
最近开了算法四的坑,在基本了解了java的特性后就开始看书了,也就当复习一边上学期的数据结构。在学校里都是用C语言写的数据结构,突然换成Java有一点不适应,也还有很多需要注意的小细节。这里栈和队列都是链表实现。
链表是一种递归的数据结构,它或则为空(null),或者是指向一个结点(node)的引用,该结点含有一个泛型(Item)的元素和一个指向另一条链表的引用。
栈
栈主要是入栈与出栈,把握住后入先出的原则,后面入栈的元素需要一个栈顶指针来对其引用。注意在出栈前需要判断栈是否为空。
public class MyStack<Item> {
private Node first; //栈顶引用,默认为null
private int N;
public class Node{ //成员内部类对应着C语言中的结点结构体
Node next;
Item node;
}
public boolean isEmpty()
{
return first == null;
}
public int size()
{
return N;
}
public void push(Item item)
{
Node oldFirst = first; //创建oldFirst保存当前栈顶引用
first = new Node(); //给要入栈的元素创建对象
first.node = item;
first.next = oldFirst; //原栈顶元素被添加到新元素的后面
N++;
}
public Item pop()
{
N--;
Item item = first.node;
first = first.next;
return item;
}
public MyStack() {
}
}
队列
队列由于需要首尾两个引用来操控,比栈的实现稍微麻烦一些。队列是先入先出的原则,在出队时也得判断一下队列是否为空。
public class MyQueue<Item>{
private Node head; //默认为null
private Node last;
private int N; //默认为0
public class Node
{
Item item;
Node next;
}
public MyQueue() {
}
public boolean isEmpty()
{
return head == null;
}
public int size()
{
return N;
}
public void enQueue(Item item)
{
Node oldLast = last;
last = new Node();
last.item = item;
last.next = null;
//如果是第一次入队,oldLast为null,oldLast.next就没有意义了(会报错)
//所以直接让last和head指向新元素即可。
if(isEmpty()){
head = last;
}
else {
oldLast.next = last;
}
N++;
}
public Item deQueue()
{
N--;
Item item = head.item;
head = head.next;
//当栈为空,设置last =null,java会主动释放这些内存,加速JVM回收
if(isEmpty()){
last = null;
}
return item;
}
}
测试:
代码中使用算法四作者提供的StdIn和StdOut标准库,需要的小伙伴可以用网盘下载然后导入即可algs4.jar
提取码:yhzz。
两段代码的测试部分我放在一起,大家可以选取一部分来测试。
最后需要我们手动退出循环体,Ctrl+D即可,同时会打印出我们数据结构中剩余的元素个数。
public class Func {
public static void main(String[] args) {
MyStack<String> myStack = new MyStack<>();
while(!StdIn.isEmpty())
{
String item = StdIn.readString();
if(!item.equals("-"))
{
myStack.push(item);
}
else if(!myStack.isEmpty())
{
StdOut.print(myStack.pop()+" ");
}
}
StdOut.println("("+myStack.size()+" left on stack)");
------------------------------------------------------------------
MyQueue<String>myQueue = new MyQueue<>();
while(!StdIn.isEmpty())
{
String item = StdIn.readString();
if(!item.equals("-"))
{
myQueue.enQueue(item);
}
else if(!myQueue.isEmpty())
{
StdOut.print(myQueue.deQueue()+" ");
}
}
StdOut.println("("+" "+myQueue.size()+" letf on queue)");
}
}