Java数据结构与算法之栈(Stack)实现详解

2025-05-29 0 36

本篇是java数据结构算法的第2篇,从本篇开始我们将来了解的设计与实现,以下是本篇的相关知识点:

的抽象数据类型顺序的设计与实现链式的设计与实现的应用

的抽象数据类型

  是一种用于存储数据的简单数据结构,有点类似链表或者顺序表(统称线性表),与线性表的最大区别是数据的存取的操作,我们可以这样认为(stack)是一种特殊的线性表,其插入和删除操作只允许在线性表的一端进行,一般而言,把允许操作的一端称为顶(top),不可操作的一端称为底(bottom),同时把插入元素的操作称为入(push),删除元素的操作称为出(pop)。若中没有任何元素,则称为空的结构如下图:

Java数据结构与算法之栈(Stack)实现详解

由图我们可看成只能从顶存取元素,同时先进入的元素反而是后出,而顶永远指向内最顶部的元素。到此可以给出的正式定义:(stack)是一种有序特殊的线性表,只能在表的一端(称为顶,top,总是指向顶元素)执行插入和删除操作,最后插入的元素将第一个被删除,因此也称为后进先出(last in first out,lifo)或先进后出(first in last out filo)的线性表。的基本操作创建,判空,入,出,获取顶元素等,注意不支持对指定位置进行删除,插入,其接口stack声明如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29
/*

* 栈接口抽象数据类型

*/

public interface stack<t> {

/**

* 栈是否为空

* @return

*/

boolean isempty();

/**

* data元素入栈

* @param data

*/

void push(t data);

/**

* 返回栈顶元素,未出栈

* @return

*/

t peek();

/**

* 出栈,返回栈顶元素,同时从栈中移除该元素

* @return

*/

t pop();

}

顺序的设计与实现

  顺序,顾名思义就是采用顺序表实现的的,顺序的内部以顺序表为基础,实现对元素的存取操作,当然我们还可以采用内部数组实现顺序,在这里我们使用内部数据组来实现,至于以顺序表作为基础的实现,将以源码提供。这里先声明一个顺序其代码如下,实现stack和serializable接口:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
/*

* 顺序栈的实现

*/

public class seqstack<t> implements stack<t>,serializable {

private static final long serialversionuid = -5413303117698554397l;

/**

* 栈顶指针,-1代表空栈

*/

private int top=-1;

/**

* 容量大小默认为10

*/

private int capacity=10;

/**

* 存放元素的数组

*/

private t[] array;

private int size;

public seqstack(int capacity){

array = (t[]) new object[capacity];

}

public seqstack(){

array= (t[]) new object[this.capacity];

}

//.......省略其他代码

}

其获取顶元素值的peek操作过程如下图(未删除只获取值):

Java数据结构与算法之栈(Stack)实现详解

以上是获取顶元素的操作,代码如下:

?

1

2

3

4

5

6

7

8

9

10
/**

* 获取栈顶元素的值,不删除

* @return

*/

@override

public t peek() {

if(isempty())

new emptystackexception();

return array[top];

}

添加元素的过程如下(更新顶top指向):

Java数据结构与算法之栈(Stack)实现详解

以上是入操作,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
/**

* 添加元素,从栈顶(数组尾部)插入

* 容量不足时,需要扩容

* @param data

*/

@override

public void push(t data) {

//判断容量是否充足

if(array.length==size)

ensurecapacity(size*2+1);//扩容

//从栈顶添加元素

array[++top]=data;

}

弹出顶元素的过程如下(删除并获取值):

Java数据结构与算法之栈(Stack)实现详解

以上是出操作,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11
/**

* 从栈顶(顺序表尾部)删除

* @return

*/

@override

public t pop() {

if(isempty())

new emptystackexception();

size--;

return array[top--];

}

到此,顺序的主要操作已实现完,是不是发现很简单,确实如此,的主要操作就这样,当然我们也可以通过前一篇介绍的myarraylist作为基础来实现顺序,这个也比较简单,后面也会提供带代码,这里就不过多啰嗦了。下面给出顺序的整体实现代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114
import java.io.serializable;

