栈和队列的api设计及代码实现

栈和队列都是数据结构中最常见的结构,本篇我们使用java代码的方式实现栈和队列这两种数据结构。

一、栈

1、栈的特点

栈的特点是先入后出,这是因为栈的存取数据入口只有一个(用一个头指针实现)。故先入栈的元素放入栈底部,后入栈的元素放到栈顶部。向栈中存入一个元素的操作叫做压栈(push),从栈顶中取出一个元素的操作叫做弹栈(pop)。

2、栈的api设计

类名:Stack<T> (物理上基于链表)
构造方法: Stack()
成员方法:
public void push(T t) 向栈中放入一个元素
public T pop() 从栈中取出一个元素
public int size() 获取长度
public boolean isEmpty() 判断是否为空

3、栈的java代码实现

package com.tingcream.alg.linear;
 
import java.util.Iterator;
 
/**
 * 栈的api设计 (物理上采用链表来实现栈)
 */
public class Stack<T> implements  Iterable<T>{
    private Node head;//头结点
    private int N;//链表长度
 
    //构造方法
    public Stack(){
        this.head=new Node(null,null);
        this.N=0;
    }
 
    //压栈
    public void push(T t){
        //找到第一个节点
        Node<T> oldFirst=head.next;
        Node<T>  newNode=new Node(t,null);
        newNode.next=oldFirst;
        head.next=newNode;
 
        N++;
    }
 
    //弹栈
    public T pop(){
        Node<T> oldFirst=  head.next;
        if(oldFirst==null){
            return null ;
        }
        head.next=oldFirst.next;
        N--;
        return oldFirst.item;
    }
 
    //获取长度
    public int size(){
        return this.N;
    }
    //判断是否为空
    public boolean isEmpty(){
        return this.N==0;
    }
    @Override
    public Iterator<T> iterator() {
        return new Itr();
    }
 
    private class Itr implements Iterator{
 
        private Node n;
 
        public Itr(){
            this.n=head;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }
 
        @Override
        public Object next() {
            n=n.next; //n指针向后移动一步
            return n.item;
        }
    }
 
    private class Node<T> {
        private  T  item;
        private  Node next;
        public  Node(T item,Node next){
            this.item=item;
            this.next=next;
        }
    }
}

4、测试代码

public class StackTest {
    public static void main(String[] args) {
        Stack<String> stack=new Stack<>();
        stack.push("a");
        stack.push("b");
        stack.push("c");
        stack.push("d");
        for(String s: stack){
            System.out.println(s);
        }
        System.out.println("============");
        String s1= stack.pop();
        System.out.println("弹出:"+s1);//d
        System.out.println("剩余长度:"+stack.size());//3
    }
}

二、队列

1、队列的特点

队列的特点是先入先出(FIFO) ,这是因为队列有两个操作的入口(用头指针和尾指针实现),头指针由于插入新元素(入队),尾指针用于取出元素(出队)队里中插入新元素的操作叫做入队(equeue),队列中去除一个元素的操作叫做出队(dequeue)

2、队列的api设计

类名: Queue<T>   (物理上使用链表实现)
构造方法: Queue()
成员变量: 
private Node head 头结点
private Node last 尾节点
private int N 链表数量
成员方法:
public void enqueue(T t)  入队
public T dequeue() 出队
public int size() 获取长度
public boolean isEmpty() 判断是否为空

3、队列的java代码实现

package com.tingcream.alg.linear;
 
import java.util.Iterator;
 
/**
 * 队列 (物理上使用链表实现)
 */
public class Queue<T> implements Iterable<T>{
    private Node head;//头结点
    private Node last;//最后一个节点
    private int N;//链表数量
 
 
    public Queue(){
        this.head=new Node(null,null);
        this.last=null;
        this.N=0;
    }
 
    //队列是否为空
    public boolean isEmpty(){
        return this.N==0;
    }
    //队列中元素数量
    public int size(){
        return this.N;
    }
 
    //入队 加入一个元素
    public void enqueue(T t){
        //如果当前尾结点为null,
        if(last==null){
            last=new Node(t,null);
            head.next=last;
        }else{
          // 当前尾结点不为null
            Node oldLast=  last;
            last= new Node(t,null);
            oldLast.next=last;
        }
        N++;
 
    }
 
    //出队  取出一个元素
    public T dequeue(){
       if(isEmpty()){
           return null;
       }
       Node<T> oldFirst=head.next;
       head.next=oldFirst.next;
       N--;
 
       //如果队列中所有数据节点被删除完了,需要重置last节点为null
       if(isEmpty()){
           last=null;
       }
        return oldFirst.item ;
    }
 
 
 
    @Override
    public Iterator<T> iterator() {
        return new Itr();
    }
 
    //内部类 迭代器
    private  class Itr implements Iterator<T>{
        private Node<T> n;
 
        public Itr(){
            this.n=head;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }
 
        @Override
        public T next() {
            n=n.next;//n指针向后移动一步
            return n.item;
        }
    }
 
 
 
    private class Node<T> {
        private  T  item;
        private  Node next;
        public  Node(T item,Node next){
            this.item=item;
            this.next=next;
        }
    }
 
}

4、测试代码


import com.tingcream.alg.linear.Queue;


public class QueueTest {
    public static void main(String[] args) {
        Queue<String> queue=new Queue<String>();
        queue.enqueue("a");
        queue.enqueue("b");
        queue.enqueue("c");
        queue.enqueue("d");

        //由于Queue类中实现了iterator接口,故可以使用for遍历
        for(String s:queue){
            System.out.println(s);
        }
        System.out.println("===========");

        String s1=queue.dequeue();
        String s2=queue.dequeue();

        System.out.println("s1:"+s1);//a
        System.out.println("s2:"+s2);//b
        System.out.println("剩余元素个数:"+queue.size());//2个
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章