栈(Stack)

栈的介绍

  1. 栈的英文为:Stack
  2. 栈是一个先入后出(FILO-First In Last Out)的有序列表。
  3. 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一 种特殊线性表。允许插入和删除的 一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。
  4. 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除
  5. 图解方式说明出栈(pop)和入栈(push)的概念:

 

 

 

 

栈的应用场景

  1. 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
  2. 处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
  3. 表达式的转换[中缀表达式转后缀表达式]与求值。
  4. 二叉树的遍历。
  5. 图形的深度优先(depth 一 first)搜索法。

数组实现栈

思路分析

  1. 使用数组来模拟栈
  2. 定义一个top来表示栈顶,初始指向为-1
  3. 入栈操作:当数据加入到栈时, 

top++

stack[top]=data; 

  1. 出栈操作: 

int value=stack[top];

top--;

return value; 

代码实现:

1. //用数组实现栈  
2. public class arraystack {  
3.     private int[] array;// 数组,数组模拟栈,数据就放在该数组  
4.     private int top = -1;// top 表示栈顶,初始化为-1  
5.     private int maxSize; // 栈的大小  
6.   
7.     //构造器  
8.     public arraystack(int maxSize) {  
9.         this.maxSize = maxSize;  
10.        array = new int[this.maxSize];  
11.     }  
12.   
13.     //判断栈是否为空  
14.     public boolean isEmpty() {  
15.         return top == -1;  
16.     }  
17.   
18.     //判断栈是否满  
19.     public boolean isFull() {  
20.         return top == this.maxSize - 1;  
21.     }  
22.   
23.     //入栈  
24.     public void push(int a) {  
25.         if (isFull()) {//先判断栈是否满  
26.             System.out.println("push():栈已满,无法添加。。。。");  
27.             return;  
28.         }  
29.         top++;  
30.         array[top] = a;  
31.     }  
32.   
33.     //出栈  
34.     public int pop() {  
35.         if (isEmpty()) {//先判断栈是否空  
36.             throw new RuntimeException("pop():栈已满,无法出栈。。。");  
37.         }  
38.         int i = array[top];  
39.         top--;  
40.         return i;  
41.     }  
42.   
43.     //遍历  
44.     public void show() {  
45.         for (int i = top; i > -1; i--) {//遍历时,需要从栈顶开始显示数据  
46.             System.out.println(array[i]);  
47.         }  
48.     }  
49.   
50.     //获取栈顶元素  
51.     public int peek() {  
52.         return array[top];  
53.     }  
54. }   

 

链表实现栈

代码实现:

  • 定义链表:
