Java数据结构基础–顺序栈与链式栈

栈的定义:
是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。
栈的操作:
向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈的特点:
先进后出,即先入栈的最后操作,后入栈的最先操作。

java顺序结构的例子 java顺序栈的基本操作_算法

顺序栈(基于数组):

完整代码:

public class Stack {
	
	private Object elements[];//存储数组
	private int top;//最后一个元素位置下标
	private int maxsize;//最大存储量
	private int stackIncreament = 50;//栈溢出扩容数量
	
	public Stack(int maxsize) {
		top = -1;
		this.maxsize = maxsize;
		elements = new Object[maxsize];
	}
	
	private void overfolwProcess() {//扩充栈
		Object newArray = new Object[maxsize+stackIncreament];
		System.arraycopy(elements, 0, newArray, 0, top+1);//复制数值元素
		elements = (Object[]) newArray;
		maxsize = maxsize+stackIncreament;
	}
	
	public void Push(Object x) {//入栈
		
		if(IsFull()==true) {//栈满做溢出处理
			overfolwProcess();
		}
		top = top +1;
		elements[top] = x;
	}

	private boolean IsFull() {//判断是否栈满
		
		if(top+1 == maxsize) {
			return true;
		}
		
		return false;
		
	}
	
	public boolean Pop() {//退栈
		
		if(IsEmpty() == true) {
			System.out.println("栈空,无元素");
			return false;
		}
		top--;
		return true;
	}

	private boolean IsEmpty() {//判断栈是否为空
		if(top == -1) {
			return true;
		}
		return false;
	}
	
	public Object getTop() {//获取栈顶元素
		
		if(IsEmpty() == true) {
			System.out.println("栈空,无元素");
			return false;
		}
		return elements[top];
	}
	
	@Override
	public String toString() {//输出函数
		
		String rel = "";
		int index = top;
		if(IsEmpty()==true) {
			return rel;
		}
		while(index > 0) {
			rel = rel + elements[index]+"-->" ;
			index--;
		}
		rel +=  elements[0];
		return rel;
	}
}

部分函数详解:

1. Stack栈类:

public class Stack {
	private Object elements[];//存储数组
	private int top;//最后一个元素位置下标
	private int maxsize;//最大存储量
	private int stackIncreament = 50;//栈溢出扩容数量
	}

(1)基于数组实现,用elements[]存储数据。
(2)用top来指向栈顶,这里则指向栈顶元素的数组下标。(初始值为-1)
(3)maxsize:初始化时定义的最大存储量,既数组长度。
(4)stackIncreament:当存储数据个数超过最大存储量,自动扩容量。

2. overfolwProcess() - -扩充栈

private void overfolwProcess() {//扩充栈
		Object newArray = new Object[maxsize+stackIncreament];
		//定义扩容后对应数组长度的数组,原来最大长度maxsize+自动扩容长度stackIncreament
		System.arraycopy(elements, 0, newArray, 0, top+1);
		//arraycopy函数复制数组元素,
		//System.arraycopy(被复制数组, 开始复制元素下标, 粘贴到此数组, 开始粘贴元素下标, 复制粘贴元素长度);
		elements = (Object[]) newArray; //将扩容后数组赋值给栈中的数组
		maxsize = maxsize+stackIncreament;//更新最大存储长度
	}

3. Push(Object x)- -入栈

public void Push(Object x) {//入栈
		
		if(IsFull()==true) {//栈满做溢出处理
			overfolwProcess();//扩容操作
		}
		top = top +1;
		elements[top] = x;
	}

java顺序结构的例子 java顺序栈的基本操作_栈_02

4. Pop()- -退栈

public boolean Pop() {//退栈
		
		if(IsEmpty() == true) {
			System.out.println("栈空,无元素");
			return false;
		}
		top--;//改变栈顶指向,通过改变top指向的数组下标实现
		return true;
	}

5.测试函数:

public class Main {
	public static void main(String[] args) {
		
		Stack stack = new Stack(4);
		stack.Push(1);//入栈
		stack.Push(2);
		stack.Push(3);
		stack.Push(4);
		stack.Push(5);
		System.out.println(stack);//重载toString函数,改变输入方式
		stack.Pop();//退栈
		stack.Push(6);
		System.out.println(stack);
	}
}

执行结果:

java顺序结构的例子 java顺序栈的基本操作_java_03

链式栈(基于单链表):

完整代码:

public class LinkedStack {

	public class Node {
		private Object data;// 存放数据
		private Node next;// 下一个节点(指针)

		public Node(Object data, Node next) {// 双参数构造函数
			this.data = data;
			this.next = next;
		}

		public Node(Object data) {// 单参数构造函数
			this.data = data;
			this.next = null;
		}

		public Node() {// 单参数构造函数
		}
	}

	private Node top ;// 栈顶指针,链头指针

	public void Push(Object x) {// 入栈
		top = new Node(x, top);// top指向新结点,新节点指向原来的栈顶
	}

	public boolean Pop() {// 退栈
		if (IsEmpty() == true) {
			return false;
		}
		top = top.next;// 栈顶移动一个节点
		return true;
	}

	private boolean IsEmpty() {// 是否为空
		if (top == null) {
			return true;
		}
		return false;
	}

	public Object getTop() {// 获取栈顶值
		if (IsEmpty() == true) {
			System.out.println("栈空");
			return null;
		}
		return top.data;
	}

	public int getSize() {// 获取长度
		Node p = top;
		int k = 0;
		while (p != null) {
			p = p.next;
			k++;
		}
		return k;
	}

	@Override
	public String toString() {
		String ans = "top-->";
		Node p = top;
		while (p != null) {
			ans += p.data + "-->";
			p = p.next;
		}
		ans += "null";
		return ans;
	}
}

部分函数详解:

  1. Node结点:
public class Node {
		private Object data;// 存放数据
		private Node next;// 下一个节点(指针)
	}

在链式栈中,将数组换成了一个一个的节点。
顺序栈基于数组实现,链式栈基于单链表实现

原先的top也用Node节点替代:

private Node top ;// 指向栈顶元素

2.Push()- -入栈:

public void Push(Object x) {// 入栈
		top = new Node(x, top);// top指向新结点,新节点指向原来的栈顶
	}

java顺序结构的例子 java顺序栈的基本操作_栈_04

3. Pop()- -退栈

public boolean Pop() {// 退栈
		if (IsEmpty() == true) {
			return false;
		}
		top = top.next;// 栈顶移动一个节点
		return true;
	}

java顺序结构的例子 java顺序栈的基本操作_数据结构_05

4. getSize() - -获取长度

public int getSize() {// 获取长度
		Node p = top;//定义一个新节点指向top栈顶
		int k = 0;
		while (p != null) {
			p = p.next;//节点后移
			k++;
		}
		return k;
	}

这里利用节点后移计算长度,和单链表计算长度相同。

应该注意的一点是:
重新定义新节点p,利用新节点p指向top后在后移。如果直接用top计算长度,会改变栈顶指向

5. 测试函数:

public class Mian {
	public static void main(String[] args) {
		LinkedStack stack = new LinkedStack();
		stack.Push(1);//入栈
		stack.Push(2);
		stack.Push(3);
		System.out.println(stack);
		stack.Pop();//退栈
		System.out.println(stack);
		System.out.println(stack.getTop());//取栈顶数据并输出
	}
}

测试结果:

java顺序结构的例子 java顺序栈的基本操作_java_06


有写的不清楚的地方欢迎留言,谢谢观看。