【算法】栈的实现(能够动态调节数组大小实现)

        看完了《算法(第四版)》中对栈这种数据结构的实现,记录一下。

        实现栈的思路如下::

        首先实现两个基本的属性,一个泛型数组用来储存栈元素,一个整型数据用来记录栈中的元素数量:

    private Item[] a = (Item[]) new Object[1];
    private int N = 0;

        之后实现两个比较基本的成员方法,isEmpty用来判断栈是否为空,size用来返回栈中元素的个数:

    public boolean isEmpty()
    {
        return N == 0;
    }

    public int size()
    {
        return N;
    }

        为了实现动态调节数组大小,添加一个reSize方法用来改变栈的容量:

  private void reSize(int max)
    {
        Item[] temp = (Item[]) new Object[max];
        for (int i = 0; i < N; i++)
        {
            temp[i] = a[i];
        }
        a = temp;
    }

        通过实现push和pop方法实现压栈和出栈的操作,在入栈时对栈的元素数量进行判断,如果栈满了,则自动扩充为原来两倍。出栈时,先要对出栈后的元素置空,避免对象游离,然后对栈中的元素数量进行判断,如果大于0且小于原容量的1/4,则将栈的容量减小为原先的一半,这样还可以留出比当前元素数量多一倍的空间进行使用,且不会造成空间浪费:

     public void push(Item item)
    {
        if (N == a.length)
        {
            reSize(a.length * 2);
        }
        a[N++] = item;
    }

    public Item pop()
    {
        Item temp = a[--N];
        a[N] = null;
        if (N > 0 && N < a.length / 4)
        {
            reSize(a.length / 2);
        }
        return temp;
    }

        最后要实现迭代功能,首先要继承Iterable<Item>接口,这个接口需要我们实现一个Iterator方法,这个方法需要一个Iterator<Item>类型的返回值,在栈的实现中我们需要对数组进行逆向遍历,所以我们封装一个继承自Iterator<Item>ReverseArrayIterator类,这是一个嵌套类,并且我们对其的remove置空,因为我们不想再迭代时候修改数据,最后让Iterator方法返回一个此类对象即可:

    private class ReverseArrayIterator 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()
        {
        }
    }

    @Override
    public Iterator<Item> iterator()
    {
        return new ReverseArrayIterator();
    }

        完整实现代码:

package Test;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

import java.util.Iterator;

public class ResizingArrayStack<Item> implements Iterable<Item>
{
    private Item[] a = (Item[]) new Object[1];
    private int N = 0;

    public boolean isEmpty()
    {
        return N == 0;
    }

    public int size()
    {
        return N;
    }

    private void reSize(int max)
    {
        Item[] temp = (Item[]) new Object[max];
        for (int i = 0; i < N; i++)
        {
            temp[i] = a[i];
        }
        a = temp;
    }

    public void push(Item item)
    {
        if (N == a.length)
        {
            reSize(a.length * 2);
        }
        a[N++] = item;
    }

    public Item pop()
    {
        Item temp = a[--N];
        a[N] = null;
        if (N > 0 && N < a.length / 4)
        {
            reSize(a.length / 2);
        }
        return temp;
    }


    private class ReverseArrayIterator 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()
        {
        }
    }

    @Override
    public Iterator<Item> iterator()
    {
        return new ReverseArrayIterator();
    }

    public static void main(String args[])
    {
        ResizingArrayStack<String> s = new ResizingArrayStack<>();
        while (!StdIn.isEmpty())
        {
            String item = StdIn.readString();
            if (!item.equals("-"))
            {
                s.push(item);
            } else if (!s.isEmpty())
            {
                StdOut.println(s.pop() + " ");
            }
        }
        StdOut.println("("+s.size()+"left on stack)");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值