3.4.2.2 基于本地创建的链表实现栈
package com.yzh.maven.entity;
import com.yzh.maven.base.dao.MyStackDao;
public class MyLinkedStack<E> implements MyStackDao<E>{
private int size;
private MyDobbleLinkedList<E> linkedList;
public MyLinkedStack(){
linkedList = new MyDobbleLinkedList<E>();
}
/***
* @functionName:push
* @description:入栈。
* @param e
* @author yzh
* @date 2019-04-05
* @return E
*/
@Override
public E push(E e) {
linkedList.add(e);
size++;
return e;
}
/***
* @functionName:pop
* @description:出栈。
* @author yzh
* @date 2019-04-05
* @return E
*/
@Override
public E pop() {
//获取栈顶元素
E e = peek();
//删除栈顶元素
linkedList.deleteByIndex(--size);
return e;
}
/***
* @functionName:isEmpty
* @description:判断是否为空栈。
* @author yzh
* @date 2019-04-05
* @return boolean
*/
@Override
public boolean isEmpty() {
return size == 0;
}
/***
* @functionName:size
* @description:栈的大小。
* @author yzh
* @date 2019-04-05
* @return int
*/
public int size(){
return size;
}
/***
* @functionName:peek
* @description:获取栈顶的元素。
* @author yzh
* @date 2019-04-05
* @return E
*/
@Override
public E peek() {
if(isEmpty()){
throw new RuntimeException("this Stack is empty!");
}
E e = linkedList.getLastHead();
return e;
}
/***
* @functionName:search
* @description:获取元素在栈中的索引。
* @param e
* @author yzh
* @date 2019-04-05
* @return int
*/
@Override
public int search(E e) {
if(isEmpty()){
throw new RuntimeException("this Stack is empty!");
}
return getIndex(e);
}
/***
* @functionName:search
* @description:获取元素在栈中的索引
* @param e
* @author yzh
* @date 2019-04-05
* @return int
*/
private int getIndex(E e){
for(int i = size -1;i>=0;i--){
if(e == null && linkedList.get(i) == null){
return size() - i;
}else if(e != null && linkedList.get(i) != null && e.equals(linkedList.get(i))){
return size() - i;
}else{
continue;
}
}
return -1;
}
}
测试:
MyLinkedStack<String> stack = new MyLinkedStack<String>();
stack.push("1");
stack.push("2");
stack.push("3");
String str = null;
int len = stack.size();
for(int i = 0;i<len;i++){
str = stack.pop();
System.out.println(str);
}
/**output:
3
2
1
*/
3.4.3 基于数组实现栈(数组的一个应用)
在前面栈的实现中,都是通过现有的数据结构(现有的顺序表和现有的链表)来实现栈的,实际上,数组或者链式结构也能用于实现栈。对于栈而言,入栈和出栈是两个非常重要的操作。如果我们通过链式结构来实现栈,由于入栈和出栈都是在栈顶进行的,那么我们正好可以利用双端链式结构的优势来实现入栈和出栈操作;如果我们通过数组来实现入栈和出栈,那么对于入栈操作,我们需要考虑数组的扩容,这是数组相对链式结构而言耗时较多一个因素之一,然而这一点并不影响数组作为实现栈的一种流行方案。下面是使用数组实现栈的代码。
package com.yzh.maven.entity;
import com.yzh.maven.base.dao.MyStackDao;
public class MyStack<E> implements MyStackDao<E>{
private Object[] myElementData = {};
private int size;
/***
* @functionName:push
* @description:入栈。
* @param e
* @author yzh
* @date 2019-04-05
* @return E
*/
@Override
public E push(E e) {
int capacity = myElementData.length;
//确认数组是否需要扩容
if(capacity == size()){
ensureCapacity(capacity);
}
myElementData[size++] = e;
return e;
}
/***
* @functionName:ensureCapacity
* @description:扩容。
* @param capacity,数组的当前容量
* @author yzh
* @date 2019-04-05
* @return
*/
private void ensureCapacity(int capacity){
int oldCapacity = capacity;
int newCapacity = oldCapacity * 2 + 1;
Object[] oldMyElementData = myElementData;
myElementData = new Object[newCapacity];
for(int i = 0; i < oldCapacity;i++){
myElementData[i] = oldMyElementData[i];
}
}
/***
* @functionName:size
* @description:栈的大小。
* @author yzh
* @date 2019-04-05
* @return int
*/
public int size(){
return size;
}
/***
* @functionName:pop
* @description:出栈。
* @author yzh
* @date 2019-04-05
* @return E
*/
@Override
public E pop() {
//获取栈顶元素
E e = peek();
//删除栈顶元素
delete(--size);
return e;
}
/***
* @functionName:isEmpty
* @description:判断是否为空栈。
* @author yzh
* @date 2019-04-05
* @return boolean
*/
@Override
public boolean isEmpty() {
return size == 0;
}
/***
* @functionName:delete
* @description:按索引删除栈的元素。
* @param index 栈元素的索引
* @author yzh
* @date 2019-04-05
* @return
*/
private void delete(int index){
MyArraysUtils.arrayCopy(myElementData, index+1, myElementData, index, myElementData.length-(index+1));
//释放内存
myElementData[myElementData.length-1] = null;
}
/***
* @functionName:peek
* @description:获取栈顶的元素。
* @author yzh
* @date 2019-04-05
* @return E
*/
@SuppressWarnings("unchecked")
@Override
public E peek() {
if(isEmpty()){
throw new RuntimeException("this stack is empty!");
}
return (E) myElementData[size - 1];
}
/***
* @functionName:search
* @description:获取元素在栈中的索引。
* @param e
* @author yzh
* @date 2019-04-05
* @return int
*/
@Override
public int search(E e) {
if(isEmpty()){
throw new RuntimeException("this Stack is empty!");
}
return getIndex(e);
}
/***
* @functionName:search
* @description:获取元素在栈中的索引
* @param e
* @author yzh
* @date 2019-04-05
* @return int
*/
private int getIndex(E e){
for(int i = size -1;i>=0;i--){
if(e == null && myElementData[i] == null){
return size() - i;
}else if(e != null && myElementData[i] != null && e.equals(myElementData[i])){
return size() - i;
}else{
continue;
}
}
return -1;
}
}
测试:
MyStack<String> stack = new MyStack<String>();
stack.push("1");
stack.push("2");
stack.push("3");
String str = null;
int len = stack.size();
for(int i = 0;i<len;i++){
str = stack.pop();
System.out.println(str);
}
stack.pop();//java.lang.RuntimeException: this stack is empty!
/**output:
3
2
1
*/