死磕算法-数组栈和队列

数组实现固定大小的栈

public class Array2Stack<T> {
	
	private T[] arr;
	//size就是添加元素要存放的位置
	private Integer size;
	
	public Array2Stack(int initSize) {
		if(initSize < 0) {
			throw new IllegalArgumentException("The initSize must more than zero");
		}else {
			arr = (T[]) new Object[initSize];
			size=0;
		}
	}
	
	
	public T peek() {
		if(size == 0) {
			return null;
		}else {
			return arr[size-1];
		}
	}
	
	
	public void push(T obj) {
		if(size == arr.length) {
			throw new ArrayIndexOutOfBoundsException("The Stack is full");
		}
		arr[size++] = obj;
	}
	
	public T pop() {
		if (size == 0) {
			throw new ArrayIndexOutOfBoundsException("The queue is empty");
		}
		return arr[--size];
	}
}

数组实现循环队列

理解循环队列
循环队列可以解决普通队列的"假溢出"问题。

循环队列如何判断队满?
循环队列就可以用来解决 假溢出 问题, 当队列后面的满了,就从头在开始,形成头尾相接的循环.。 出现的问题: front=rear即头指针和尾指针相等,但是对应两种情况:一种是队列是空,一种是队列是满。
因此,我们定义循环队列中空出一个位置为满队列状态。front指向头元素,rear指向尾元素的下一个位置
在这里插入图片描述

head表示弹出时的位置
tail表示添加元素的位置

循环队列长度计算?

  • 情况一:当tail大于head时,循环队列长度为 head - tail
  • 情况二:当tail小于head时,循环队列的长度:分为两部分计算 0+tail 和 Quesize-head , 将两部分的长度合并到一起即为: tail-head+Quesize
public class Array2Queue {

    private int[] d = null;// 队列空间
    private int head = 0;// 队列头索引
    private int tail = 0;// 队列尾索引
    private int len = 0;// 队列最大长度

    public Array2Queue(int len) {
        this.len = len;
        d = new int[len];
    }

    //入队函数
    public void push(int x) {
        if (isFull()) {
            System.out.println("队列已满,入队失败");
        } else {
            d[tail] = x;
            tail = (tail + 1) % len;
        }
    }

    //出队函数
    public void pop() {
        if (isEmpty()) {
            System.out.println("队列为空,出对失败");
        } else {
            head = (head + 1) % len;
        }
    }
    
    //查看队首元素
    public int front() {
        return d[head];
    }

    //查看队尾元素
    public int back() {
        return d[(tail + len - 1) % len];
    }

    //查看队列元素总数
    public int size() {
        return (tail + len - head) % len-1;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        //头尾索引相等表示队列为空
        if (tail == head)
            return true;
        return false;
    }

    //判断队列是否为满
    public boolean isFull() {
        //尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定
        if ((tail + 1) % len == head)
            return true;
        return false;
    }

    
}

队列结构实现栈

用队列实现栈,可以用两个队列实现,一个用来插入数据,一个用来返回数据。push时直接把数据放在第一个队列中,pop时先把第一个队列里除了最后一个push进去的数全部push进第二个队列,最后的元素就是我们要pop出的元素,pop出后再把第二个队列中的数放进队列一,实际上直接交换引用也可以。

ext_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDI4ODM4MQ==,size_16,color_FFFFFF,t_70)

简单理解就是在需要弹栈时将队列其他元素全部Poll进另一个队列,留下最后一个元素即可

public static class TwoQueuesStack {
		private Queue<Integer> queue;
		private Queue<Integer> help;

		public TwoQueuesStack() {
			queue = new LinkedList<Integer>();
			help = new LinkedList<Integer>();
		}

		public void push(int pushInt) {
			queue.add(pushInt);
		}

		public int peek() {
			if (queue.isEmpty()) {
				throw new RuntimeException("Stack is empty!");
			}
			while (queue.size() != 1) {
				help.add(queue.poll());
			}
			int res = queue.poll();
			help.add(res);
			//交换引用,将Data队列和Help队列互换
			swap();
			return res;
		}

		public int pop() {
			if (queue.isEmpty()) {
				throw new RuntimeException("Stack is empty!");
			}
			while (queue.size() > 1) {
				help.add(queue.poll());
			}
			int res = queue.poll();
			//交换引用,将Data队列和Help队列互换
			swap();
			return res;
		}

		private void swap() {
			Queue<Integer> tmp = help;
			help = queue;
			queue = tmp;
		}

	}

栈结构实现队列

用栈实现队列结构,同样需要两个栈实现,一个栈用来Poll数据,另一个用来Push数据。Push时将数据放进栈一,Poll时将栈1的数据都放进栈2再Poll。
在这里插入图片描述

通过两个栈实现队列的先进先出

public static class TwoStacksQueue {
		private Stack<Integer> stackPush;
		private Stack<Integer> stackPop;

		public TwoStacksQueue() {
			stackPush = new Stack<Integer>();
			stackPop = new Stack<Integer>();
		}

		public void push(int pushInt) {
			stackPush.push(pushInt);
		}

		//将Push栈的元素Pop进Pop栈,这样就可以做到队列的先进先出
		public int poll() {
			if (stackPop.empty() && stackPush.empty()) {
				throw new RuntimeException("Queue is empty!");
			} else if (stackPop.empty()) {
				while (!stackPush.empty()) {
					stackPop.push(stackPush.pop());
				}
			}
			return stackPop.pop();
		}

		public int peek() {
			if (stackPop.empty() && stackPush.empty()) {
				throw new RuntimeException("Queue is empty!");
			} else if (stackPop.empty()) {
				while (!stackPush.empty()) {
					stackPop.push(stackPush.pop());
				}
			}
			return stackPop.peek();
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值