1. //定义链表  
2. public class linkedList<E> {  
3.   
4.     private class Node {//内部类,定义链表中的节点内容  
5.         private Node next;//表示下一个节点  
6.         E e;//此节点的值  
7.   
8.         //构造器  
9.         public Node(E e, Node next) {  
10.             this.next = next;  
11.             this.e = e;  
12.         }  
13.   
14.         //构造器  
15.         public Node() {  
16.             this(nullnull);  
17.         }  
18.   
19.         //构造器  
20.         public Node(E e) {  
21.             this(e, null);  
22.         }  
23.   
24.         //重写toString()  
25.         @Override  
26.         public String toString() {  
27.             return "Node{" +  
28.                     "e=" + e +  
29.                     '}';  
30.         }  
31.     }  
32.   
33.     private Node first = new Node();//表示链表的头结点  
34.     private int size;//表示链表的长度(大小)  
35.   
36.     // 获取链表中的元素个数  
37.     public int getSize() {  
38.         return size;  
39.     }  
40.   
41.     // 返回链表是否为空  
42.     public boolean isEmpty() {  
43.         return size == 0;  
44.     }  
45.   
46.     // 在链表的index( 0 ~ size-1 )位置添加新的元素e  
47.     public void add(int index, E e) {  
48.         if (index < 0 || index > size) {//判断index是否合法  
49.             throw new IllegalArgumentException("add():输入index值有误,添加失败。。。");  
50.         }  
51.         Node temp = first;//头结点不能移动,所以设置辅助节点temp  
52.         for (int i = 0; i < index; i++) {//将temp节点指向index位置的前一个位置节点  
53.             temp = temp.next;  
54.         }  
55.         Node node = new Node(e, temp.next);//将新元素e创建成node对象,next为temp的下一个节点  
56.         temp.next = node;//将temp所指节点的next指向node  
57.         size++;  
58.     }  
59.   
60.     // 在链表头添加新的元素e  
61.     public void addAtFirst(E e) {  
62.         add(0, e);  
63.     }  
64.   
65.     // 在链表末尾添加新的元素e  
66.     public void addAtLast(E e) {  
67. //        add(getSize(),e);  
68.         add(size, e);  
69.     }  
70.   
71.     // 获得链表的第index( 0 ~ size-1 )个位置的元素  
72.     public E get(int index) {  
73.         if (index < 0 || index >= size) {  
74.             throw new IllegalArgumentException("get():输入的index非法,获取失败。。。");  
75.         }  
76.         Node temp = first.next;  
77.         for (int i = 0; i < index; i++) {  
78.             temp = temp.next;  
79.         }  
80.         return temp.e;  
81.     }  
82.   
83.     // 获得链表的第一个元素  
84.     public E getFirst() {  
85.         return get(0);  
86.     }  
87.   
88.     // 获得链表的最后一个元素  
89.     public E getLast() {  
90.         return get(size - 1);  
91.     }  
92.   
93.     // 修改链表的第index( 0 ~ size-1 )个位置的元素为e  
94.     public void set(int index, E e) {  
95.         if (index < 0 || index >= size) {  
96.             throw new IllegalArgumentException("set():获取元素失败,输入的index值非法!");  
97.         }  
98.         Node temp = first;  
99.         for (int i = 0; i < index; i++) {  
100.             temp = temp.next;  
101.         }  
102.         temp.e = e;  
103.     }  
104.   
105.     // 查找链表中是否有元素e  
106.     public boolean contains(E e) {  
107.         Node temp = first.next;  
108.         boolean flag = false;  
109.         while (temp != null) {  
110.             if (temp.e.equals(e)) {  
111.                 return true;  
112.             }  
113.             temp = temp.next;  
114.         }  
115.         return false;  
116.     }  
117.   
118.     // 从链表中删除index( 0 ~ size-1 )位置的元素, 返回删除的元素  
119.     public E remove(int index) {  
120.         if (index < 0 || index >= size) {  
121.             throw new IllegalArgumentException("remove():获取元素失败,输入的index值非法!");  
122.         }  
123.         Node temp = first;  
124.         for (int i = 0; i < index; i++) {  
125.             temp = temp.next;  
126.         }  
127.         Node delNode = temp.next;  
128.         temp.next = delNode.next;  
129.         size--;  
130.         return delNode.e;  
131.     }  
132.   
133.   
134.     // 从链表中删除第一个元素(0), 返回删除的元素  
135.     public E removeFirst() {  
136.         return remove(0);  
137.     }  
138.   
139.     // 从链表中删除最后一个元素(size-1), 返回删除的元素  
140.     public E removeLast() {  
141.         return remove(size - 1);  
142.     }  
143.   
144.     // 从链表中删除指定元素e  
145.     public void removeElement(E e) {  
146.         Node temp = first;  
147.         while (temp.next != null) {  
148.             if (temp.next.e.equals(e)) {  
149.                 temp.next = temp.next.next;  
150.                 size--;  
151.                 return;  
152.             }  
153.             temp = temp.next;  
154.         }  
155.         System.out.println("removeElemen():没有找到该元素,删除失败。。。");  
156.     }  
157.   
158.     //重写toString()  
159.     @Override  
160.     public String toString() {  
161.         StringBuilder stringBuilder = new StringBuilder();  
162.         Node temp = first.next;  
163.         while (temp != null) {  
164.             if (temp.next == null) {  
165.                 stringBuilder.append(temp.e);  
166.             } else {  
167.                 stringBuilder.append(temp.e + "->");  
168.             }  
169.             temp = temp.next;  
170.         }  
171.         return stringBuilder.toString();  
172.     }  
173. }  

来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 
  • 用链表定义栈:
1. interface stack<E> {  
2.     /** 
3.      * 获取栈的大小 
4.      */  
5.     int getSize();  
6.   
7.     /** 
8.      * 栈顶元素出栈 
9.      */  
10.     E pop();  
11.   
12.     /** 
13.      * 元素入栈 
14.      */  
15.     void push(E e);  
16.   
17.     /** 
18.      * 遍历栈元素 
19.      */  
20.     void printAll();  
21.   
22.     /** 
23.      * 输出栈顶元素 
24.      */  
25.     E peek();  
26.   
27.     /** 
28.      * 判断栈是否为空 
29.      */  
30.     boolean isEmpty();  
31. }  

来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 

 

1. //用链表来实现栈  
2. class linkedListStack<E> implements stack<E> {  
3.     private linkedList<E> list;  
4.   
5.     public linkedListStack() {  
6.         list = new linkedList<>();  
7.     }  
8.   
9.     @Override  
10.     public int getSize() {  
11.         return list.getSize();  
12.     }  
13.   
14.     @Override  
15.     public E pop() {  
16.         return list.removeLast();  
17.     }  
18.   
19.     @Override  
20.     public void push(E e) {  
21.         list.addAtLast(e);  
22.     }  
23.   
24.     @Override  
25.     public void printAll() {  
26.         System.out.println(list.toString());  
27.     }  
28.   
29.     @Override  
30.     public E peek() {  
31.         E atLast = null;  
32.         try {  
33.             atLast = list.getLast();  
34.         } catch (Exception e) {  
35.             System.out.print("栈为空:");  
36.         }  
37.         return atLast;  
38.     }  
39.   
40.     @Override  
41.     public boolean isEmpty() {  
42.         return list.isEmpty();  
43.     }  
44.   
45. }  

来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 

 

posted @ 2020-10-16 10:35  白刃天使  阅读(615)  评论(0编辑  收藏  举报