1.栈的基础概念
a.栈是限制在表的一端进行插入(进栈)和删除(出栈)运算的线性表,而进行这两个操作,需要一个头指针。
b.通常称插入,删除的这一端为栈顶,另一端为栈底。
c.当表中没有元素时称为空栈。假设栈S=(a1,a2,...an),a1称为栈底元素,an称为栈顶元素。
注意:栈是按后进先出的原则进行的,所以,栈称为后进先出(先进后出)表。
2.栈的实现——顺序栈
栈抽象数据结构 栈接口, 描述栈抽象数据类型,泛型参数T表示数据元素的数据类型:
package com.clarck.datastructure.stack;
/**
* 栈抽象数据结构 栈接口, 描述栈抽象数据类型,泛型参数T表示数据元素的数据类型
*
* @author clarck
*
* @param <T>
*/
public interface SStack<T> {
/**
* 判断栈是否为空
*
* @return
*/
boolean isEmpty();
/**
* 元素x入栈
*
* @param x
*/
void push(T x);
/**
* 出栈,返回栈顶元素
*
* @return
*/
T pop();
/**
* 取栈顶元素, 未出栈
*
* @return
*/
T get();
}
顺序栈:
package com.clarck.datastructure.stack;
/**
* 顺序栈
*
* @author clarck
*
* @param <T>
*/
public class SeqStack<T> implements SStack<T> {
/**
* 存储栈数据元素的数组
*/
private Object element[];
/**
* 栈顶元素下标
*/
private int top;
/**
* 构造容量为size的空栈
*/
public SeqStack(int size) {
this.element = new Object[Math.abs(size)];
this.top = -1;
}
/**
* 构造默认容量的空栈
*/
public SeqStack() {
this(64);
}
/**
* 判断栈是否空,若空返回true
*/
@Override
public boolean isEmpty() {
return this.top == -1;
}
/**
* 元素x入栈,空对象不能入栈
*/
@Override
public void push(T x) {
if (x == null)
return;
// 若栈满,则扩充栈容量
if (this.top == element.length - 1) {
Object[] temp = this.element;
// 重新申请一个容量更大的数组
this.element = new Object[temp.length * 2];
// 复制数组元素,O(n)
for (int i = 0; i < temp.length; i++) {
this.element[i] = temp[i];
}
}
this.top++;
this.element[this.top] = x;
}
/**
* 出栈,返回栈顶元素,若栈空返回null
*/
@SuppressWarnings("unchecked")
@Override
public T pop() {
return this.top == -1 ? null : (T) this.element[this.top--];
}
/**
* 取栈顶元素,未出栈,若栈空返回null
*/
@SuppressWarnings("unchecked")
@Override
public T get() {
return this.top == -1 ? null : (T) this.element[this.top];
}
/**
* 返回栈所有元素的描述字符串,形式为“(,)”,算法同顺序表
*/
@Override
public String toString() {
String str = "(";
if (this.top != -1)
str += this.element[this.top].toString();
for (int i = this.top - 1; i >= 0; i--) {
str += ", " + this.element[i].toString();
}
return str + ") ";
}
}
顺序栈的测试类:
package com.clarck.datastructure.stack;
/**
* 栈的测试类
*
* @author clarck
*
*/
public class Stack_test {
public static void main(String args[]) {
SeqStack<String> stack = new SeqStack<String>(20);
System.out.print("Push: ");
char ch = ‘a‘;
for (int i = 0; i < 5; i++) {
String str = (char) (ch + i) + "";
stack.push(str);
System.out.print(str + " ");
}
System.out.println(stack.toString());
}
}
测试结果如下:
Push: a b c d e (e, d, c, b, a)
提醒:源码下载链接为:
http://www.cnblogs.com/tanlon/p/4039667.html
3.栈的实现——链式栈
栈抽象数据结构 栈接口, 描述栈抽象数据类型,泛型参数T表示数据元素的数据类型:
package com.clarck.datastructure.stack;
/**
* 栈抽象数据结构 栈接口, 描述栈抽象数据类型,泛型参数T表示数据元素的数据类型
*
* @author clarck
*
* @param <T>
*/
public interface SStack<T> {
/**
* 判断栈是否为空
*
* @return
*/
boolean isEmpty();
/**
* 元素x入栈
*
* @param x
*/
void push(T x);
/**
* 出栈,返回栈顶元素
*
* @return
*/
T pop();
/**
* 取栈顶元素, 未出栈
*
* @return
*/
T get();
}
栈结点类,T指定结点的元素类型:
package com.clarck.datastructure.stack;
/**
* 单链表结点类,T指定结点的元素类型
*
* @author clarck
*
* @param <T>
*/
public class Node<T> {
/**
* 数据域,保存数据元素
*/
public T data;
/**
* 地址域,引用后继结点
*/
public Node<T> next;
/**
* 构造结点,data指定数据元素,next指定后继结点
*
* @param data
* @param next
*/
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
/**
* 构造节点
*/
public Node() {
this(null, null);
}
/**
* 返回结点元素值对应的字符串
*/
@Override
public String toString() {
return this.data.toString();
}
/**
* 比较两个结点值是否相等,覆盖Object类的equals(obj)方法
*/
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
return obj == this || obj instanceof Node && this.data.equals(((Node<T>)obj).data);
}
}
链式栈:
package com.clarck.datastructure.stack;
/**
* 链式栈
*
* @author clarck
*
* @param <T>
*/
public class LinkedStack<T> implements SStack<T> {
/**
* 栈顶结点
*/
private Node<T> top;
/**
* 构造空栈
*/
public LinkedStack() {
this.top = null;
}
/**
* 判断栈是否空,若空返回true
*/
@Override
public boolean isEmpty() {
return this.top == null;
}
/**
* 元素x入栈,空对象不能入栈
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void push(T x) {
//头插入,x结点作为新的栈顶结点
if (x != null) {
this.top = new Node(x, this.top);
}
}
/**
* 出栈,返回栈顶元素,若栈空返回null
*/
@Override
public T pop() {
if (this.top == null)
return null;
//取栈顶结点元素
T temp = this.top.data;
//删除栈顶结点
this.top = this.top.next;
return temp;
}
/**
* 取栈顶元素,未出栈,若栈空返回null
*/
@Override
public T get() {
return this.top == null ? null : this.top.data;
}
/**
* 返回栈所有元素的描述字符串,形式为“(,)”。算法同不带头结点的单链表
*/
@Override
public String toString() {
String str = "(";
for (Node<T> p = this.top; p != null; p = p.next) {
str += p.data.toString();
//不是最后一个结点时后加分隔符
if (p.next != null) {
str += ", ";
}
}
return str + ") ";
}
}
栈的测试类:
package com.clarck.datastructure.stack;
/**
* 栈的测试类
*
* @author clarck
*
*/
public class Stack_test {
public static void main(String args[]) {
LinkedStack<Integer> stack2 = new LinkedStack<Integer>();
System.out.print("Push: ");
for (int i = 1; i <= 5; i++) {
Integer intobj = new Integer(i);
stack2.push(intobj);
System.out.print(intobj + " ");
}
System.out.println("\n Stack: " + stack2.toString());
System.out.print("Pop: ");
while (!stack2.isEmpty()) { // 全部出栈
System.out.print(stack2.pop().toString() + " ");
}
System.out.println();
}
}
测试结果:
Push: 1 2 3 4 5
Stack: (5, 4, 3, 2, 1)
Pop: 5 4 3 2 1
提醒:源码下载地址为:
http://www.cnblogs.com/tanlon/p/4039677.html