数据结构-稀疏数组和队列
前段时间跟着尚硅谷的视频学习,自己截图做了一些学习笔记,现在简单整理出来供大家参考,同时也方便自己日后复习查询,如果有存在疏漏,欢迎大家批评指正。文末将会附上视频链接。
稀疏矩阵
稀疏数组:记录原始数组共几行几列,以及它的值所在的位置
二维数组转稀疏数组:
-
遍历原始二维数组,得到有效数据的个数sum
-
根据sum创建稀疏数组spaceArr int[sum+1][3]
-
将二维数组的有效数据存入稀疏数组
稀疏数组转二维数组:
-
读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
-
在读取稀疏数组后几行的数据,赋给原始二维数组
-
代码实现:
//创建一个原始的二维数组 //0:表示没有棋子;1表示黑子 2表示蓝子 int chessArray1[][]=new int[11][11]; chessArray1[1][2]=1; chessArray1[2][3]=2; //输出原始的二维数组 System.out.println("输出原始的二维数组"); for(int[] row:chessArray1){ for(int data:row){ System.out.printf("%d\t",data); } System.out.println(); } //将二维数组转稀疏矩阵 //1.遍历原始二维数组,得到有效数据的个数sum int sum=0; for (int i=0;i<11;i++){ for(int j=0;j<11;j++){ if(chessArray1[i][j]!=0){ sum++; } } } //2.根据sum创建稀疏数组spaceArr int[sum+1][3] int spaceArr[][] = new int[sum+1][3]; //给稀疏数组第一行赋值 spaceArr[0][0]=11; spaceArr[0][1]=11; spaceArr[0][2]=sum; //遍历二维数组,将有效数据存入稀疏数组 int count=0; for (int i=0;i<11;i++){ for(int j=0;j<11;j++){ if(chessArray1[i][j]!=0){ count++; spaceArr[count][0]=i; spaceArr[count][1]=j; spaceArr[count][2]=chessArray1[i][j]; } } } //输出稀疏数组 System.out.println(); System.out.println("输出稀疏数组"); for (int i=0;i<spaceArr.length;i++){ System.out.printf("%d\t%d\t%d\t\n",spaceArr[i][0],spaceArr[i][1],spaceArr[i][2]); } System.out.println(); //稀疏数组转二维数组: //1.读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组 int chessArr2[][]=new int[spaceArr[0][0]][spaceArr[0][1]]; //2.在读取稀疏数组后几行的数据,赋给原始二维数组 for (int i=1;i<spaceArr.length;i++){ chessArr2[spaceArr[i][0]][spaceArr[i][1]]=spaceArr[i][2]; } //输出恢复后的二维数组 System.out.println(); System.out.println("恢复后的二维数组"); for(int[] row:chessArr2){ for(int data:row){ System.out.printf("%d\t",data); } System.out.println(); }
队列
介绍:
-
队列本身是有序的列表,可以用数组或链表实现
-
先进先出
数组实现
-
队列声明,maxSize是该队列的最大容量
-
根据前后端处理队列的输入输出,需要两个变量front和rear分别记录队列的前后端的下标,
-
front随数据输出而改变,rear随数据输入而改变
-
存入数据(addQueue)
-
判断队列是否满:
-
尾指针rear<maxSize-1 ,队列没满,将尾指针rear往后移:rear+1,数据存入队列
-
rear=maxSize-1 ,队列满
-
-
-
普通数组代码实现(数组内存不能复用)
package com.main.queue; import java.util.Scanner; public class ArrayQueueDemo { public static void main(String[] args) { //初始化一个队列 ArrayQueue queue=new ArrayQueue(3); char key = ' ';//接收用户输入 Scanner scanner=new Scanner(System.in); boolean loop=true; //输出一个菜单 while (loop){ System.out.println("s(show):显示队列"); System.out.println("a(add):添加数据到队列"); System.out.println("g(get):从队列取出数据"); System.out.println("h(head):查看队列头的数据"); System.out.println("e(exit):退出程序"); key=scanner.next().charAt(0);//接收一个字符 switch (key){ case 's': queue.showQueue(); break; case 'a': System.out.println("请输入要添加的数据:"); int value=scanner.nextInt(); queue.addQueue(value); break; case 'g': try { int res=queue.getQueue(); System.out.printf("取出的数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'h': try { int res=queue.headQueue(); System.out.printf("队列头数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'e': scanner.close(); loop=false; System.out.println("程序退出"); break; default: break; } } } } class ArrayQueue{ private int maxSize;//表示数组的最大容量 private int front;//队列头 private int rear;//队列尾 private int[] arr;//用数组存放数据,模拟队列 //创建队列的构造器 public ArrayQueue(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 addQueue(int n){ if (isFull()){ System.out.println("队列满,不能加入数据"); return; } rear++;//添加队列,尾指针加1 arr[rear]=n; } //获取队列数据,出队列 public int getQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空,不能取数据"); } front++;//front后移 return arr[front]; } //显示队列所有数据 public void showQueue(){ if (isEmpty()){ System.out.println("队列为空,没有数据"); return; } for (int i=0;i<arr.length;i++){ System.out.printf("arr[%d]=%d\n",i,arr[i]); } } //显示队列的头数据,不取出 public int headQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空,不能取数据"); } return arr[front+1]; } }
改进:环形队列
-
front指向队列的第一个元素,初始值=0
-
rear指向队列的最后一个元素的后一个位置,初始值=0
-
队列满:(rear+1)%maxSize=front
-
队列空:rear==front
-
队列有效的数据个数:(rear+maxSize-front)%maxSize
-
模拟环形队列代码实现
package com.main.queue; import java.util.Scanner; public class CircleArrayQueue { public static void main(String[] args) { //初始化一个队列,设置大小为4,其最大有效数据为3 CircleArray queue=new CircleArray(4); char key = ' ';//接收用户输入 Scanner scanner=new Scanner(System.in); boolean loop=true; //输出一个菜单 while (loop){ System.out.println("s(show):显示队列"); System.out.println("a(add):添加数据到队列"); System.out.println("g(get):从队列取出数据"); System.out.println("h(head):查看队列头的数据"); System.out.println("e(exit):退出程序"); key=scanner.next().charAt(0);//接收一个字符 switch (key){ case 's': queue.showQueue(); break; case 'a': System.out.println("请输入要添加的数据:"); int value=scanner.nextInt(); queue.addQueue(value); break; case 'g': try { int res=queue.getQueue(); System.out.printf("取出的数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'h': try { int res=queue.headQueue(); System.out.printf("队列头数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'e': scanner.close(); loop=false; System.out.println("程序退出"); break; default: break; } } } } class CircleArray{ private int maxSize;//表示数组的最大容量 //front指向队列的第一个元素,初始值=0 private int front;//队列头 //rear指向队列的最后一个元素的后一个位置,初始值=0 private int rear;//队列尾 private int[] arr;//用数组存放数据,模拟队列 //创建队列的构造器 public CircleArray(int arrMaxSize){ maxSize = arrMaxSize; arr = new int[maxSize]; front=0;//指向队列头部 rear=0;//指向队列尾部的后一个位置 } //判断队列是否满 public boolean isFull(){ //队列满: return (rear+1)%maxSize==front; } //判断队列是否为空 public boolean isEmpty(){ return rear==front; } //添加数据到队列 public void addQueue(int n){ if (isFull()){ System.out.println("队列满,不能加入数据"); return; } //直接将数据加入 arr[rear] = n; //将rear后移,考虑取模 rear=(rear+1)%maxSize; } //获取队列数据,出队列 public int getQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空,不能取数据"); } //先把front对应的值保留到一个临时变量 //将front后移,考虑取模 //将临时变量返回 int value=arr[front]; front = (front +1)%maxSize; return value; } //显示队列所有数据 public void showQueue(){ if (isEmpty()){ System.out.println("队列为空,没有数据"); return; } //从front开始遍历,遍历有效元素个数 for (int i=front;i<front+size();i++){ System.out.printf("arr[%d]=%d\n",i % maxSize,arr[i % maxSize]); } } //求出当前队列有效个数 public int size(){ return (rear+maxSize-front)%maxSize; } //显示队列的头数据,不取出 public int headQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空,不能取数据"); } return arr[front]; } }
在此附上尚硅谷的教学视频:
【尚硅谷】数据结构与算法(Java数据结构与算法)