JAVA定义数组与链表_栈的Java实现-分别使用数组和链表

栈是非常重要的数据结构,栈具有后进先出的特点。

在JVM内部,每个线程维护一个栈,对于每个方法调用,入栈一个元素,成为栈帧,当方法执行完成后,对应的栈帧出栈。

栈帧中,也包含一个栈,称为操作数栈。

一、定义栈

public interface Stack {

// 添加一个元素

void push(Item item);

// 删除最近添加的元素

Item pop();

// 栈是否为空

boolean isEmpty();

// 栈中的元素数量

int size();

}

二、数组实现

/**

* 数组实现

* @param

*/

public class ResizingArrayStack implements Stack, Iterable {

private Item[] a;

// 表示栈实际大小

int N;

/**

* 初始的数组容量为16

*/

public ResizingArrayStack(){ this(16); }

public ResizingArrayStack(int cap){ a = (Item[]) new Object[cap]; }

@Override

public void push(Item item) {

if(N == a.length) resize(2 * N);

a[N++] = item;

}

/**

* 扩容,每次扩2倍的空间

* @param size

*/

private void resize(int size) {

if(size <= 16){

return;

}

System.out.println("触发扩容,原容量: " + a.length + ", 扩容后:" + size);

Item[] temp = (Item[]) new Object[size];

for (int i = 0; i < N; i++) {

temp[i] = a[i];

}

a = temp;

}

@Override

public Item pop() {

if(N == a.length / 4) resize(a.length / 2);

return a[--N];

}

@Override

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

@Override

public int size() { return N; }

// *********** 以下代码与算法实现无关,仅为方便测试使用 *************

@Override

public Iterator iterator() {

return new Iterator() {

private int i = N;

@Override

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

@Override

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

@Override

public void remove() { }

};

}

public void print(){

System.out.print("当前元素(自栈顶至栈底):\t");

Iterator iterator = iterator();

while (iterator.hasNext()){

System.out.print(iterator.next() + "\t");

}

System.out.println();

}

}

三、链表实现

/**

* 链表实现

* @param

*/

public class LinkStack implements Stack, Iterable {

private Node top;

private int N;

private class Node{ Item item;Node next;}

/**

* 入栈

* @param item

*/

@Override

public void push(Item item) {

Node node = new Node();

node.item = item;

node.next = top;

top = node;

N++;

}

/**

* 出栈

* @return

*/

@Override

public Item pop() {

Item item = top.item;

top = top.next;

N--;

return item;

}

@Override

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

@Override

public int size() { return N; }

//*********** 以下代码与算法实现无关,仅为方便测试使用 *************

@Override

public Iterator iterator() {

return new Iterator() {

Node temp = top;

@Override

public boolean hasNext() {

return temp != null;

}

@Override

public Item next() {

Item item = temp.item;

temp = temp.next;

return item;

}

};

}

public void print(){

System.out.print("当前元素(自栈顶至栈底):\t");

Iterator iterator = iterator();

while (iterator.hasNext()){

System.out.print(iterator.next() + "\t");

}

System.out.println();

}

}

四、测试结果

public class StackTest {

@Test

public void arrayStackTest(){

// ResizingArrayStack stack = new ResizingArrayStack<>();

LinkStack stack = new LinkStack<>();

System.out.print("初始化后, ");

stack.print();

String pop;

//压入元素to

System.out.print("入栈:to,");

stack.push("to");

stack.print();

//压入元素be

System.out.print("入栈:be,");

stack.push("be");

stack.print();

//压入元素or

System.out.print("入栈:or,");

stack.push("or");

stack.print();

//压入元素not

System.out.print("入栈:not,");

stack.push("not");

stack.print();

//压入元素to

System.out.print("入栈:to,");

stack.push("to");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//压入元素be

System.out.print("入栈:be,");

stack.push("be");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//压入元素that

System.out.print("入栈:that,");

stack.push("that");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//弹出元素

pop = stack.pop();

System.out.print("出栈:" + pop + ",");

stack.print();

//压入元素is

System.out.print("入栈:is,");

stack.push("is");

stack.print();

}

@Test

public void test2(){

ResizingArrayStack stack = new ResizingArrayStack<>();

for (int i = 0; i < 100; i++) {

stack.push(i);

}

}

}

测试结果如下:

test1

930bcde10cc5d3898e32616548f301e7.png

test2

18fed96724d9812b002b389e569f6498.png

五、多说一点

在网上搜索数组和链表的区别时,最常见的说法是:数组访问较快,插入操作较慢;链表访问操作慢,修改便捷。

在实现栈时,由于栈仅涉及在最后插入一个值、在最后删除一个值,所以在这里比较2种实现方式优劣时,不能按照上述方式描述。

个人认为,数组实现,劣势在于需要扩容操作;链表实现,需要额外维护一个指向next的链接,占用更多空间;总体来说,2种实现方式优劣不明显,均比较合适。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值