数据结构学习笔记

162 阅读3分钟

稀疏数组

简介

  当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组保存该数组

处理方法

  • 记录数组共有几行几列,有多少不同的值
  • 把具有不同指的元素的行列以及值记录在一个小规模的数组中,从而缩小程序的规模

二维数组转稀疏数组

  • 遍历原始二维数组,得到有效数据的个数sum
  • 根据sum就可以创建稀疏数组sparseArr int[sum+1][3]
  • 将二维数组的有效数据存入到稀疏数组中

稀疏数组转二维数组

  • 稀疏数组的第一行保存的原始数组的元数据,行列以及有效数据(有意义的数据),根据首行数据,创建原始的二维数组
  • 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可

原始数组转二维数组

public static void main(String[] args) {
        //原始数据
        int[][] orgArr = new int[11][10];
        //添加数据
        orgArr[1][2] = 2;
        orgArr[2][3] = 4;
        //统计有效数据
        int sum = 0;
        System.out.println("原始数组:");
        for (int i = 0;i<orgArr.length;i++){
            for (int j = 0;j<orgArr[i].length;j++){
                System.out.print(String.format("%d\t",orgArr[i][j]));
                if (!Objects.equals(0,orgArr[i][j]))
                    sum++;
            }
            System.out.println();
        }
        //原始数组转稀疏数组
        int[][] sparseArr = new int[sum+1][3];
        //记录原始数组的元数据
        sparseArr[0][0] = orgArr.length;
        sparseArr[0][1] = orgArr[0].length;
        sparseArr[0][2] = sum;
        //设置计数器
        int folow = 1;
        for (int i = 0;i<orgArr.length;i++){
            for (int j = 0;j<orgArr[i].length;j++){
                if (!Objects.equals(0,orgArr[i][j])){
                    sparseArr[folow][0] = i;
                    sparseArr[folow][1] = j;
                    sparseArr[folow][2] = orgArr[i][j];
                    if (Objects.equals(folow,sum))
                        break;
                    folow++;
                }
            }
        }
        System.out.println("稀疏数组:");
        for (int i = 0;i<sparseArr.length;i++){
            for (int j = 0;j<sparseArr[i].length;j++){
                System.out.print(String.format("%d\t",sparseArr[i][j]));
            }
            System.out.println();
        }

    }

队列

介绍

  • 队列是一个有序列表,可以用数组或者链表实现
  • 遵循先入先出的原则:先存入的数据,要先取出来;后存入的数据后取出来
  • 示意图:
class ArrayQueue{

    //队列最大容量
    private int maxSize;
    //队列头部
    private int front;
    //队列尾部
    private int rear;
    //队列
    private int[] arr;

    //队列构造器
    public ArrayQueue(int maxSize){
        this.maxSize = maxSize;
        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 num) {
        if (isFull())
            throw new RuntimeException("队列已满");
        rear++;
        arr[rear] = num;
    }

    //获取数据
    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.println(String.format("arr[%d]=%d/n",i,arr[i]));
        }
    }

    //展示队列头部数据
    public int showFront(){
        if (isEmpty())
            throw new RuntimeException("队列已经空了~");
        return arr[front+1];
    }

}

上述队列结构只能使用一次,不能做到重复使用

  • 尾索引的下一个是头索引则表示队列已满,即将队列容量作为一个约定(rear+1)%maxSize =front 队列已满
  • rear = front 队列为空
class CircleArrayQueue{

    //队列最大容量
    private int maxSize;
    //front 变量含义:指向队列第一个元素  front初始值尾0
    private int front;
    //rear指向最后一个元素的后一个位置   rear初始值尾0
    private int rear;
    //队列
    private int[] arr;

    //初始化
    public CircleArrayQueue(int maxSize){
        this.maxSize = maxSize;
        front = 0;
        rear = 0;
        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())
            throw new RuntimeException("队列已满");
        arr[rear] = n;
        rear = (rear+1) % maxSize;
    }

    //获取数据
    public int get(){
        if (isEmpty())
            throw new RuntimeException("队列已空");
        //获取当前第一个变量值
        int value = arr[front];
        //将front后移
        front = (front+1) % maxSize;
        return value;
    }

    //获取有效数据的小标
    public int size(){
        return (rear + maxSize- front) % maxSize;
    }
}