歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java實現棧和隊列

Java實現棧和隊列

日期:2017/3/1 9:27:41   编辑:Linux編程

棧:LIFO(後進先出)

隊列:FIFO(先進先出)

棧的順序存儲結構實現:

/**
* 基於數組實現的順序棧
* @param <E>
*/
public class Stack<E> {
private Object[] data = null;
private int maxSize=0; //棧容量
private int top =-1; //棧頂指針

/**
* 構造函數:根據給定的size初始化棧
*/
Stack(){
this(10); //默認棧大小為10
}

Stack(int initialSize){
if(initialSize >=0){
this.maxSize = initialSize;
data = new Object[initialSize];
top = -1;
}else{
throw new RuntimeException("初始化大小不能小於0:" + initialSize);
}
}

//判空
public boolean empty(){
return top==-1 ? true : false;
}

//進棧,第一個元素top=0;
public boolean push(E e){
if(top == maxSize -1){
throw new RuntimeException("棧已滿,無法將元素入棧!");
}else{
data[++top]=e;
return true;
}
}

//查看棧頂元素但不移除
public E peek(){
if(top == -1){
throw new RuntimeException("棧為空!");
}else{
return (E)data[top];
}
}

//彈出棧頂元素
public E pop(){
if(top == -1){
throw new RuntimeException("棧為空!");
}else{
return (E)data[top--];
}
}

//返回對象在堆棧中的位置,以 1 為基數
public int search(E e){
int i=top;
while(top != -1){
if(peek() != e){
top --;
}else{
break;
}
}
int result = top+1;
top = i;
return result;
}
}

棧的鏈式存儲結構實現:

public class LinkStack<E> {
//鏈棧的節點
private class Node<E>{
E e;
Node<E> next;

public Node(){}
public Node(E e, Node next){
this.e = e;
this.next = next;
}
}

private Node<E> top; //棧頂元素
private int size; //當前棧大小

public LinkStack(){
top = null;
}

//當前棧大小
public int length(){
return size;
}

//判空
public boolean empty(){
return size==0;
}

//入棧:讓top指向新創建的元素,新元素的next引用指向原來的棧頂元素
public boolean push(E e){
top = new Node(e,top);
size ++;
return true;
}

//查看棧頂元素但不刪除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空棧異常!");
}else{
return top;
}
}

//出棧
public Node<E> pop(){
if(empty()){
throw new RuntimeException("空棧異常!");
}else{
Node<E> value = top; //得到棧頂元素
top = top.next; //讓top引用指向原棧頂元素的下一個元素
value.next = null; //釋放原棧頂元素的next引用
size --;
return value;
}
}
}

基於LinkedList實現的棧結構:

import java.util.LinkedList;

/**
* 基於LinkedList實現棧
* 在LinkedList實力中只選擇部分基於棧實現的接口
*/
public class StackList<E> {
private LinkedList<E> ll = new LinkedList<E>();

//入棧
public void push(E e){
ll.addFirst(e);
}

//查看棧頂元素但不移除
public E peek(){
return ll.getFirst();
}

//出棧
public E pop(){
return ll.removeFirst();
}

//判空
public boolean empty(){
return ll.isEmpty();
}

//打印棧元素
public String toString(){
return ll.toString();
}
}

隊列的順序存儲結構實現

public class Queue<E> {
private Object[] data=null;
private int maxSize; //隊列容量
private int front; //隊列頭,允許刪除
private int rear; //隊列尾,允許插入

//構造函數
public Queue(){
this(10);
}

public Queue(int initialSize){
if(initialSize >=0){
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear =0;
}else{
throw new RuntimeException("初始化大小不能小於0:" + initialSize);
}
}

//判空
public boolean empty(){
return rear==front?true:false;
}

//插入
public boolean add(E e){
if(rear== maxSize){
throw new RuntimeException("隊列已滿,無法插入新的元素!");
}else{
data[rear++]=e;
return true;
}
}

//返回隊首元素,但不刪除
public E peek(){
if(empty()){
throw new RuntimeException("空隊列異常!");
}else{
return (E) data[front];
}
}

//出隊
public E poll(){
if(empty()){
throw new RuntimeException("空隊列異常!");
}else{
E value = (E) data[front]; //保留隊列的front端的元素的值
data[front++] = null; //釋放隊列的front端的元素
return value;
}
}

//隊列長度
public int length(){
return rear-front;
}
}

