java顺序栈和链栈_Java的顺序栈和链式栈
棧的定義
棧是限制在表的一段進(jìn)行插入和刪除的運(yùn)算的線性表,通常能夠?qū)⒉迦搿h除的一端為棧頂,例外一端稱為棧底,當(dāng)表中沒有任何元素的時(shí)候稱為空棧。
通常刪除(又稱“退棧”)叫做彈出pop操作,每次刪除的都是棧頂最新的元素;每次插入(又稱“進(jìn)棧”)稱為壓入push操作。
當(dāng)棧滿的時(shí)候,進(jìn)行push 操作,會(huì)上溢,當(dāng)空棧的時(shí)候進(jìn)行退棧操作的時(shí)稱為下溢。
上溢是一種出錯(cuò)的情況,下溢可能是正常的情況處理。
堆棧的運(yùn)算是按照后進(jìn)先出的原則,簡稱LIFO。
棧的基本運(yùn)算定義:
initStack:構(gòu)造一個(gè)空棧;
stackEmpty:判斷是否為空;
stackFUll:判斷是否棧滿;
push:進(jìn)棧,將該元素壓入棧頂;
pop:退棧,彈出棧頂元素,注意非空判斷;
stackTop:去除棧頂元素,不改變指針。
做個(gè)簡單的Stack接口:
package com.wuwii.utils;
/**
* 堆棧
* @author Zhang Kai
* @version 1.0
* @since
2017/12/14 22:51*/
public interface Stack {
/**
* 進(jìn)棧
*
* @param element 進(jìn)棧的元素
*/
void push(E element);
/**
* 彈出棧頂元素 ,并改變指針
*
* @return 棧頂元素
*/
E pop();
/**
* 返回棧頂元素 ,不改變指針
*
* @return 棧頂元素
*/
E topElement();
/**
* 判斷是否為空棧
*
* @return true為空棧
*/
Boolean isEmpty();
/**
* 清空棧
*/
void clear();
}
順序棧
就是符合LIFO運(yùn)算規(guī)則的順序線性表。
package com.wuwii.utils;
/**
* 順序棧
* @author Zhang Kai
* @version 1.0
* @since
2017/12/14 23:05*/
public class ArrayStack implements Stack {
/**
* 初始化棧的默認(rèn)大小
*/
private final int defaultSize = 10;
/**
* 棧的集合大小
*/
private int size;
/**
* 棧頂?shù)奈恢?/p>
*/
private int top;
/**
* 元素存儲(chǔ)在數(shù)組
*/
private Object[] elements;
/**
* 初始化默認(rèn)大小為10 的棧
*/
public ArrayStack() {
initStack(defaultSize);
}
/**
* 初始化指定大小的棧
* @param givenSize 指定棧大小
*/
public ArrayStack(Integer givenSize) {
initStack(givenSize);
}
/**
* 初始化棧
* @param givenSize 給定的棧大小
*/
private void initStack(Integer givenSize) {
size = givenSize;
top = 0;
elements = new Object[size];
}
/**
* 清空棧
*/
@Override
public void clear() {
top = 0;
}
/**
* 進(jìn)棧
* @param element 進(jìn)棧的元素
*/
@Override
public void push(E element) {
sizeCheckForPush();
elements[top++] = element;
}
/**
* 彈出棧頂元素 ,并改變指針
* @return 棧頂元素
*/
@Override
public E pop() {
sizeCheckForPop();
return (E) elements[--top];
}
/**
* 返回棧頂元素 ,不改變指針
* @return 棧頂元素
*/
@Override
public E topElement() {
sizeCheckForPush();
return (E) elements[top - 1];
}
/**
* 判斷是否為空棧
* @return true為空棧
*/
@Override
public Boolean isEmpty() {
return size == 0;
}
/**
* 在進(jìn)棧的時(shí)候檢查
*/
private void sizeCheckForPush() {
if (top >= size) {
throw new RuntimeException("Stack overflow");
}
}
/**
* 退棧檢查
*/
private void sizeCheckForPop() {
if (isEmpty()) {
throw new RuntimeException("Stack is empty");
}
}
}
鏈?zhǔn)綏?/p>
符合LIFO運(yùn)算規(guī)則的鏈?zhǔn)骄€性表。
package com.wuwii.utils;
/**
* @author Zhang Kai
* @version 1.0
* @since
2017/12/15 12:58*/
public class LinkStack implements Stack {
/**
* 鏈?zhǔn)絾卧?/p>
*/
private Node top;
/**
* 初始化鏈?zhǔn)蕉褩?/p>
*/
public LinkStack() {
initStack();
}
/**
* 初始化
*/
private void initStack() {
top = null;
}
/**
* 存儲(chǔ)單元
*/
private static class Node {
E element;
Node next;
Node(E element, Node next) {
this.element = element;
this.next = next;
}
}
/**
* 進(jìn)棧
*
* @param element 進(jìn)棧的元素
*/
@Override
public void push(E element) {
top = new Node(element, top);
}
/**
* 彈出棧頂元素 ,并改變指針
*
* @return 棧頂元素
*/
@Override
public E pop() {
checkEmpty();
E element = top.element;
top = top.next;
return element;
}
/**
* 返回棧頂元素 ,不改變指針
*
* @return 棧頂元素
*/
@Override
public E topElement() {
checkEmpty();
return top.element;
}
/**
* 判斷是否為空棧
*
* @return true為空棧
*/
@Override
public Boolean isEmpty() {
return top == null;
}
/**
* 清空棧
*/
@Override
public void clear() {
if (isEmpty()) {
return;
}
for (Node x = top; x != null; ) {
Node next = x.next;
x.element = null;
x.next = null;
x = next;
}
size = 0;
}
/**
* 檢查鏈?zhǔn)蕉褩J欠駷榭?#xff0c;為空拋出異常
*/
private void checkEmpty() {
if (isEmpty()) {
throw new RuntimeException("LinkStack is empty");
}
}
}
首先push 修改新產(chǎn)生的鏈表節(jié)點(diǎn)的next 域并指向棧頂,然后設(shè)置top 指向新的鏈表節(jié)點(diǎn),pop則相反。
順序棧和鏈?zhǔn)綏5谋容^
實(shí)現(xiàn)鏈?zhǔn)綏:晚樞驐5牟僮鞫际切枰?shù)時(shí)間,時(shí)間復(fù)雜度為O(1),主要從空間和時(shí)間復(fù)雜度考慮。
順序棧初始化的時(shí)候必須要給定指定大小,當(dāng)堆棧不滿的時(shí)候,會(huì)造成一部分的空間浪費(fèi),鏈?zhǔn)綏W冮L,相對(duì)節(jié)約空間,但是增加了指針域,額外加大了數(shù)據(jù)結(jié)構(gòu)的開銷。
當(dāng)需要多個(gè)堆棧共享的時(shí)候,順序存儲(chǔ)中可以充分的利用順序棧的單向延伸,將一個(gè)數(shù)組可以存在兩個(gè)堆棧里,每個(gè)堆棧從各自的棧頂出發(fā)延伸,這樣減少了空間的浪費(fèi)。但只有兩個(gè)為堆棧的空間有相反的需求的時(shí)候才能使用。就是最好一個(gè)堆棧只能增加,一個(gè)只能減少。如果,兩個(gè)一起增加,可能造成堆棧的溢出。
如果在多個(gè)順序堆棧共享空間,一個(gè)堆棧滿了,其他可能沒滿,需要使用堆棧的LIFO 運(yùn)算法則,將滿的堆棧元素向左或者右進(jìn)行平移操作,這樣會(huì)造成大量的數(shù)據(jù)元素移動(dòng),使得時(shí)間的開銷增大。
相對(duì)來說,使用兩個(gè)堆棧共享一個(gè)空間是比較適宜的存儲(chǔ)方式,但是也增加了堆棧溢出的危險(xiǎn)。
由于鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的不連續(xù)性,什么時(shí)候需要,就什么時(shí)候去存儲(chǔ),不存在溢出的問題,但是增加了結(jié)構(gòu)的開銷,總體上來說浪費(fèi)了空間,但是不需要堆棧共享,
總結(jié)
以上是生活随笔為你收集整理的java顺序栈和链栈_Java的顺序栈和链式栈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票周线买入技巧?
- 下一篇: java家具网站需求分析_基于jsp的家