稀疏数组
使用二维数组来记录棋盘
如果棋盘黑是1,白是2,那么数组中很多的默认值都是0或者很多同一个值。这个时候我们就可以使用稀疏数组
基本介绍
稀疏数组的处理方法:
1) 记录数组一共有几行几列,有多少个不同的值
2) 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
实例:(第一行是总共有几行几列几个值)
转换的思路
二维数组–》稀疏数组:
-
遍历原来的二维数组等到有效数据个数sum
-
根据sum创建稀疏数组 sparseArray int[sum+1][3]
-
将二维数组的有效数据传入到稀疏数组中
稀疏数组–》二维数组:
-
先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
-
读取后面几行的数据进行赋值
代码实现
public class _稀疏数组_ {
public static void main(String[] args) {
//场景:围棋的棋盘保存
//创建一个11*11的棋盘数组(二维
//黑色是1,蓝色是2,默认是0
int chessArr[][] = new int[11][11];
chessArr[1][2] = 1;
chessArr[3][4] = 2;
System.out.println("原来的数组:");
for(int[] row: chessArr){
for(int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
//转换成稀疏数组
int sum = 0;
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
if(chessArr[i][j]!=0){
sum+=1;
}
}
}
System.out.println("有效的数据:"+sum);
//创建相应的稀疏数组
int chessArr1[][] = new int[sum+1][3];
chessArr1[0][0] = 11;
chessArr1[0][1] = 11;
chessArr1[0][2] = sum;
//给稀疏数组赋值
int count = 1;
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
if(chessArr[i][j]!=0){
chessArr1[count][0] = i;
chessArr1[count][1] = j;
chessArr1[count++][2] = chessArr[i][j];
}
}
}
System.out.println("稀疏数组的形式:");
for(int i=0;i<sum+1;i++){
for(int j=0;j<3;j++){
System.out.printf("%d\t",chessArr1[i][j]);
}
System.out.println();
}
//用稀疏数组恢复成二位数组
int chessArr2[][] = new int[chessArr1[0][0]][chessArr1[0][0]];
for(int i=1;i<chessArr1.length;i++){
chessArr2[chessArr1[i][0]][chessArr1[i][1]] = chessArr1[i][2];
}
System.out.println("恢复后的二维数组");
for(int[] row: chessArr2){
for(int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
//上面的数据存放可以用io保存到data文件中
}
}
队列
是一个有序列表,用数组或者链表实现。遵循先进先出
数组模拟队列
思路:(保存数据的数组是Queue类的基本属性)
以上思路实现之后存在的问题:
- 数组只能使用一次,当取出数据之后,这个数据的下标(含之前)的都不能第二次使用
代码实现:
public class _队列_ {
public static void main(String[] args) {
//存在的问题,数组的下标只能使用一次 当数据取出之后不能使用第二次空间
//数组模拟队列
//ArrayQueue
Queue queue = new Queue(3);
char key = ' ';
Scanner put = new Scanner(System.in);
boolean loop= true;
while(loop){
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):取出队列的数据");
System.out.println("h(head):查看队列头的数据");
key = put.next().charAt(0); //接收一个字符
switch(key){
case 's':
queue.show_Queue();
break;
case 'g':
try{
int res = queue.get_data();
System.out.printf("取出的数据是%d\n",res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'a':
System.out.println("请输入一个数:");
int number = put.nextInt();
queue.add(number);
break;
case 'h':
try{
queue.headQueue();
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'e':
put.close();
exit();
default:
break;
}
}
}
}
class Queue{
private int maxSize;//队列数组的最大容量
private int front;//队列头,指向队列头的前一个数据
private int rear;//队列尾,指向队列尾的数据(就是队列尾这个数)
private int[] arr;//存放数据,模拟队列
public Queue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
this.front = -1;
this.rear = -1;
}
//判断队列是否满
public Boolean is_full(){
return rear==maxSize-1;
}
//判断队列是不是空的
public Boolean is_empty(){
return rear==front;
}
//添加数据到队列
public void add(int n){
if(is_full()){
System.out.println("不好意思队列满了····不能加入数据");
return;
}
//尾部后移
rear+=1;
arr[rear] = n;
}
//出队列
public int get_data(){
//判断是不是空
if(is_empty()){
throw new RuntimeException("队列空,不能取数据");
}
front+=1;
return arr[front];
}
// 显示队列的所有数据
public void show_Queue(){
//遍历
if(is_empty()){
System.out.println("队列是空的没有数据");
return;
}
for(int i=0;i<=rear;i++){
System.out.printf("arr[%d] = %d\n",i,arr[i]);
}
}
//显示队列的头部数据
public void headQueue(){
if(is_empty()){
System.out.println("队列是空的没有数据");
throw new RuntimeException("对类空的");
}
System.out.println(arr[front + 1]);
}
}
数组模拟实现环形队列
思路:
tip:
其中的数组在空间上总是要预留一个空间,当rear=maxSize-1,front=0时 队列是满的
front的初始值是0,rear的初始值也是0
代码实现:
class Queue_Circle{
private int maxSize;//队列数组的最大容量
private int front;//队列头,就是指向第一个元素,初始值是0
private int rear;//队列尾,指向队列尾数据的后一个位置,初始值0
private int[] arr;//存放数据,模拟队列
public Queue_Circle(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
this.front = 0;
this.rear = 0;
}
//判断队列是否满
public Boolean is_full(){
return (rear+1)%maxSize==front;
}
//判断队列是不是空的
public Boolean is_empty(){
return rear==front;
}
//添加数据到队列
public void add(int n){
if(is_full()){
System.out.println("不好意思队列满了····不能加入数据");
return;
}
//尾部后移
arr[rear] = n;
rear = (rear+1)%maxSize;
}
//出队列
public int get_data(){
//判断是不是空
if(is_empty()){
throw new RuntimeException("队列空,不能取数据");
}
// 首先保存一个当前数据,然后front后移,最后返回历史数据
int value = arr[front];
front = (front+1)%maxSize;
return value;
}
// 显示队列的所有数据
public void show_Queue(){
//遍历
if(is_empty()){
System.out.println("队列是空的没有数据");
return;
}
//需要先求出有效数据的个数 打印个数
int size = size();
//front开始遍历
for(int i=front;i<size;i++){
System.out.printf("arr[%d] = %d\n",i%maxSize,arr[front%maxSize]);
}
}
//求出当前队列的有效数据个数
public int size(){
return (rear+maxSize-front)%maxSize;
}
//显示队列的头部数据
public void headQueue(){
if(is_empty()){
System.out.println("队列是空的没有数据");
throw new RuntimeException("对类空的");
}
System.out.println(arr[front]);
}
}