日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java顺序栈和链栈_Java的顺序栈和链式栈

發(fā)布時間:2023/12/2 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java顺序栈和链栈_Java的顺序栈和链式栈 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

棧的定義

棧是限制在表的一段進行插入和刪除的運算的線性表,通常能夠?qū)⒉迦搿h除的一端為棧頂,例外一端稱為棧底,當表中沒有任何元素的時候稱為空棧。

通常刪除(又稱“退棧”)叫做彈出pop操作,每次刪除的都是棧頂最新的元素;每次插入(又稱“進棧”)稱為壓入push操作。

當棧滿的時候,進行push 操作,會上溢,當空棧的時候進行退棧操作的時稱為下溢。

上溢是一種出錯的情況,下溢可能是正常的情況處理。

堆棧的運算是按照后進先出的原則,簡稱LIFO。

棧的基本運算定義:

initStack:構(gòu)造一個空棧;

stackEmpty:判斷是否為空;

stackFUll:判斷是否棧滿;

push:進棧,將該元素壓入棧頂;

pop:退棧,彈出棧頂元素,注意非空判斷;

stackTop:去除棧頂元素,不改變指針。

做個簡單的Stack接口:

package com.wuwii.utils;

/**

* 堆棧

* @author Zhang Kai

* @version 1.0

* @since

2017/12/14 22:51

*/

public interface Stack {

/**

* 進棧

*

* @param element 進棧的元素

*/

void push(E element);

/**

* 彈出棧頂元素 ,并改變指針

*

* @return 棧頂元素

*/

E pop();

/**

* 返回棧頂元素 ,不改變指針

*

* @return 棧頂元素

*/

E topElement();

/**

* 判斷是否為空棧

*

* @return true為空棧

*/

Boolean isEmpty();

/**

* 清空棧

*/

void clear();

}

順序棧

就是符合LIFO運算規(guī)則的順序線性表。

package com.wuwii.utils;

/**

* 順序棧

* @author Zhang Kai

* @version 1.0

* @since

2017/12/14 23:05

*/

public class ArrayStack implements Stack {

/**

* 初始化棧的默認大小

*/

private final int defaultSize = 10;

/**

* 棧的集合大小

*/

private int size;

/**

* 棧頂?shù)奈恢?/p>

*/

private int top;

/**

* 元素存儲在數(shù)組

*/

private Object[] elements;

/**

* 初始化默認大小為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;

}

/**

* 進棧

* @param element 進棧的元素

*/

@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;

}

/**

* 在進棧的時候檢查

*/

private void sizeCheckForPush() {

if (top >= size) {

throw new RuntimeException("Stack overflow");

}

}

/**

* 退棧檢查

*/

private void sizeCheckForPop() {

if (isEmpty()) {

throw new RuntimeException("Stack is empty");

}

}

}

鏈式棧

符合LIFO運算規(guī)則的鏈式線性表。

package com.wuwii.utils;

/**

* @author Zhang Kai

* @version 1.0

* @since

2017/12/15 12:58

*/

public class LinkStack implements Stack {

/**

* 鏈式單元

*/

private Node top;

/**

* 初始化鏈式堆棧

*/

public LinkStack() {

initStack();

}

/**

* 初始化

*/

private void initStack() {

top = null;

}

/**

* 存儲單元

*/

private static class Node {

E element;

Node next;

Node(E element, Node next) {

this.element = element;

this.next = next;

}

}

/**

* 進棧

*

* @param element 進棧的元素

*/

@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;

}

/**

* 檢查鏈式堆棧是否為空,為空拋出異常

*/

private void checkEmpty() {

if (isEmpty()) {

throw new RuntimeException("LinkStack is empty");

}

}

}

首先push 修改新產(chǎn)生的鏈表節(jié)點的next 域并指向棧頂,然后設(shè)置top 指向新的鏈表節(jié)點,pop則相反。

順序棧和鏈式棧的比較

實現(xiàn)鏈式棧和順序棧的操作都是需要常數(shù)時間,時間復(fù)雜度為O(1),主要從空間和時間復(fù)雜度考慮。

順序棧初始化的時候必須要給定指定大小,當堆棧不滿的時候,會造成一部分的空間浪費,鏈式棧變長,相對節(jié)約空間,但是增加了指針域,額外加大了數(shù)據(jù)結(jié)構(gòu)的開銷。

當需要多個堆棧共享的時候,順序存儲中可以充分的利用順序棧的單向延伸,將一個數(shù)組可以存在兩個堆棧里,每個堆棧從各自的棧頂出發(fā)延伸,這樣減少了空間的浪費。但只有兩個為堆棧的空間有相反的需求的時候才能使用。就是最好一個堆棧只能增加,一個只能減少。如果,兩個一起增加,可能造成堆棧的溢出。

如果在多個順序堆棧共享空間,一個堆棧滿了,其他可能沒滿,需要使用堆棧的LIFO 運算法則,將滿的堆棧元素向左或者右進行平移操作,這樣會造成大量的數(shù)據(jù)元素移動,使得時間的開銷增大。

相對來說,使用兩個堆棧共享一個空間是比較適宜的存儲方式,但是也增加了堆棧溢出的危險。

由于鏈式存儲結(jié)構(gòu)的不連續(xù)性,什么時候需要,就什么時候去存儲,不存在溢出的問題,但是增加了結(jié)構(gòu)的開銷,總體上來說浪費了空間,但是不需要堆棧共享,

總結(jié)

以上是生活随笔為你收集整理的java顺序栈和链栈_Java的顺序栈和链式栈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。