题记
我们知道,在数组中,若知道数据项的下标,便可立即访问该数据项,或者通过顺序搜索数据项,访问到数组中的各个数据项。但是栈和队列不同,它们的访问是受限制的,即在特定时刻只有一个数据项可以被读取或者被删除。众所周知,栈是先进后出,只能访问栈顶的数据,队列是先进先出,只能访问头部数据。这里不再赘述。
栈的主要机制可以用数组来实现,也可以用链表来实现,
下面分别使用两种来实现栈基本操作:
/**
* 栈 先进后出
* 数组来实现栈的基本操作
* @author fancy
* @date 2018-12-05 09:31
*/
public class ArrayStack {
//存取数据
private int[] array;
//栈大小
private int size;
//栈顶部数据下标
private int topIndex;
public ArrayStack(int size) {
this.array = new int[size];
this.size = size;
//初始化为-1 表示空栈
this.topIndex = -1;
}
/**
* 压入数据
* @author fancy
* @param value
*/
public void push (int value) {
if (isFull()) {
throw new OutOfMemoryError("空间已满!");
}
array[++topIndex] = value;
}
/**
* 弹出栈顶数据/并且删除数据
* @author fancy
*/
public int pop () throws Exception {
if (isEmpty()) {
throw new Exception("栈为空");
}
if (topIndex > size) {
throw new ArrayIndexOutOfBoundsException("下标越界");
}
int i = array[topIndex];
// 初始化顶部
array[topIndex] = 0;
topIndex --;
return i;
}
/**
* 返回栈顶部数据 - 不删除顶部数据
* @return
*/
public int peek () throws Exception {
if (isEmpty()) {
throw new Exception("栈为空");
}
if (topIndex > size) {
throw new ArrayIndexOutOfBoundsException("下标越界");
}
return array[topIndex];
}
/**
* 判断栈是否满的
* @return
*/
private boolean isFull () {
if (topIndex == size) {
return true;
}
return false;
}
/**
* 判断栈是否是空的
* @return
*/
private boolean isEmpty () {
if (topIndex == -1) {
return true;
}
return false;
}
}
/**
* 栈 先进后出
* 链表实现 栈的基本操作
* @author fancy
* @date 2018-12-05 11:02
*/
public class LinkedListStack {
private MyLinkedList list;
public LinkedListStack () {
this.list = new MyLinkedList();
}
public int getSize() {
return this.list.getSize();
}
public boolean isEmpty() {
if (list.getSize() == 0) {
return true;
}
return false;
}
/**
* 压栈
* @author fancy
* @param value
*/
public void push(int value) {
list.set(list.getSize(), value);
}
/**
* 弹栈
* @author fancy
* @return
*/
public int pop() {
return list.remove(list.getSize());
}
public int peek() {
return list.get(list.getSize());
}
}
/**
* 单项链表 - 组成一个环形
* 链表没有下标
* @author fancy
* @date 2018-12-05 11:03
*/
public class MyLinkedList{
private Node currentNode;
private int size;
public MyLinkedList(){
currentNode = new Node();
size = 0;
}
// 获取链表中的元素个数
public int getSize(){
return size;
}
// 返回链表是否为空
public boolean isEmpty(){
return size == 0;
}
// 在链表的index(0-based)位置添加新的元素e
// 在链表中不是一个常用的操作,练习用:)
public void add(int index, int data){
if(index < 0 || index > size){
throw new IllegalArgumentException("Add failed. Illegal index.");
}
Node prev = currentNode;
for(int i = 0 ; i < index ; i ++){
prev = prev.getNext();
}
prev.setNext(new Node(data, prev.getNext()));;
size ++;
}
// 获得链表的第index(0-based)个位置的元素
// 在链表中不是一个常用的操作,练习用:)
public int get(int index){
if(index < 0 || index >= size){
throw new IllegalArgumentException("Get failed. Illegal index.");
}
Node cur = currentNode.getNext();
for(int i = 0 ; i < index ; i ++){
cur = cur.getNext();
}
return cur.getData();
}
// 修改链表的第index(0-based)个位置的元素为e
// 在链表中不是一个常用的操作,练习用:)
public void set(int index, int data){
if(index < 0 || index >= size){
throw new IllegalArgumentException("Update failed. Illegal index.");
}
Node cur = currentNode.getNext();
for(int i = 0 ; i < index ; i ++){
cur = cur.getNext();
}
cur.setData(data);
size ++;
}
// 查找链表中是否有元素e
public boolean contains(int value){
Node cur = currentNode.getNext();
while(cur != null){
if(cur.getData() == value){
return true;
}
cur = cur.getNext();
}
return false;
}
// 从链表中删除index(0-based)位置的元素, 返回删除的元素
// 在链表中不是一个常用的操作,练习用:)
public int remove(int index){
if(index < 0 || index >= size){
throw new IllegalArgumentException("Remove failed. Index is illegal.");
}
Node prev = currentNode;
for(int i = 0 ; i < index ; i ++){
prev = prev.getNext();
}
Node retNode = prev.getNext();
prev.setNext(retNode.getNext());
retNode.setNext(null);
size --;
return retNode.getData();
}
}
/**
* 单向链表节点
* @author fancy
* @date 2018-12-05 11:34
*/
public class Node {
private int data;
//下个节点
private Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}