数据结构Java学习笔记——知识点:数据结构概述、稀疏数组、队列
一、数据结构概述
1、程序 = 数据结构 + 算法
2、数据结构包括两个部分:线性结构和非线性结构
线性结构:
1)数据元素之间是一对一的关系
2)线性结构有两种存储结构:顺序存储(数组)和链式存储(链表)
顺序存储:是连续的。
链式存储:不一定是连续的,节点中存放的是数据元素和相邻元素的地址信息。
3)常见的线性结构:数组、队列、链表、栈
非线性结构:
1)不仅限于一对一的关系
2)非线性结构包括:二维数组、多维数组、广义表、树结构、图结构
二、稀疏数组(sparseArray)
在五子棋游戏中可以使用稀疏数组。
1、稀疏数组概述
当一个数组中大部分元素是0,或者为同一个值的数组是,就可以用稀疏数组保存。
2、稀疏数组的处理方法
分为两步:
1):记录数组一共有几行几列,有多少个不同的值
2):把具有不同值的元素的行列及值记录在一个小规模的数组中,以减少存储空间消耗。
例:
一组行列值表示数组中的一个元素(表中数字表示下标值,是[行数/列数 - 1])。
特殊的:下标为[0]的行和列表示一共有几行几列,值表示一共有几个有效数据。
3、二维数组转稀疏数组的思路
4、代码实现
// An highlighted block
public class sparseArray {
public static void main(String[] args) {
//create a 2-D array of size 11 by 11
int[][] array = new int[11][11];
//Assigns a value to the 2-D array.
// 0:means no chess pieces.
// 1:means black pieces.
// 2:means blue pieces.
array[1][2] = 1;
array[2][3] = 2;
//Prints the original 2-D array
System.out.println("Original Array:");
for(int[] row : array) {
for(int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
System.out.println("--------------------------------");
//===========================================================================================================
//The idea of converting the 2-D array to a sparse array
//No.1:Traverse the 2-D array to obtain the number of non 0 data
int sum = 0;
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
if(array[i][j] != 0){
sum++;
}
}
}
System.out.println("The number of non o data: " + sum);
System.out.println("--------------------------------");
//No.2:Create a sparse array corresponding to this 2-D array
int[][] sparseArray = new int[sum + 1][3];
//Assigns a value to the sparse array
sparseArray[0][0] = 11;
sparseArray[0][1] = 11;
sparseArray[0][2] = sum;
//Traverse the 2-D array and put 0 data into this sparse array
int count = 0;//Count is used to record the number of the non 0 data of this 2-D array
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
if(array[i][j] != 0){
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = array[i][j];
}
}
}
//Print the sparse array
System.out.println();
System.out.println("Sparse Array:");
for (int[] row : sparseArray){
for(int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
System.out.println("--------------------------------");
//===========================================================================================================
//The idea of converting the sparse array to a 2-D array
//No.1:Read the first row of a sparse array and create a 2-D array based on the data from the first row
int[][] arrayTwo = new int[sparseArray[0][0]][sparseArray[0][0]];
//No.2:Travers the sparse array and put the number of non zero data into the new 2-D array
for(int i = 1; i < sparseArray.length; i++){
arrayTwo[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
//Print the new 2-D array
System.out.println("The new Array:");
for(int[] row : array) {
for(int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
}
}
5、运行结果
6、课后作业:
在以上代码基础上,将稀疏数组保存在磁盘上,如:spraseArray.txt
从文件中调取数据,并将其还原成二维数组。
三、队列
1、队列的概述
队列是一个有序列表,可以用数组或链表来实现,它遵循先入先出规则。
2、使用数组模拟队列
数组模拟队列的结构
队列本身就是一个有序列表,如果使用数组的结构储存队列,那么结构和声明如下:
上图中队列的输入和输出都分别是从前后端来处理,因此需要两个变量 front 和 rear 来分别记录队列前后端的下标值,front 会随着数据输出而改变,而 rear 则会随着数据的输入而改变。
数据存入队列成为addQueue。
具体思路:
1)将尾指针往后移: rear + 1,当 front = rear 时,表示队列为空。
2)如果尾指针 rear 小于队列的最大下标maxSize - 1,则数据存入 rear 所指向的数组元素中,否则无法存入数据。当 rear = maxSize - 1 时,队列为满。
特殊的:rear 是队列的最后(包含),front 是队列的开始(不包含)。
代码实现
// An highlighted block
package com.database;
import java.util.Scanner;
public class queue {
public static void main(String[] args) {
//create a queue
ArrayQueue arrayQueue = new ArrayQueue(3);
char key = ' ';//received user input
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//create a list
while(loop){
System.out.println("----------------------------------------");
System.out.println("1. Add data into the queue");
System.out.println("2. Get data from the queue");
System.out.println("3. Show data from the queue");
System.out.println("4. Show data of the head of the queue");
System.out.println("5. Exit");
System.out.print("Enter your choice: ");
key = scanner.next().charAt(0);//received user input
switch (key){
case '1':
System.out.print("Enter data: ");
arrayQueue.addQueue(scanner.nextInt());
break;
case '2':
try{
System.out.println("Data: " + arrayQueue.getQueue());
}
catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '3':
arrayQueue.showQueue();
break;
case '4':
try{
System.out.println("The data of the head: " + arrayQueue.headQueue());
}
catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '5':
scanner.close();//close the scanner
loop = false;//end of loop
break;
default:
break;
}
}
System.out.println("The process finished");
}
}
//use array to imitate a queue. Compile a class named ArrayQueue
class ArrayQueue{
private int maxSize;//means the max size of the array
private int front;//define the front of the queue
private int rear;//define the rear of the queue
private int[] arr;//define the data of the array,compile the queue
//create a constructor of the queue
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
front = -1;//print to the front of the head of the queue
rear = -1;//print to the last of the queue,include the last data of the queue
}
//determine if the queue is full or not full
public boolean isFull(){
return rear == maxSize - 1;
}
//determine if the queue is empty or not empty
public boolean isEmpty(){
return rear == front;
}
//add data into the queue
public void addQueue(int n){
//determine if the queue full
if(isFull()){
System.out.println("Queue is full! Can't add data into the quere.");
return;
}
//add data into the queue
arr[++rear] = n;
}
//get data from the queue
public int getQueue() {
//determine if the queue is empty
if (isEmpty()) {
//by throw exception
throw new RuntimeException("Queue is empty");
}
front++;//front move back
return arr[front];
}
//show all data in the queue
public void showQueue(){
//determine if the queue empty
if(isEmpty()) {
System.out.println("Queue is empty!");
return;
}
for (int i = front + 1; i <= rear; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
//show the data of the head of the queue
public int headQueue(){
//determine if the queue is empty
if (isEmpty()) {
//by throw exception
throw new RuntimeException("Queue is empty");
}
return arr[front + 1];
}
}
这段代码虽然能正常运行,但是是有问题的,因为头指针一旦上移,存储空间就不会再回来了,后面会对代码进行优化。
运行结果
3、使用数组模拟环形队列
具体思路
脑子里面想像一下,有个圆环,动手画个图就能理解了。
代码实现
// An highlighted block
package com.database;
import java.util.Scanner;
public class circleArrayQueue {
public static void main(String[] args) {
//create a CircleArray queue
CircleQueue arrayQueue = new CircleQueue(4);//create a CircleArray valid size is 4
char key = ' ';//received user input
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//create a list
while(loop){
System.out.println("----------------------------------------");
System.out.println("1. Add data into the queue");
System.out.println("2. Get data from the queue");
System.out.println("3. Show data from the queue");
System.out.println("4. Show data of the head of the queue");
System.out.println("5. Exit");
System.out.print("Enter your choice: ");
key = scanner.next().charAt(0);//received user input
switch (key){
case '1':
System.out.print("Enter data: ");
arrayQueue.addQueue(scanner.nextInt());
break;
case '2':
try{
System.out.println("Data: " + arrayQueue.getQueue());
}
catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '3':
arrayQueue.showQueue();
break;
case '4':
try{
System.out.println("The data of the head: " + arrayQueue.headQueue());
}
catch (Exception e){
System.out.println(e.getMessage());
}
break;
case '5':
scanner.close();//close the scanner
loop = false;//end of loop
break;
default:
break;
}
}
System.out.println("The process finished");
}
}
class CircleQueue{
private int maxSize;//means the max size of the array
private int front;//define the front of the queue
private int rear;//define the rear of the queue
private int[] arr;//define the data of the array,compile the queue
public CircleQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
front = 0;//print to the front of the head of the queue
rear = 0;//print to the last of the queue,include the last data of the queue
}
public boolean isEmpty(){
return front == rear;
}
public boolean isFull(){
return (rear + 1) % maxSize == front;
}
//get the initial size
public int getSize(){
return (rear + maxSize - front) % maxSize;
}
//add data into the queue
public void addQueue(int n){
//determine if the queue full
if(isFull()){
System.out.println("Queue is full! Can't add data into the quere.");
return;
}
//add data into the queue
arr[rear] = n;
rear = (rear + 1) % maxSize;//move rear to the next space
}
//get data from the queue
public int getQueue() {
//determine if the queue is empty
if (isEmpty()) {
//by throw exception
throw new RuntimeException("Queue is empty");
}
//define a temporary variable
int temporary = arr[front];
front = (front + 1) % maxSize;//move front to the next space
return temporary;
}
//show all data in the queue
public void showQueue(){
//determine if the queue empty
if(isEmpty()) {
System.out.println("Queue is empty!");
return;
}
for (int i = front; i < (front + getSize()); i++) {
System.out.print(arr[i % maxSize] + " ");
}
System.out.println();
}
//show the data of the head of the queue
public int headQueue(){
//determine if the queue is empty
if (isEmpty()) {
//by throw exception
throw new RuntimeException("Queue is empty");
}
return arr[front % maxSize];
}
}