zoukankan      html  css  js  c++  java
  • 背包,队列,栈的java实现

    先从栈开始实现,从简单开始,栈的特点是先进后出LIFO,应该具有的操作有:入栈push 出栈pop,判断栈是否为空isEmpty和返回栈大小size,使用java中最简单的数组实现字符串栈为开始:

    public class FixCapacityStringStack{
        private String[] str = null;
        private int n = 0;
        public FixCapacityStringStack(int m){
            str = new String[m];
        }
        public boolean isEmpty(){
            return n == 0;
        }
        public int size(){
            return n;
        }
        public void push(String s){
            str[n++] = s;
        }
        public String pop(){
            return str[--n];
        }
    }
    这样的字符串栈仅能简单体现栈的基本功能,不可避免的有很多缺陷,首先由于固定类型只能存储字符串对象,其他对象无法复用,应该定义一个所有对象都能通用的通用栈,可以用java的泛型实现:
    public class FixCapacityStack <Item>{
        private Item[] stack = null;
        private int N = 0;
        public FixCapacityStack(int m){
            stack = (Item[]) new Object[m];
          //stack = new Item[m];//waring:Cannot create a generic array of Item    
        }
        public boolean isEmpty(){
            return N == 0;
        }
        public int size(){
            return N;
        }
        public void push(Item item){
            stack[N++] = item;
        }
        public Item pop(){
            return stack[--N];//此处对象游离
        }
    }
    数组实现的泛型定容栈虽然解决了对象通用问题,但很多细节的实现仍然很粗糙,比如数组的大小固定,创建后就无法改变,出栈操作对象游离,虽然对象已出栈,但仍然在数组中,应该不保留出栈对象句柄,让此对象等待垃圾回收等等。
    于是我们需要用数组实现一个对所有对象通用,并且能够动态调整数组大小,实现无上界的栈,同时对出栈对象及时消除句柄的栈,另外,作为集合对象类型,这样的栈应该支持迭代遍历栈中所有数据元素。
    关于调整数组大小,可以采用这样的方式:
    如果入栈后判断数组已满,则创建一个新数组,此数组长度为原数组的两倍,将原数组复制到新数组。
    如果出栈后判断栈的长度小于数组长度的四分之一,则将创建新数组为原数组长度的一半,复制原数组到新数组。
    如此以数组为原型的栈不会溢出,同时,栈的使用率永远不会低于四分之一,不会造成空间浪费。
    如果要迭代遍历集合元素,类似其他集合类实现Iterable接口,实现iterator方法返回迭代器对象,迭代器对象应是一个实现hasNext,next,remove方法,操作栈对象。可以实现为内部类。
    import java.util.Iterator;

    public class ReizeArrayStack<Item> implements Iterable<Item>{
        private Item[] stack = null;
        private int N = 0;
        public ReizeArrayStack(){
            stack = (Item[])new Object[1];
        }
        public boolean isEmpty(){
            return N == 0;
        }
        public int size(){
            return N;
        }
        public void push(Item item){
            if(N == stack.length){
                resize(2*stack.length);
            }
            stack[N++] = item;
        }
        public Item pop(){
            Item temp =  stack[--N];
            stack[N] = null;//出栈对象及时清除,无引用对象等待回收。
            if(N == stack.length/4){
                resize(stack.length/2);
            }
            return temp;
        }
        public void resize(int max){//重新调整数组大小
            Item[] temp = (Item[])new Object[max];
            for(int i =0;i<N;i++){
                temp[i] = stack[i];
            }
            stack = temp;
        }
        @Override
        public Iterator<Item> iterator() {
            // TODO Auto-generated method stub
            return new ReizeArrayStackIterator();
        }
        private class ReizeArrayStackIterator implements Iterator<Item>{
            private int i = N;
            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return i > 0;
            }
            @Override
            public Item next() {
                // TODO Auto-generated method stub
                return stack[--i];
            }

            @Override
            public void remove() {
                // TODO Auto-generated method stub
            }
        }
    }
    如果使用链表实现栈,可以方便的多,链表实现栈达到了最优的设计目的:
    可以处理任何数据类型;
    所需空间和集合大小成正比;
    操作所需的时间和集合的大小无关;(因为总是表头插入删除)
    import java.util.Iterator;
    public class ListStack<Item> implements Iterable<Item> {
        public Node first;
        public int N = 0;
        private class Node{
            public Item item;
            public Node next;
        }
        public boolean isEmpty(){
            return N == 0;
        }
        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 temp = first.item;
            first = first.next;
            N--;
            return temp;
        }
        @Override
        public Iterator<Item> iterator() {
            // TODO Auto-generated method stub
            return null;
        }
        private class ListStackIterator implements Iterator<Item>{
            private Node current = first;
            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return current != null;
            }

            @Override
            public Item next() {
                // TODO Auto-generated method stub
                Item temp = current.item;
                current = current.next;
                return temp;
            }
            public void remove() {}   
        }
    }
    队列的链表实现也如此类似(FIFO):
    public class ListQueue <Item>{
        private Node first = null;
        private Node last = first;
        private int N = 0 ;
        private class Node{
            public Item item;
            public Node next;
        }
        public boolean isEmpty(){
            return first == last;
        }
        public int size(){
            return N;
        }
        public void enqueue(Item item){
            last = new Node();
            last.item = item;
            last.next = null;
            last = last.next;
            N++;
        }
        public Item dequeue() {
            if (!isEmpty()) {
                Item temp = first.item;
                first = first.next;
                N--;
                return temp;
            }
            else return null;
        }
    }
    背包是一种不支持从中删除元素的集合数据类型,目的是帮助用例收集数据元素,并迭代遍历所有收集到的元素,迭代顺序不确定。用例可以检查背包是否为空或者获取背包中元素的数量。
    import java.util.Iterator;

    public class ListBag <Item> implements Iterable<Item>{
        private Node first;
        private class Node{
            Item item;
            Node next;
        }
        public void add(Item item){
            Node oldfirst = first;
            first = new Node();
            first.item = item;
            first.next = oldfirst;
        }
        @Override
        public Iterator<Item> iterator() {
            // TODO Auto-generated method stub
            return new ListBagIterator();
        }
        private class ListBagIterator implements Iterator<Item>{
            private Node current = first;
            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return current == null;
            }
            @Override
            public Item next() {
                // TODO Auto-generated method stub
                Item temp = current.item;
                current = current.next;
                return temp;
            }
            @Override
            public void remove() {}
           
        }
    }

  • 相关阅读:
    网上搜索整理的前端开发工程师面试题附答案
    Python-RabbitMQ-topic(细致消息过滤的广播模式)
    Python-RabbitMQ-direct(广播模式)
    Python-RabbitMQ-fanout(广播模式)
    rabbitmq中关于exchange模式type报错
    Python-RabbitMQ(持久化)
    Python-RabbitMQ(简单发送模型)
    python-gevent模块实现socket大并发
    python-gevent模块(自动切换io的协程)
    python-greenlet模块(协程)
  • 原文地址:https://www.cnblogs.com/brucemu/p/3113451.html
Copyright © 2011-2022 走看看