import java.util.emptystackexception;

/*

* 顺序栈的实现

*/

public class seqstack<t> implements stack<t>,serializable {

private static final long serialversionuid = -5413303117698554397l;

/**

* 栈顶指针,-1代表空栈

*/

private int top=-1;

/**

* 容量大小默认为10

*/

private int capacity=10;

/**

* 存放元素的数组

*/

private t[] array;

private int size;

public seqstack(int capacity){

array = (t[]) new object[capacity];

}

public seqstack(){

array= (t[]) new object[this.capacity];

}

public int size(){

return size;

}

@override

public boolean isempty() {

return this.top==-1;

}

/**

* 添加元素,从栈顶(数组尾部)插入

* @param data

*/

@override

public void push(t data) {

//判断容量是否充足

if(array.length==size)

ensurecapacity(size*2+1);//扩容

//从栈顶添加元素

array[++top]=data;

size++;

}

/**

* 获取栈顶元素的值,不删除

* @return

*/

@override

public t peek() {

if(isempty())

new emptystackexception();

return array[top];

}

/**

* 从栈顶(顺序表尾部)删除

* @return

*/

@override

public t pop() {

if(isempty())

new emptystackexception();

size--;

return array[top--];

}

/**

* 扩容的方法

* @param capacity

*/

public void ensurecapacity(int capacity) {

//如果需要拓展的容量比现在数组的容量还小,则无需扩容

if (capacity<size)

return;

t[] old = array;

array = (t[]) new object[capacity];

//复制元素

for (int i=0; i<size ; i++)

array[i]=old[i];

}

public static void main(string[] args){

seqstack<string> s=new seqstack<>();

s.push("a");

s.push("b");

s.push("c");

system.out.println("size->"+s.size());

int l=s.size();//size 在减少,必须先记录

for (int i=0;i<l;i++){

system.out.println("s.pop->"+s.pop());

}

system.out.println("s.peek->"+s.peek());

}

}

链式的设计与实现

  了解完顺序,我们接着来看看链式,所谓的链式(linked stack),就是采用链式存储结构的,由于我们操作的是顶一端,因此这里采用单链表(不带头结点)作为基础,直接实现的添加,获取,删除等主要操作即可。其操作过程如下图:

Java数据结构与算法之栈(Stack)实现详解

Java数据结构与算法之栈(Stack)实现详解

从图可以看出,无论是插入还是删除直接操作的是链表头部也就是顶元素,因此我们只需要使用不带头结点的单链表即可。代码实现如下,比较简单,不过多分析了:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77
import com.zejian.structures.linkedlist.singlelinked.node;

import java.io.serializable;

/*

* 栈的链式实现

*/

public class linkedstack<t> implements stack<t> ,serializable{

private static final long serialversionuid = 1911829302658328353l;

private node<t> top;

private int size;

public linkedstack(){

this.top=new node<>();

}

public int size(){

return size;

}

@override

public boolean isempty() {

return top==null || top.data==null;

}

@override

public void push(t data) {

if (data==null){

throw new stackexception("data can\\'t be null");

}

if(this.top==null){//调用pop()后top可能为null

this.top=new node<>(data);

}else if(this.top.data==null){

this.top.data=data;

}else {

node<t> p=new node<>(data,this.top);

top=p;//更新栈顶

}

size++;

}

@override

public t peek() {

if(isempty()){

throw new emptystackexception("stack empty");

}

return top.data;

}

@override

public t pop() {

if(isempty()){

throw new emptystackexception("stack empty");

}

t data=top.data;

top=top.next;

size--;

return data;

}

//测试

public static void main(string[] args){

linkedstack<string> sl=new linkedstack<>();

sl.push("a");

sl.push("b");

sl.push("c");

int length=sl.size();

for (int i = 0; i < length; i++) {

system.out.println("sl.pop->"+sl.pop());

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:http://www.cnblogs.com/ECJTUACM-873284962/p/7506864.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java数据结构与算法之栈(Stack)实现详解 https://www.kuaiidc.com/114672.html

相关文章

发表评论
暂无评论