數據結構
數據結構包含:線性結構和非線性結構
- 1、線性結構作爲最常用的數據結構,其特點是數據元素之間存在一對一的線性關係
- 2、線性結構有兩種不同的存儲結構,即順序存儲結構和鏈式存儲結構。順序存儲的線性表稱爲順序表,順序表中的存儲元素是連續的
- 3、鏈式存儲的線性表稱爲鏈表,鏈表中的存儲元素不一定是連續的,元素節點存放數據元素以及相鄰元素的地址信息
- 4、線性結構常見的有:數組、隊列、鏈表和棧。
非線性結構:
非線性結構包含:二維數組、多位數組,廣義表,樹結構,圖結構
一、稀疏數組:(完成棋盤)
當一個數組中大部分元素爲0,或者爲同一個值當數據時,可以使用稀疏數組來保存該數組。
稀疏數組當處理方法是:
- 1、記錄數組一共有幾行幾列,有多少哥不同當值
- 2、把這具有不同值當元素當行列及值記錄在一個小規模當數組中,從而縮小程序的規模
應用實例:
- 1、使用稀疏數組,來保留類似前面的二維數組(棋盤、地圖等等)
- 2、把稀疏數組存盤,並且可以從新恢復原來的二維數組數
- 3、整體思路分析
二維數組轉稀疏數組的思路:
- 1、遍歷原始的二維數組,得到有效數據的個數sum
- 2、根據sum就可以創建稀疏數組sparseArr int[sum+1][3]
- 3、將二維數組的有效數據存入到稀疏數組
將稀疏數組轉爲原始的二維數組的思路:
- 1、先讀取稀疏數組的第一行,根據第一行的數據,創建原始的二維數組
- 2、在讀取稀疏數組後幾行的數據,並賦給原始的二維數組即可。
代碼實現:
public class SpareArray {
public static void main(String[] args) {
int array1[][] = new int[11][10];
array1[2][3]=2;
array1[3][5]=3;
System.out.println(array1[0].length);
System.out.println(array1.length);
int sum=0;
for (int arr[]:array1){
for (int status:arr){
System.out.print(status + " ");
if(status!=0){
sum++;
}
}
System.out.println("");
}
// 變成稀疏數組
if(sum==0){
System.out.println("不需要變成稀疏數組");
return;
}
int arr2[][]= new int[sum+1][3];
arr2[0][0]=array1[0].length;
arr2[0][1]=array1.length;
arr2[0][2]=sum;
// 這是從數組--》稀疏數組
int count =1;
for(int i=0;i<array1[0].length;i++){
for (int j=0;j<array1.length;j++){
if(array1[j][i]!=0){
arr2[count][0]=i;
arr2[count][1]=j;
arr2[count][2]=array1[j][i];
count++;
}
}
}
for (int arr[]:arr2){
for (int status:arr){
System.out.print(status + " ");
}
System.out.println("");
}
System.out.println("從稀疏數組變成數組");
int arr3[][] = new int[arr2[0][1]][arr2[0][0]];
for (int i=1;i<arr2.length;i++){
arr3[arr2[i][1]][arr2[i][0]]=arr2[i][2];
}
for (int arr[]:arr3){
for (int status:arr){
System.out.print(status + " ");
}
System.out.println("");
}
}
}
二、隊列
隊列介紹:
隊列是一個有序列表,可以用數組或是鏈表來實現。
遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取出
隊列本身是有序立標,若是數組的結構來存儲隊列的數據,則隊列數組的聲明如下圖,其中masSize是該隊列的最大容量。
因爲隊列的輸出、輸入是分別從前後端來處理,因此需要兩個變量front及rear分別記錄隊列前後端的下標,front會隨着數據輸出而改變,而rear則是隨着數據輸入而改變,如圖所示:
當我們將數據存入隊列時稱爲“addQueue”,addQueue的處理需要有兩個步驟:思路分析
- 1、將尾指針往後移:rear+1,當front==rear【空】
- 2、若尾指針rear小於隊列的最大下標maxSize-1,則數據存入rear所指的數組元素中,否則無法存入數據。rear==maxSize-1【隊列滿】
2.1、使用數組來實現隊列
思路如下:
- 1、front變量就是指向隊列的第一個元素,也就是說arr[front]就是隊列的第一個元素,front的初始值爲0;
- 2、rear變量指向隊列的最後一個元素,rear的初始值爲0;
- 3、當隊列滿時。條件是(rear+1)%size==front;(滿)
- 4、對隊列爲空的條件,rear==front空
- 5、當我們這樣分析,隊列中有效的數據的個數(rear+size-front)%size (這個計算出來的是數據的個數)
public class ArrayRealizationQueue {
// 指向最後一個元素的指針
private int rear;
// 指向第一個元素的指針
private int front;
// 這個數據的大小
private int size;
// 存取數據的
private int arr[];
public ArrayRealizationQueue(int size){
arr=new int[size];
this.size=size;
this.front=0;
this.rear=0;
}
public void add(int add){
if(isFull()){
System.out.println("以前滿了,請稍等。。。");
return;
}
if(rear==size){//當存儲的指針,等於空間大小的時候,需從頭開始
rear=0;
}
arr[rear]=add;
++rear;
System.out.println("添加成功");
}
public int take(){
if(isEmpty()){
System.out.println("數組爲空,不能在取了");
return -100;
}
if(front==size){
front=0;
}
int i = arr[front];
front++;
return i;
}
public boolean isFull(){
return (rear+1)%size==front;
}
public boolean isEmpty(){
return rear==front;
}
// 看有多少個元素
public int countElement(){
return (rear+size-front)%size;
}
public void toStringPrintln(){
for (int i=0;i<size;i++){
System.out.print(arr[i]+" ,");
}
System.out.println("6");
System.out.println(front+"----"+rear);
}
public static void main(String[] args) {
ArrayRealizationQueue arrayRealizationQueue = new ArrayRealizationQueue(3);
Scanner scanner = new Scanner(System.in);
boolean flag=true;
int count=1;
while (flag){
int i = scanner.nextInt();
switch (i){
case 1:
// 插入數據
System.out.println("插入數據");
arrayRealizationQueue.add(count++);
break;
case 2:
// 取出數據
System.out.println("取出數據");
int take = arrayRealizationQueue.take();
System.out.println(take);
break;
case 3:
//是不是,滿了
System.out.println("是不是滿了"+arrayRealizationQueue.isFull());
break;
case 4:
System.out.println("是不是沒有數據了"+arrayRealizationQueue.isEmpty());
break;
case 5:
System.out.println("有幾個數據了"+arrayRealizationQueue.countElement());
break;
case 6:
arrayRealizationQueue.toStringPrintln();
break;
default:
flag=false;
break;
}
}
}
}
2.2、使用鏈表來實現隊列
3、鏈表(Linked List)
鏈表是有序的列表,但是他在內存中是存儲如下
小結:
- 1、鏈表是以節點的方式存儲是鏈式存儲
- 2、每個節點包含data域,next域:指向下一個節點
- 3、如上圖:發現鏈表的各個節點不一定是連續存儲
- 4、鏈表分表頭節點的鏈表和沒有頭節點的鏈表,根據實際的需求來確定
下圖只是一個邏輯結構,看起來是連續存儲的,其實不是的
實例:
添加(創建)
1、先創建一個head頭節點,作用就是表示單鏈表的頭
2、後面我們每添加一個節點,就直接加入到鏈表的最後
遍歷:
通過一個輔助遍歷,幫助遍歷整個鏈表
當不考慮編號的順序時:
1、找到當前鏈表的最後節點
2、將最後這個節點的next指向新的節點