栈接口定义:
public interface Stack<Item> {
/**
* 添加一个元素
* @param item
*/
public void push(Item item);
/**
* 获取最后一个添加的元素,并将其从栈中删除
* @return
*/
public Item pop();
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty();
/**
* 获取栈当前的元素个数
* @return
*/
public int size();
}
基于数组的实现:
import java.util.Iterator;
import com.mycode.algorithms.stack.Stack;
/**
* 基于数组的栈实现
* @author imhuqiao
*/
public class ArrayStack<Item> implements Stack<Item>,Iterable<Item> {
private Item[] data = null;
private int pos = -1;
public ArrayStack(){
this(10);
}
public ArrayStack(int initLength){
data = (Item[]) new Object[initLength];
}
@Override
public void push(Item item) {
pos++;
if(pos==data.length){
resize(data.length*2);
}
data[pos] = item;
//print();
}
private void print(){
System.out.print("[");
for(Item d : data){
System.out.print(d+",");
}
System.out.println("],pos="+pos);
}
@Override
public Item pop() {
if(isEmpty()){
return null;
}
Item item = data[pos];
data[pos] = null;
pos--;
if(pos > 0 && pos == data.length/4) resize(data.length/2);
//print();
return item;
}
@Override
public boolean isEmpty() {
return pos==-1;
}
@Override
public int size() {
return pos+1;
}
@Override
public Iterator<Item> iterator() {
return new ArrayStackIterator();
}
private void resize(int length){
Item[] newdata = (Item[]) new Object[length];
int i = 0;
for(Item item : data){
if(i<length){
newdata[i] = data[i];
data[i] = null;
}
i++;
}
data = newdata;
}
class ArrayStackIterator implements Iterator<Item>{
private int i = pos;
@Override
public boolean hasNext() {
return i>-1;
}
@Override
public Item next() {
Item result = data[i--];
return result;
}
@Override
public void remove() {
}
}
}
基于链表的实现:
import java.util.Iterator;
import com.mycode.algorithms.stack.Stack;
/**
* 基于链表的栈实现
* @param <Item>
*/
public class LinkStack<Item> implements Stack<Item>, Iterable<Item> {
private Node<Item> head;
private int count = 0;
public LinkStack(){
head = new Node<Item>();
}
@Override
public Iterator<Item> iterator() {
return new LinkStackIterator();
}
@Override
public void push(Item item) {
Node<Item> newNode = new Node<Item>();
newNode.data = item;
newNode.next = head;
head = newNode;
count++;
print();
}
@Override
public Item pop() {
Item data = head.data;
head = head.next;
count--;
print();
return data;
}
@Override
public boolean isEmpty() {
return count == 0;
}
@Override
public int size() {
return count;
}
private void print(){
Node<Item> node = head;
System.out.print("[");
while(node.next!=null){
System.out.print(node.data+",");
node = node.next;
}
System.out.println("]");
}
class Node<T>{
public T data;
public Node<T> next;
}
class LinkStackIterator implements Iterator<Item>{
private Node<Item> theHead;
private int theCount;
public LinkStackIterator(){
theHead = new Node<Item>();
theHead = head;
theHead.next = head.next;
this.theCount = count;
}
@Override
public boolean hasNext() {
return theCount>0;
}
@Override
public Item next() {
Item data = theHead.data;
theHead = theHead.next;
theCount--;
return data;
}
@Override
public void remove() {
}
}
}
测试代码:
@Test
public void testArrayStack(){
Stack<String> as = new ArrayStack<String>(1);
as.push("a");
as.push("b");
as.push("c");
Assert.assertEquals("c",as.pop());
String res = "";
for(String str : as){
res += str;
}
Assert.assertEquals("ba",res);
}
@Test
public void testLinkStack(){
Stack<String> ls = new LinkStack<String>();
ls.push("a");
ls.push("b");
ls.push("c");
Assert.assertEquals("c",ls.pop());
String res = "";
for(String str : ls){
res += str;
}
Assert.assertEquals("ba",res);
}
分享到:
相关推荐
数组适合于数据量固定、访问频率较高的场景,而链表则更适合于数据量动态变化较大、需要频繁插入和删除的场合。理解它们的区别有助于我们在实际开发中选择最合适的数据结构来解决问题。在选择合适的数据结构时,还...
在计算机科学中,数据结构是组织、存储和处理数据的方式,它们是算法设计的基础。...在实际编程中,Java提供了ArrayList和LinkedList两种内置的列表实现,分别基于数组和链表,可以根据需要选择使用。
因此,题目中提到的“链表-使用Python基于链表实现数组栈”就是将栈的特性与链表的高效插入和删除结合,创建一个更高效的栈数据结构。 为了实现基于链表的数组栈,我们需要定义一个Stack类,包含head(栈顶)属性和...
总结一下,顺序栈和链式栈都是实现栈这一数据结构的有效方法,它们各有优缺点。数组实现的顺序栈在访问效率上有优势,但可能受限于固定容量;而链表实现的链式栈虽然在空间上有一定开销,但能提供更灵活的大小调整。...
本压缩包"基于JAVA实现的常用数据结构代码"包含了多个关键的数据结构实现,包括复杂度分析、动态数组、链表、栈、队列以及二叉搜索树。以下是这些数据结构的详细说明: 1. **复杂度**:在计算机科学中,复杂度分为...
- **链表栈定义**:链表栈是一种基于链表结构的栈,每个节点包含数据和指针,使得数据在链表中按照后进先出的顺序排列。 - **链表栈操作**:链表栈的插入(入栈)和删除(出栈)操作都在链表的头部进行。新元素...
**基于动态数组的栈** 栈是一种特殊的线性数据结构,遵循“后进先出...在VS2017中,我们可以方便地编写、编译和测试这样的实现,从而加深对栈和动态数组的理解。然而,对于性能敏感的应用,可能需要考虑其他实现策略。
顺序栈是基于数组实现的栈,而链栈则是基于链表。对于顺序栈,当栈满时可能需要扩展数组,而链栈则没有这样的限制,可以在运行时动态增加节点。 对于队列的算法,考核内容是实现基本的队列操作,包括置空队列、入队...
本文将深入探讨一种常用的数据结构——栈,特别是顺序栈和链表栈,它们都是实现栈功能的不同方式。栈通常被称为“后进先出”(LIFO,Last In First Out)的数据结构,广泛应用于各种算法和程序设计中,如表达式求值...
Java中的ArrayList类就是基于动态数组实现的,它在扩容时会创建一个新的更大容量的数组,然后将原有元素复制到新数组中。这个过程的时间复杂度为O(n),其中n为原数组的元素数量。因此,频繁的扩容操作会带来性能开销...
栈是一种常见的数据结构,它遵循“后进先出”(LIFO)的原则。在实际编程中,栈常用于函数调用、表达式求值、内存管理等多种场景。...同时,文章可能会对比不同栈实现的性能和适用场景,比如数组栈和链表栈的区别。
【电信优惠套餐推荐系统】是基于数组和链表数据结构设计的一种软件系统,它主要用于帮助电信运营商为用户提供个性化的优惠套餐建议。在这个系统中,数组和链表是两种基础且重要的数据组织方式,它们在存储和处理大量...
在"stackar.c"、"stackli.c"和对应的头文件中,可能实现了基于数组和链表两种方式的栈操作。栈的主要操作包括: 1. 初始化:创建一个空栈。 2. 入栈(Push):将元素添加到栈顶。 3. 出栈(Pop):移除并返回栈顶的...
本资源提供了Java实现的数据结构代码,包括栈、动态数组、队列、链表和二叉树,这些都是计算机科学中最基础且重要的数据结构。 1. **栈(Stack)**:栈是一种“后进先出”(LIFO)的数据结构,常用于表达式求值、...
在这个项目中,我们将深入探讨如何使用C++模板来实现一个基于链表的栈。 栈的基本操作包括压栈(Push)、弹栈(Pop)、查看栈顶元素(Top)以及检查栈是否为空(IsEmpty)。在C++中,模板(Template)是一种泛型...
栈一般用数组或者链表来实现。数组需要静态分配数据空间,占用空间比较大。链表则根据实际需要动态分配数据空间,占用空间相对小一些。本程序用单向链表实现栈。是C++、数据结构及算法学习的一个小小练习。供大家...
总结一下,本压缩包中的内容介绍了如何使用Python基于链表实现栈数据结构。通过学习这个主题,你可以更好地理解链表的工作原理,掌握如何在Python中创建链表类,以及如何利用链表实现栈的特性。这将有助于你在解决...
本主题将深入探讨四种基本数据结构:字符串、向量、链表、栈和队列,这些是编程中最常见且实用的数据结构。 首先,我们来了解**字符串**。在编程中,字符串是由字符组成的序列,常用于处理文本信息。C++中的`std::...
在Python中实现栈数据结构,通常有两种方法:基于数组和基于单链表。栈是一种后进先出(LIFO)的数据结构,常用于处理临时存储和弹出元素的需求,如函数调用堆栈、表达式求值等。下面将详细讲解这两种实现方式。 1....
C++中的栈可以通过数组或链表实现,seqStack.cpp和linkStack.cpp提供了这两种实现。顺序栈操作简便,但可能需要处理栈满的情况;链式栈则无需考虑空间预分配问题。 在实际编程中,C++提供了标准模板库(STL),其中...