1. 程式人生 > >java 棧+佇列資料結構

java 棧+佇列資料結構

也是一種線性結構,其實你就可以把理解為陣列,只能從一端新增元素,也只能從哪一端刪除資料。

這一端稱為棧頂,

棧是一種後進先出的資料結構,可以理解,吃了就吐

力扣的一道題 利用棧來解答

以下是java程式碼

package com.binglian.stack;

import java.util.Stack;

/**
 * 棧
 *  括號匹配應用
 * @author binglian
 *
 */
public class Solution {
	
	public boolean isValid(String s){
		Stack<Character> stack=new Stack<Character>();
		for(int i=0;i<s.length();i++){
			char c=s.charAt(i);
			if(c == '(' || c == '[' || c == '{')
				stack.push(c);
			else{
				if(stack.isEmpty())
					return false;
				
				char topChar =stack.pop();
				if(c == ')' && topChar != '(')
					return false;
				if(c == ']' && topChar !='[')
					return false;
				if(c == '}' && topChar != '{')
					return false;
			}
		}
		
		return stack.isEmpty();
	}
}

佇列

然後是我們的佇列

佇列和棧都是一種線性結構 就是一條線 可以認為這樣

只能從一端新增元素(隊尾),從另一端取出元素(隊首)

先進先出、吃了就拉

可以使用陣列來實現佇列,我這裡用迴圈佇列

以下是思路

front==tail 佇列為空(隊首和隊尾相等那麼就為空)

(tail+1)%c ==front佇列滿(如果隊尾加1  佇列的元素 取餘 相等那麼就為滿,是不是覺得和上面那個很像,其實這裡是 和佇列元素長度取餘在判斷)

在迴圈佇列要浪費一個空間,

 

以下程式碼,要仔細看哦 有註解的

package com.binglian.stack;


/**
 * 迴圈佇列
 * @author binglian
 *
 * @param <E>
 */
public class LoopQueue<E>  {
	
	private E[] data;
	private int front,tail;//front 隊頭 tail隊尾
	private int size;//元素長度
	
	/**
	 * 構造方法 生成初始化佇列 
	 * @param capacity
	 */
	public LoopQueue(int capacity){
		data=(E[])new Object[capacity+1];
		front=0;
		tail=0;
		size=0;
	}
	
	/**
	 * 預設長度為10的佇列
	 */
	public LoopQueue(){
		this(10);
	}
	
	/**
	 * 因為迴圈佇列最後要被浪費一個空間 所以減一
	 * @return
	 */
	public int getCapacity(){
		return data.length-1;
	}
	
	/**
	 * 判斷是否為空
	 */
	public boolean isEmpty(){
		return front == tail;//隊尾和隊首相等那麼沒有元素
	}
	
	/**
	 * 佇列元素長度
	 * @return
	 */
	public int getSize(){
		return size;
	}
	
	/**
	 * 入隊操作
	 */
	public void enqueue(E e){
		if((tail+1) % data.length ==front){//如果tail+1 %data的長度 等於隊首那麼就滿了
			resize(getCapacity()*2);//滿了之後建立新的佇列並吧 新的佇列元素放進去
		}
		data[tail]=e;
		tail=(tail+1)%data.length;
		size++;
	}
	
	/**
	 * 移除元素
	 */
	public E dequeue(){
		if(isEmpty())
			throw new IllegalArgumentException("佇列為空,沒有元素,可以移除");
		
		E ret=data[front];
		data[front]=null;
		front=(front+1) %data.length;
		size--;
		if(size == getCapacity() /4 && getCapacity() /2 !=0 )//判斷 佇列是否有多餘空與空間 然後進行縮小佇列
			resize(getCapacity()/2);
		return ret;
	}
	
	/**
	 * 檢視隊首元素
	 * @return
	 */
	public E getFron(){
		if(isEmpty())
			throw new IllegalArgumentException("佇列為空,沒有元素,");
		return data[front];
	}
	/**
	 * 建立新的佇列,並把資料移進去
	 * @param newCapacity
	 */
	private void resize(int newCapacity){
		E[] newData=(E[])new Object[newCapacity +1];//建立新的佇列
		
		//吧原來佇列的元素,移到新的佇列
		for(int i=0;i<size;i++){
			newData[i]=data[(i+front)% data.length];//重點
		}
		data=newData;
		front=0;
		tail=size;
	}
	
	@Override
	public String toString(){
		StringBuilder res=new StringBuilder();
		res.append(String.format("Queue:size=%d,capacity=%d\n", size,getCapacity()));
		res.append("front[");
		for (int i = front; i !=tail;i=(i+1) %data.length) {
			res.append(data[i]);
			if((i+1)%data.length !=tail)
				res.append(",");
			
		}
		res.append("]tail");
		return res.toString();
	}
	
	public static void main(String[] args) {
		LoopQueue<Integer> queue=new LoopQueue<Integer>();
		for(int i=0;i<10;i++){
			queue.enqueue(i);
			System.out.println(queue);
			
			if(i%3 ==2){
				queue.dequeue();
				System.out.println(queue);
			}
		}
	}
}


github地址https://github.com/binlian/binglian-DateStructure