循環隊列的順序存儲結構實現

import java.util.Arrays;

public class LoopQueue<E> {
public Object[] data = null;
private int maxSize; // 隊列容量
private int rear;// 隊列尾,允許插入
private int front;// 隊列頭,允許刪除
private int size=0; //隊列當前長度

public LoopQueue() {
this(10);
}

public LoopQueue(int initialSize) {
if (initialSize >= 0) {
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear = 0;
} else {
throw new RuntimeException("初始化大小不能小於0:" + initialSize);
}
}

// 判空
public boolean empty() {
return size == 0;
}

// 插入
public boolean add(E e) {
if (size == maxSize) {
throw new RuntimeException("隊列已滿,無法插入新的元素!");
} else {
data[rear] = e;
rear = (rear + 1)%maxSize;
size ++;
return true;
}
}

// 返回隊首元素,但不刪除
public E peek() {
if (empty()) {
throw new RuntimeException("空隊列異常!");
} else {
return (E) data[front];
}
}

// 出隊
public E poll() {
if (empty()) {
throw new RuntimeException("空隊列異常!");
} else {
E value = (E) data[front]; // 保留隊列的front端的元素的值
data[front] = null; // 釋放隊列的front端的元素
front = (front+1)%maxSize; //隊首指針加1
size--;
return value;
}
}

// 隊列長度
public int length() {
return size;
}

//清空循環隊列
public void clear(){
Arrays.fill(data, null);
size = 0;
front = 0;
rear = 0;
}
}

隊列的鏈式存儲結構實現

public class LinkQueue<E> {
// 鏈棧的節點
private class Node<E> {
E e;
Node<E> next;

public Node() {
}

public Node(E e, Node next) {
this.e = e;
this.next = next;
}
}

private Node front;// 隊列頭,允許刪除
private Node rear;// 隊列尾,允許插入
private int size; //隊列當前長度

public LinkQueue() {
front = null;
rear = null;
}

//判空
public boolean empty(){
return size==0;
}

//插入
public boolean add(E e){
if(empty()){ //如果隊列為空
front = new Node(e,null);//只有一個節點,front、rear都指向該節點
rear = front;
}else{
Node<E> newNode = new Node<E>(e, null);
rear.next = newNode; //讓尾節點的next指向新增的節點
rear = newNode; //以新節點作為新的尾節點
}
size ++;
return true;
}

//返回隊首元素,但不刪除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空隊列異常!");
}else{
return front;
}
}

//出隊
public Node<E> poll(){
if(empty()){
throw new RuntimeException("空隊列異常!");
}else{
Node<E> value = front; //得到隊列頭元素
front = front.next;//讓front引用指向原隊列頭元素的下一個元素
value.next = null; //釋放原隊列頭元素的next引用
size --;
return value;
}
}

//隊列長度
public int length(){
return size;
}
}

基於LinkedList實現隊列結構

/**
* 使用java.util.Queue接口,其底層關聯到一個LinkedList(雙端隊列)實例.
*/
import java.util.LinkedList;
import java.util.Queue;

public class QueueList<E> {
private Queue<E> queue = new LinkedList<E>();

// 將指定的元素插入此隊列(如果立即可行且不會違反容量限制),在成功時返回 true,
//如果當前沒有可用的空間,則拋出 IllegalStateException。
public boolean add(E e){
return queue.add(e);
}

//獲取,但是不移除此隊列的頭。
public E element(){
return queue.element();
}

//將指定的元素插入此隊列(如果立即可行且不會違反容量限制),當使用有容量限制的隊列時,
//此方法通常要優於 add(E),後者可能無法插入元素,而只是拋出一個異常。
public boolean offer(E e){
return queue.offer(e);
}

//獲取但不移除此隊列的頭;如果此隊列為空,則返回 null
public E peek(){
return queue.peek();
}

//獲取並移除此隊列的頭,如果此隊列為空,則返回 null
public E poll(){
return queue.poll();
}

//獲取並移除此隊列的頭
public E remove(){
return queue.remove();
}

//判空
public boolean empty() {
return queue.isEmpty();
}
}

Copyright © Linux教程網 All Rights Reserved