栈的定义
栈是计算机科学中非常基础和重要的一种数据结构,它在计算机相关领域中有着广泛的应用,典型的编程语言中的函数调用,编译器便是采取栈这种结构来组织环境的。数据结构就是数据的组织方式,不同的组织方式,对于集合中元素的选取存在差异。
实现
package org.util.ds;
import java.util.Random;
/** * 栈 * @author Weibing Long * @since 2018.04.16 * @param <Item> 泛型 */
public class Stack<Item> {
private Node root; // 根节点
private int n; // 栈元素个数
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
Random random = new Random();
System.out.println("进栈");
for (int i = 0; i < 100; i++) {
int x = random.nextInt();
stack.push(x);
System.out.println(x);
}
System.out.println("出栈");
while (stack.size() > 0)
System.out.println(stack.pop());
}
/** * 进栈 * @param item 进栈元素 */
public void push(Item item) {
if (item == null)
throw new NullPointerException("参数不能为空");
if (root == null) {
root = new Node();
root.item = item;
root.next = root;
} else {
Node temp = root;
root = new Node();
root.item = item;
root.next = temp;
}
n++;
}
/** * 出栈 * @return 出栈元素 */
public Item pop() {
if (n == 0)
throw new NullPointerException("栈中元素为空!");
Item item = root.item;
root = root.next;
n--;
return item;
}
/** * 栈中元素的个数 * @return 元素个数 */
public int size() {
return n;
}
// 定义节点
private class Node {
private Item item;
private Node next;
}
}
一些细节
代码中定义了节点类
private class Node {
private Item item;
private Node next;
}
然后利用单链表来实现,节点的定义体现了单链表结构,即值与指向另一个节点的指针(这里用引用
更恰当,但其他资料一般说为指针
)。
至于本代码是头插法还是尾插法我也不区别了,因为关键在于理解内部原理和区分引用
和在内存中的对象
,不然容易报空指针异常。
同时,代码使用的泛型这一高级属性,提高了代码的重用率,可以包容几乎所有的对象。当然,所有的对象类型必须一致。
实现二
上面的代码是基于单链表的栈实现,下面是基于数组的实现:
/** * 数组实现 * @author Wee bing * @param <Item> */
public class MyStack<Item> {
private Object[] myArray = null;//元素容器
private int capacity = 0;//元素容量
private int n = 0;//元素个数
public MyStack() {
capacity = 2;
myArray = new Object[capacity];
}
public MyStack(int capacity) {
this.capacity = capacity;
myArray = new Object[capacity];
}
//插入元素
public void push(Item item) {
if (n >= capacity/2) {
capacity *= 2;
Object[] temp = new Object[capacity];
for (int i = 0; i < capacity/2; i++)
temp[i] = myArray[i];
myArray = temp;
}
myArray[n++] = item;
}
public Item peek() {
if (n == 0)
return null;
Item item = (Item) myArray[n-1];
return item;
}
//删除元素
public Item pop() {
if (isEmpty()) throw new NullPointerException();
Item item = (Item) (myArray[--n]);
myArray[n] = null;
return item;
}
//元素个数
public int size() {
return n;
}
//是否为空
public boolean isEmpty() {
return n == 0;
}
//测试
public static void main(String[] args) {
}
}
https://blog.csdn.net/github_37412255/article/details/69202769 是这个代码一开始的文章,我不想把这个文章删了(原因:又少了10个积分 哈哈),又想将两种方法放到一块,所以放在这里了。