1. 稀疏數組和隊列
1.1 稀疏(sparsearray)數組
- 基本概念:
- 當一個數組中大部分元素爲0,或者爲同一個值的數組時,可以使用稀疏數組來保存該數組。
- 處理方法:
- 記錄數組一共有幾行幾列,有多少個不同的值。
- 把具有不同值的元素的行列及值記錄在一個小規模的數組中,從而縮小程序的規模
- 舉例:
- 普通數組
- 稀疏數組
- 代碼實現:
public class AparseArray {
public static void main(String[] args) {
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
System.out.println("原始二維數組爲:");
for (int[] row : chessArr1) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
int sum = 0;
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1.length; j++) {
if (chessArr1[i][j] != 0) {
sum++;
}
}
}
int sparseArr[][] = new int[sum + 1][3];
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
int count = 0;
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1.length; j++) {
if (chessArr1[i][j] != 0) {
count++;
sparseArr[count][0] = i;
sparseArr[count][1] = j;
sparseArr[count][2] = chessArr1[i][j];
}
}
}
System.out.println("稀疏數組爲:");
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);
}
int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];
for (int i = 1; i < sparseArr.length; i++) {
chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
System.out.println("恢復後的二維數組爲:");
for (int[] row : chessArr2) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
}
運行結果爲:
原始二維數組爲:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
稀疏數組爲:
11 11 2
1 2 1
2 3 2
恢復後的二維數組爲:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
1.2 隊列
- 基本概念:
- 隊列是一個有序列表,可以用數組或是鏈表來實現。
- 遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取出
- 數組模擬隊列:
- 示意圖:
- 其中 MaxSize 是該隊列的最大容量,兩個變量 front 及 rear 分別記錄隊列前後端的下標,front 會隨着數據輸出而改變,而 rear 則是隨着數據輸入而改變。
- 代碼實現:
public class Demo01ArrayQueue {
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("e(exit):退出程序");
System.out.println("a(add):添加數據到隊列");
System.out.println("g(get):從隊列取出數據");
System.out.println("h(head):查看隊列頭的數據");
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;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
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++;
arr[rear] = n;
}
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("隊列爲空,不能取數據!");
}
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];
}
}
- 數組模擬環形隊列:
- 問題分析:
- 上述數組隊列,沒能達到複用效果,只能使用一次。
- 使用算法改進爲環形隊列(通過取模的方式來實現)。
- 處理方法(算法):
- 尾索引的下一個爲頭索引時表示隊列滿,即將隊列容量空出一個作爲約定。
- 判斷隊列滿的依據:(rear + 1) % maxSize == front
- 判斷隊列空的依據:rear == front
- 隊列中有效數據的個數:(rear + maxSize - front) % maxSize
- 代碼實現:
public class Demo02CircleArrayQueue {
public static void main(String[] args) {
System.out.println("數組模擬環形隊列");
CircleArrayQueue queue = new CircleArrayQueue(4);
char key = ' ';
Scanner scanner = 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 = 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;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircleArrayQueue {
private int maxSize;
private int front;
private int rear;
private int[] arr;
public CircleArrayQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
}
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 + 1) % maxSize;
}
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("隊列爲空,不能取數據!");
}
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
public void showQueue() {
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]);
}
}
public int size() {
return (rear + maxSize - front) % maxSize;
}
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("空隊列");
}
return arr[front];
}
}