稀疏数组与环形队列

稀疏数组

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

稀疏数组的处理方法是:

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

图解
原始数组转稀疏数组图解
代码实现

import java.util.Arrays;

/**
 * @author:西瓜菌
 * @date:2022年3月16日上午8:48:11
 * @Description:稀疏数组
 */
public class SparseArray {
	public static void main(String[] args) {
		int[][] oriArr = createArr();
		// 遍历原始数组
		System.out.println("原始数组:");
		for(int[] ele : oriArr) {
			System.out.println(Arrays.toString(ele));
		}
		
		// 原始数组转稀疏数组
		int[][] spaArr = arrToSparse(oriArr);
		// 遍历稀疏数组
		System.out.println("稀疏数组:");
		for(int[] ele : spaArr) {
			System.out.println(Arrays.toString(ele));
		}
		
		// 稀疏数组转原始数组
		int[][] arr = spaToArr(spaArr);
		// 遍历稀疏数组
		System.out.println("原始数组:");
		for(int[] ele : arr) {
			System.out.println(Arrays.toString(ele));
		}
	}
	
	// 创建二维数组
	private static int[][] createArr(){
		int[][] original = new int[5][7];
		original[0][3] = 22;
		original[0][6] = 15;
		original[1][1] = 11;
		original[1][5] = 17;
		original[2][3] = -6;
		original[3][0] = 91;
		original[3][5] = 39;
		original[4][2] = 28;
		return original;
	}
	
	// 将二维数组转为稀疏数组
	private static int[][] arrToSparse(int[][] arr) {
		int valueCount = 0;
		
		for(int[] ele : arr) {
			for(int val : ele) {
				if(val != 0) {
					valueCount++;
				}
			}
		}
		
		int[][] spaArr = new int[valueCount+1][3];
		
		spaArr[0][0] = arr.length;
		spaArr[0][1] = arr[0].length;
		spaArr[0][2] = valueCount;
		
		int count = 1;
		for(int i = 0; i < arr.length; i++) {
			for(int j = 0; j < arr[i].length; j++) {
				if(arr[i][j] != 0) {
					spaArr[count][0] = i;
					spaArr[count][1] = j;
					spaArr[count][2] = arr[i][j];
					count++;
				}
			}
		}
		
		return spaArr;
	}
	
	// 稀疏数组转二维数组
	private static int[][] spaToArr(int[][] spaArr) {
		int[][] arr = new int[spaArr[0][0]][spaArr[0][1]];
		
		for(int i = 1; i < spaArr.length; i++) {
			arr[spaArr[i][0]][spaArr[i][1]] = spaArr[i][2];
		}
		
		return arr;
	}
}

运行结果

原始数组:
[0, 0, 0, 22, 0, 0, 15]
[0, 11, 0, 0, 0, 17, 0]
[0, 0, 0, -6, 0, 0, 0]
[91, 0, 0, 0, 0, 39, 0]
[0, 0, 28, 0, 0, 0, 0]
稀疏数组:
[5, 7, 8]
[0, 3, 22]
[0, 6, 15]
[1, 1, 11]
[1, 5, 17]
[2, 3, -6]
[3, 0, 91]
[3, 5, 39]
[4, 2, 28]
原始数组:
[0, 0, 0, 22, 0, 0, 15]
[0, 11, 0, 0, 0, 17, 0]
[0, 0, 0, -6, 0, 0, 0]
[91, 0, 0, 0, 0, 39, 0]
[0, 0, 28, 0, 0, 0, 0]

队列

环形队列的几个要素

  1. 队空条件:front = rear
  2. 队满条件:( rear + 1 ) % maxSize = front
  3. 进队操作:rear = ( rear + 1 ) % maxSize
  4. 出队操作:front = ( front + 1 ) % maxSize
  5. 队中元素数量:( rear + maxSize - front ) % maxSize

实现环形队列会损失数组的一个空间

代码实现

/**
 * @author:西瓜菌
 * @date:2022年3月16日上午10:10:06
 * @Description:循环队列
 */
public class RoundRobinQueue {
	public static void main(String[] args) {
		QueueDemo q = new QueueDemo(3);
		q.add(1);
		q.add(2);
		q.add(3);
		System.out.println("取出的元素:"+ q.getEle());
		System.out.println("显示所有元素");
		q.showQueue();
		System.out.println("\n元素数量");
		System.out.println(q.eleCount());
	}
}

class QueueDemo{
	int front;
	int rear;
	int maxSize;
	int queue[];
	
	public QueueDemo(int maxSize) {
		super();
		this.maxSize = maxSize+1;
		queue = new int[this.maxSize];
	}
	
	/**
	 * 判断队列是否为空
	 * @return true:为空		false:不为空
	 */
	public boolean isEmpty() {
		return front == rear;
	}
	
	/**
	 * 判断队列是否已满
	 * @return true:已满		false:未满
	 */
	public boolean isFull() {
		return (rear + 1) % maxSize == front;
	}
	
	/**
	 * 添加元素
	 * @param ele 添加进队列的元素
	 */
	public void add(int ele) {
		if(isFull()) {
			throw new RuntimeException("队列已满,无法添加元素");
		}
		queue[rear] = ele;
		// rear 向后移动
		rear = (rear + 1) % maxSize;
	}
	
	/**
	 * 取出元素
	 * @return 取出的元素
	 */
	public int getEle() {
		if(isEmpty()) {
			throw new RuntimeException("队列为空,无法取出元素");
		}
		int ele = queue[front];
		front = (front + 1) % maxSize;
		return ele;
	}
	
	/**
	 * 遍历队列
	 */
	public void showQueue() {
		if(isEmpty()) {
			throw new RuntimeException("队列为空,无法显示");
		}
		int temp = front;
		while(temp != rear) {
			System.out.print(queue[temp] + "\t");
			temp = (temp + 1) % maxSize;
		}
	}
		
	/**
	 * 计算有效元素个数
	 * @return 有效元素个数
	 */
	public int eleCount() {
		return (rear + maxSize - front) % maxSize;
	}
}

运行结果

取出的元素:1
显示所有元素
2	3	
元素数量
2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值