数据结构与算法(二)

队列

队列(queue) 是只允许在一端进行插入操作,而在另一端进行删除操作的线性表

     队列是一种先进先出的线性表,简称FOIO。允许插入一端称为队尾,允许删除的一端称为队头。队列符合我们的生活习惯例如排队,排在第一个的优先出列,最后来的只能插入到队伍最末尾。

    我们假设一个队列有n个元素,则顺序存储的队列需建立一个大于m的数组,并把队列的所有元素存储在数组的前n个单元,数组下标为0的一端即是队头。所滑的入队列操作,其实就是在队尾追加一个元素,不需要移动任何元素,因此时间复杂度为O(1)。队列元素的出列是在队头,即下标为0的位置,那也就意味着,队人列中的所有元素都得向前移动,以保证队列的队头,也就是下标为0的位置不为空,此时时间复杂度为O(n);

下面用数组模拟实现队列:

package com.jxust.queue;


import java.util.Scanner;

public class ArrayQueueDemo {
    public static void main(String[] args) {

        ArratQueue queue=new ArratQueue(3);

        Scanner choice=new Scanner(System.in);
        while (true){
            System.out.println("1:显示队列");
            System.out.println("2.添加数据");
            System.out.println("3.取出数据");
            System.out.println("4.查看队列头");
            System.out.println("5.退出");
            int key=choice.nextInt();
            switch (key){
                case 1:
                    queue.show();
                    break;
                case 2:
                    System.out.println("输入一个数");
                    int d=choice.nextInt();
                    queue.add(d);
                    break;
                case 3:
                    try {
                        int d1=queue.get();
                        System.out.println("取出的数为"+d1);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 4:
                    try {
                        int d2= queue.head();
                        System.out.println("队列头是"+d2);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 5:
                    queue.exit();
                    break;
                default:
                    break;
            }
        }
    }




}

class ArratQueue {
    private int maxSize;//表示数组的最大容量
    private int front;//队列头,队列头前一个位置(不是队列第一个元素)
    private int rear;//队列尾(队尾最后一个数据)
    private int [] arr ;//该数据用于存放数据


    public ArratQueue(int arrMaxSize){
        maxSize=arrMaxSize;
        arr =new int [maxSize];
        front=-1;//指向队列头部
        rear=-1;//指向队列尾
    }

    //判断队列是否满
    public boolean isFull(){
        return rear==maxSize-1;
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return rear==front;
    }

    //添加数据到队列
    public void add(int n){
        if(isFull()) {
            System.out.println("队列已满 不能加入");
            return;
        }

        rear++;
        arr[rear]=n;
    }

    public int get(){
        if(isEmpty()){
            throw new RuntimeException("队列空,不能取数据");
        }
        front++;
        return arr[front];
    }

    //显示队列所有数据
    public void show(){
        if (isEmpty()){
            System.out.println("队列空");return;
        }

        for (int i = 0; i <arr.length ; i++) {
            System.out.printf("arr[%d]=%d\n",i,arr[i]);
        }
//      for (int i = front; i!=rear+1 ; i++) {
//          System.out.printf("arr[%d]=%d\n",i,arr[i]);
//      }
    }


    public int head(){
        if (isEmpty()){
            throw new RuntimeException("队列空");
        }
        return arr[front+1];
    }
    public void exit(){
        System.exit(0);
    }


}

 循环队列

       为了解决假溢出的办法很简单,就是后面满了,就再从头开始,也就是头尾相连的循环。我们把队列的这种头尾相连的顺序存储结构称为循环队列。

 

 

 

 下面代码实现循环队列:

package com.jxust.queue;

import java.util.Scanner;

public class CircleArrayDeom {

    public static void main(String[] args) {

        CircleArray ca = new CircleArray(4);
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("输入1,显示队列");
            System.out.println("输入2,加入数据");
            System.out.println("输入3,取出数据");
            System.out.println("输入4,显示头数据");
            int input = sc.nextInt();
            switch (input) {
                case 1:
                    ca.show();
                    break;
                case 2:
                    System.out.println("输入你所要加入的数字");
                    int addnum = sc.nextInt();
                    ca.add(addnum);
                    break;
                case 3:
                    System.out.println("你取出的数为" + ca.get());
                case 4:
                    System.out.println("头数据为" + ca.head());
                    break;
                default:
                    break;
            }
        }
    }


}

class CircleArray {
    private int maxSize;//表示数组的最大容量
    private int front = 0;//队列头
    private int rear = 0;//队列尾(队尾最后一个数据)
    private int[] arr;//该数据用于存放数据

    public CircleArray(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
    }

    //判断队列是否满
    public boolean isFull() {
        return (rear+1)%maxSize == front;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear==front;
    }

    //添加数据到队列
    public void add(int n) {
        if (isFull()) {
            System.out.println("队列已满 不能加入");
            return;
        }
        arr[rear] = n;
        rear = (rear + 1) % maxSize;

    }

    public int get() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,不能取数据");
        }

        int valuer = arr[front];
        front = (front + 1) % maxSize;
        return valuer;
    }

    //显示队列所有数据
    public void show() {
        if (isEmpty()) {
            System.out.println("队列空");
            return;
        }

        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
//      for (int i = front; i!=rear+1 ; i++) {
//          System.out.printf("arr[%d]=%d\n",i,arr[i]);
//      }
    }

    public int size() {
        return (rear + maxSize - front) % maxSize;
    }


    public int head() {
        if (isEmpty()) {
            throw new RuntimeException("队列空");
        }
        return arr[front];
    }

    public void exit() {
        System.exit(0);
    }
}

栈练习题

 输入样例:

10
push 5
query
push 6
pop
query
pop
empty
push 4
query
empty

输出样例:

5
5
YES
4
NO
#include<iostream>
using namespace std;

const int N=100010;
int m;

int stk[N],tt;

int main(){
  cin>>m;
    while (m--){
        string c; int x;
        cin>>c;
        
        if(c=="push") {  cin>>x; stk[++tt]=x;}
        
        else if(c=="pop"){ tt--;}
        
        else if(c=="empty") cout<<(tt ? "NO":"YES")<<endl;
        
        else cout<<stk[tt]<<endl;
    }
   
   return 0;
}

 

输入样例

(2+2)*(1+1)

输出样例:

8

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack> 
#include<unordered_map>
using namespace std;

stack<int> num;//栈
stack<char> op;

void eval()
{
    auto b = num.top(); num.pop();
    auto a = num.top(); num.pop();
    auto c = op.top(); op.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    num.push(x);
}




int main(){
    unordered_map<char,int> pr{{'+',1},{'-',1},{'*',2},{'/',2} };
    string str; 
    
    cin>>str;
    
    for(int i=0;i<str.size();i++)
    {
        auto c=str[i];
        if(isdigit(c)){ //isdigit()函数判断当前输入的字符串是否是由数字组成
            int x=0,j=i;
            while(j<str.size()&&isdigit(str[j]))
               x=x*10+str[j++]-'0';
               num.push(x);
               i=j-1;
        }
        
        else if(c=='(' )op.push(c);
        else if(c==')'){
            while(op.top() != '(' )  eval();
            op.pop();
        }
        
        else{
            while(op.size()&&pr[op.top()]>=pr[c]) eval();
            op.push(c);
        }
        
        
    }
    
    while(op.size()) eval();
    
    cout<<num.top()<<endl;
    return 0;
    
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值