算法(二)栈,数组实现

P132-P142 栈,数组实现
Implementing Collections
定长栈(fixed-capacity stack)

public class FixedCapacityStackOfStrings
{
	private String[] a; // stack entries
	private int N; // size
	public FixedCapacityStackOfStrings(int cap)
	{ a = new String[cap]; } //构造函数,需要指定长度,不支持iteration
	public boolean isEmpty() { return N == 0; }
	public int size() { return N; }
	public void push(String item)
	{ a[N++] = item; }
	public String pop()
	{ return a[--N]; }
}

开发一个API的实现最主要的就是选择一种数据结构
使用数组实现非常简单,

  1. 所有的item都保持在他们插入的位置
  2. N=0的时候栈为空
  3. 栈顶 在 a[N-1] 的地方
    优点:push 和 pop 与数组的大小无关

缺点

  1. 泛型:之前的这个只能使用 String,现在我们需要使用泛型来提高它的通用性
public class FixedCapacityStack<Item>
{
private Item[] a; // stack entries
private int N; // size
public FixedCapacityStack(int cap)
{ a = (Item[]) new Object[cap]; } //历史遗留问题,不能直接新建一个 new Item[]
public boolean isEmpty() { return N == 0; }
public int size() { return N; }
public void push(Item item)
{ a[N++] = item; }
public Item pop()
{ return a[--N]; }
}
  1. 数组大小调整
    选择数组来表示stack,暗示客户端必须估计好最大的栈大小。我们不能改变一个数组的长度。
 public void resize(int N) {
        Item[] resizedItems = (Item[]) new Object[N];
        for (int i = 0; i < a.length; i++) {
            resizedItems[i] = a[i]; //copy the data from member a to resizedItem
        }
        a = resizedItems; //link the resized Items to a;
    }

这段代码不难理解,把a里面的元素复制给一个临时变量。然后把临时变量的引用再还给a。

  1. Iteration
    迭代
    例子:使用 foreach 来遍历一个集合
Stack<String> collection = new Stack<String>();
...
for (String s : collection)
StdOut.println(s);
...

例子:使用迭代器,应该可以取得与foreach相同的效果

Iterator<String> i = collection.iterator();
while (i.hasNext())
{
String s = i.next();
StdOut.println(s);
}

要使用迭代器:
我们必须要有两个条件:
1. 必须实现了, iterable 接口,能够返回一个 Iterator 对象

 public interface Iterable<Item>
{
Iterator<Item> iterator(); //自己创造的集合类,需要实现这个接口,返回一个Iterator对象
}

2. Iterator 对象必须有 hasNext, next() 实现了 Iterator 接口

public Iterator<Item> iterator()
{ return new ReverseArrayIterator(); } //stack必须要反向输出

public interface Iterator<Item> // 所有的迭代器需要实现这个接口
{
boolean hasNext();
Item next();
void remove();
}

实现了 Iterable 接口的好处,我们可以使用foreach而不需要关心数据结构的内部实现。这可以让我们改变实现的类型,而不需要改变我们客户端的代码。
例子, collection a 和 collection b全部都实现了 Iterable 接口,客户端的代码都是遍历返回的集合。当我们的实现从A 换到 B 的时候我们不需要改变客户端的for each。因为他们都实现了Iterable接口。

Algorithm 1.1

import java.util.Iterator;

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

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

        public int size() {
            return N;
        }

        private void resize(int max) { // Move stack to a new array of size 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) { // Add item to top of stack.
            if (N == a.length) resize(2 * a.length);
            a[N++] = item;
        }

        public Item pop() { // Remove item from top of stack.
            Item item = a[--N]; //书上的例子应该有一些问题,这里我们应该先需要判断是不是可以pop?
            a[N] = null; // Avoid loitering (see text).
            if (N > 0 && N == a.length / 4) resize(a.length / 2);
            return item;
        }

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

        private class ReverseArrayIterator implements Iterator<Item> { // Support LIFO iteration.
            private int i = N;

            public boolean hasNext() {
                return i > 0;
            }

            public Item next() {
                return a[--i];
            }

            public void remove() {
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值