前言
栈、队列、背包都是基本的数据结构,栈遵循LIFO(后进先出的原则),队列遵循FIFO(先进先出)。背包类似栈,但是不像队列和栈一样强调顺序,并且,只进不出,用于不强调顺序的集合。
栈
java中存在栈的数据结构,但是不推荐使用,其也实现了从栈尾添加的功能,宽接口
设置,并不符合栈的特点。
import java.util.Iterator;
// 使类可迭代需添加Iterable接口
public class ResizingArrayStack<Item> implements Iterable<Item>{
private Item[] a;
private int N;// size
public ResizingArrayStack(int cap){
a = (Item[]) new Object[cap];
}
public void resize(int length){
// java中没有泛型数组,只有转化
Item[] temp = (Item[]) new Object[length];
for(int i=0;i<N;i++){
temp[i] = a[i];
}
a = temp;
}
public void push(Item item){
if(N==a.length) resize(2*a.length);
a[N++] = item;
}
public Item pop(){
Item result = a[--N];
a[N] = null;// 垃圾回收
if(N>0&&N<a.length/4) resize(a.length/2);
return result;
}
public boolean isEmpty(){
return N==0;
}
public int size(){
return a.length;
}
@Override
public Iterator<Item> iterator() {
return new ReverseArrIterator();
}
public class ReverseArrIterator implements Iterator<Item>{
private int i = N;
@Override
public boolean hasNext() {
return i>0;
}
@Override
public Item next() {
return a[--i];
}
@Override
public void remove() {
}
}
public static void main(String[] args){
ResizingArrayStack<Integer> stack = new ResizingArrayStack<>(10);
stack.push(5);
stack.push(8);
stack.push(9);
StdOut.println("stack pop:"+stack.pop());
for(Integer i:stack){
StdOut.println("stack foreach:"+i);
}
}
}
上述栈结构强调内存控制,通过resize
方法动态改变栈的大小
import java.util.Iterator;
// 下压堆栈(链表实现)
public class Stack<Item> implements Iterable<Item>{
private Node first;
private int N;
@Override
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item>{
private Node current = first;
@Override
public boolean hasNext() {
return current!=null;
}
@Override
public Item next() {
Item item = current.item;
current = current.next;
return item;
}
@Override
public void remove() {
}
}
private class Node{
Item item;
Node next;
}
public boolean isEmpty(){
return first == null;
}
public int size(){
return N;
}
public void push(Item item){
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
}
public Item pop(){
Item item = first.item;
first = first.next;
N--;
return item;
}
public static void main(String[] args){
Stack<Integer> stack = new Stack<>();
stack.push(3);
stack.push(5);
stack.push(8);
StdOut.println("stack size:"+stack.size());
for(Integer i:stack){
StdOut.println("foreach:"+i);
}
while (!stack.isEmpty()){
StdOut.println("stack iterator"+stack.pop());
}
}
}
上述栈结构通过链表的形式实现,引用first保存头结点,即栈顶结点
队列
队列使用链表实现,first和last结点分别保存头结点和尾结点,头结点实现出队列功能,尾结点实现入队列功能,需要注意的是,当只有一个结点时first和last需要指向同一结点,当没有结点时,first和last均需指向null
import java.util.Iterator;
// 队列链表实现 先进先出 first 保存头结点 last 保存尾结点
public class Queue<Item> implements Iterable<Item>{
private int N;// size
private Node first;// first Node
private Node last;// last Node
@Override
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item>{
private Node current = first;
@Override
public boolean hasNext() {
return current!=null;
}
@Override
public Item next() {
Item item = current.item;
current = current.next;
return item;
}
@Override
public void remove() {
}
}
private class Node{
Item item;
Node next;
}
public int size(){
return N;
}
public boolean isEmpty(){
return first == null;
}
public void enQueue(Item item){
Node oldlast = last;
last = new Node();
last.item = item;
// 如果first 为null 代表现在是唯一的结点,first = last
if(isEmpty()) first = last;
else oldlast.next = last;
N++;
}
public Item deQueue(){
Item item = first.item;
first = first.next;
// 如果first为空,则last需要为null
if(isEmpty()) last = null;
N--;
return item;
}
public static void main(String[] args){
Queue<Integer> queue = new Queue<>();
queue.enQueue(5);
queue.enQueue(8);
queue.enQueue(10);
StdOut.println("queue size:"+queue.size());
while (!queue.isEmpty()){
StdOut.println("queue deQueue:"+queue.deQueue());
}
}
}
背包
背包类似与栈结构,但是没有出栈功能,并且不强调顺序的作用性
import java.util.Iterator;
// 背包,类似与Stack,但是不强调迭代顺序,且只进不出
public class Bag<Item> implements Iterable<Item>{
private int N;// size
private Node first;// first Node
private class Node{
Item item;
Node next;
}
@Override
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item>{
private Node current = first;
@Override
public boolean hasNext() {
return first!=null;
}
@Override
public Item next() {
Item item = first.item;
first = first.next;
return item;
}
@Override
public void remove() {
}
}
public void add(Item item){
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
}
public boolean isEmpty(){
return first == null;
}
public int size(){
return N;
}
public static void main(String[] args){
Bag<Integer> bag = new Bag<>();
bag.add(3);
bag.add(5);
bag.add(8);
StdOut.println("size:"+bag.size());
for(Integer i:bag){
StdOut.println("foreach:"+i);
}
}
}