数据结构篇——队列

一、仿写代码

        在循环队列中,当队列为空,可知 front=rear;而当所有队列空间全占满时,也有 front=rear。为了区别这两种情况,假设队列使用的数组有 k 个存储空间,size表示队头到队尾的长度,如果size==k则表示队列已满。根据以上可知,队列判空的条件是 front=rear,而队列判满的条件是 size == k。
        对于一个固定大小的数组,只要知道队尾rear 与队首 front,即可计算出队列当前的长度:

                                                (rear−front+k) mod k
循环队列的属性如下:

  • elements:一个固定大小的数组,用于保存循环队列的元素。
  • k:循环队列的容量,即队列中最多可以容纳的元素数量。
  • front:队列首元素对应的数组的索引。
  • rear:队列尾元素对应的索引的下一个索引。

循环队列的接口方法如下:

  • MyCircularQueue(int k): 初始化队列,同时base 数组的空间初始化大小为 k。front,rear 全部初始化为 0。
  • isEmpty():检测队列是否为空,根据之前的定义只需判断 rear 是否等于front。
  • isFull():检测队列是否已满,根据之前的定义只需判断 size 是否等于 k。
  • enQueue(int value):在队列的尾部插入一个元素,并同时将队尾的索引 rear 更新为 (rear+1) mod k。
  • deQueue():从队首取出一个元素,并同时将队首的索 front 更新为 (front+1) mod k。
  • Front():返回队首的元素,需要检测队列是否为空。
  • Rear():返回队尾的元素,需要检测队列是否为空。
  • showQueue():输出队列所有数据

数组法:

class MyCircularQueue {
	private int front;
	private int rear;
	private int size;
	private int k;
	private int[] elements;
	
	public static void main(String[] args) {
		MyCircularQueue myCircular = new MyCircularQueue(5);
		myCircular.enQueue(3);
		myCircular.enQueue(6);
		myCircular.enQueue(5);
		myCircular.deQueue();
		int a = myCircular.Front();
		int b = myCircular.Rear();
		System.out.println(a);
		System.out.println(b);
		myCircular.showQueue();
	}
	
	// 构造器
	public MyCircularQueue(int k) {
		this.k = k;
		elements = new int[k];
		rear = front = 0;
	}
	
	// 判断队列是否为空
	public boolean isEmpty() {                             
		return rear == front;
	}
		
	// 判断队列是否已满
	public boolean isFull() {                              
		return size == k;
	}
		
	// 在队列尾部插入一个元素
	public boolean enQueue(int value) {                    
		if(isFull()) {
			return false;
		}
		elements[rear] = value;
		rear = (rear + 1)%k;
		size++;
		return true;
	}
	
	// 从队列头部删除一个元素
	public boolean deQueue() {                              
		if(isEmpty()) {
			return false;
		}
		front = (front + 1)%k;
		size--;
		return true;
	}
	
	// 返回头部元素
	public int Front() {                                   
		if(isEmpty()) {
			return -1;
		}
		return elements[front];
	}
	
	// 返回尾部元素
	public int Rear() {                                    
		if(isEmpty()) {
			return -1;
		}
		return elements[(rear-1)%k];
	}
	
	// 显示队列所有数据
	public void showQueue() {
		if(isEmpty()) {
			System.out.println("队列为空,没有值~");
		}
		for(int i = front; i<rear; i++) {
			System.out.println(elements[i]);
		}
	}
}

链表法:

class MyCircularQueue{
	private int k,count;
	public static void main(String[] args) {
		MyCircularQueue myCircularQueue = new MyCircularQueue();
		myCircularQueue.Rear(3);
		myCircularQueue.Rear(5);
		myCircularQueue.Rear(6);
		myCircularQueue.poll();                    // 删除
		int a = myCircularQueue.peek();            // 返回队头
		myCircularQueue.poll();
		int b = myCircularQueue.poll();
		int c = myCircularQueue.peek();
		int d = myCircularQueue.size();            // 返回队列长度
		
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
		System.out.println(d);
		
	}
	
	public static class Node{
		public int val;
		public Node next;
		
		public Node(int val, Node next) {
			this.val = val;
			this.next = next;
		}
		
		public Node(int val) {
			this.val = val;
		}
	}
	
	public Node head;
	public Node last;
	
	// 尾部插入
	public void Rear(int val) {
		if(head == null) {
			head = new Node(val);
			last = head;
		}else {
			Node cur = new Node(val);
			last.next = cur;
			last = cur;
		}
		
	}
	
	// 从头部删除元素,并返回删除的数
	public int poll() {
		if(head == null || last == null) {
			return -1;
		}
		int val = head.val;
		head = head.next;
		return val;
		
	}
	
	// 返回头部元素,但不删除
	public int peek() {
		if(head == null || last == null) {
			return -1;
		}
		int val = head.val;
		return val;
		
	}
	
	// 队列长度
	public int size() {
		Node cur = head;
		int size = 0;
		while(cur!=null) {
			cur=cur.next;
			size++;
		}
		return size;
	}
}

二、算法题巩固

(1)用两个队列实现栈

类定义:

  • Queue类表示生成队列
  • Stack类表示生成栈

属性定义和方法定义看代码注释

// 创建队列
class Queue {
	private int front;
	private int rear;
	private int size;
	private int k;
	private int[] elements;
	
	// 构造器
	public Queue(int k) {
		this.k = k;
		elements = new int[k];
		rear = front = 0;
	}
	
	// 判断队列是否为空
	public boolean isEmpty() {                             
		return rear == front;
	}
		
	// 判断队列是否已满
	public boolean isFull() {                              
		return size == k;
	}
		
	// 在队列尾部插入一个元素
	public boolean offer(int value) {                    
		if(isFull()) {
			return false;
		}
		elements[rear] = value;
		rear = (rear + 1)%k;
		size++;
		return true;
	}
	
	// 从队列头部删除一个元素
	public int poll() {                              
		if(isEmpty()) {
			return -1;
		}
		int val = elements[front];
		front = (front + 1)%k;
		size--;
		return val;
	}
	
	// 返回头部元素
	public int peek() {                                   
		if(isEmpty()) {
			return -1;
		}
		return elements[front];
	}
	
	// 返回尾部元素
	public int Rear() {                                    
		if(isEmpty()) {
			return -1;
		}
		return elements[(rear-1)%k];
	}
	
	// 显示队列所有数据
	public void showQueue() {
		if(isEmpty()) {
			System.out.println("队列为空,没有值~");
		}
		for(int i = front; i<rear; i++) {
			System.out.println(elements[i]);
		}
	}
}


public class Stack {
	public static void main(String[] args) {
		Stack stack = new Stack();
		stack.push(1);
		stack.push(2);
		int a = stack.top();           // 返回栈顶元素
		stack.pop();                   // 删除并返回栈顶元素
		int b = stack.pop();
		System.out.println(a);
		System.out.println(b);
		System.out.print(stack.empty());
	}
	
	// 创建两个长度为5的队列对象
	Queue m1;
	Queue m2;
	
	public Stack() {
		m1 = new Queue(5);
		m2 = new Queue(5);
	}
	
	// 向栈中添加元素
	public void push(int val) {
		m2.offer(val);
		while(!m1.isEmpty()) {
			m2.offer(m1.poll());
		}
		Queue temp = m1;
		m1 = m2;
		m2 = temp;
	}
	
	// 移除并返回栈顶元素
	public int pop() {
		return m1.poll();
	}
	
	// 返回栈顶元素
	public int top() {
		return m1.peek();
	}
	
	// 判断栈是否为空
	public boolean empty() {
		return m1.isEmpty();
	}
	
}

(2)用单队列实现栈

public class Stack {
	public static void main(String[] args) {
		Stack stack = new Stack();
		stack.push(1);
		stack.push(2);
		int a = stack.top();           // 返回栈顶元素
		stack.pop();                   // 删除并返回栈顶元素
		int b = stack.pop();
		System.out.println(a);
		System.out.println(b);
		System.out.print(stack.empty());
	}
	
	// 创建两个长度为5的队列对象
	Queue m1;
	
	public Stack() {
		m1 = new Queue(5);
	}
	
	// 向栈中添加元素
	public void push(int val) {
		int n = m1.Size();
		m1.offer(val);
		// 单个队列实现栈
		for(int i = 0; i < n; i++) {
			m1.offer(m1.poll());
		}
	}
	
	// 移除并返回栈顶元素
	public int pop() {
		return m1.poll();
	}
	
	// 返回栈顶元素
	public int top() {
		return m1.peek();
	}
	
	// 判断栈是否为空
	public boolean empty() {
		return m1.isEmpty();
	}
	
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小修士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值