1.線性結構:數組、棧、隊列、鏈表、哈希表...java
2.樹結構:二叉樹、二分搜索樹、AVL、紅黑樹、Treap、Splay、堆、Trie、線段樹、K-D樹、並查集、哈夫曼樹...數組
3.圖結構:鄰接矩陣、鄰接表數據結構
1.定義:把數據碼成一排進行存放app
2.圖解:ide
3.示例代碼 Main.java函數
public class Main { public static void main(String[] args) { int[] arr = new int[10]; //聲明數組 for(int i = 0 ; i < arr.length ; i ++) arr[i] = i; int[] scores = new int[]{100, 99, 66};//聲明數組並賦值 for(int i = 0 ; i < scores.length ; i ++) System.out.println(scores[i]);//經過索引訪問的方式來訪問數組的變量 for(int score: scores) //數組具備可遍歷的特性 System.out.println(score); scores[0] = 96; ////經過索引訪問的方式來修改數組的變量 for(int i = 0 ; i < scores.length ; i ++) System.out.println(scores[i]); } }
輸出:ui
4.數組基礎this
數組優勢:快速查詢;spa
索引能夠用語義,也能夠沒有語義;數組最好應用於「索引有語義」的狀況;3d
但並不是全部有語義的索引都適用於數組;例: 身份證號就不適合,佔用空間太大;
數組也能夠處理 「索引沒有語義 」的狀況;主要討論該狀況下數組的使用;
5.二次封裝本身的數組
(Java 自身的數組是靜態數組,不具備對內存空間增、刪、改、查功能;故二次分裝本身的內存,爲動態數組)
例圖:
本身的數組類: Array
data:數組名稱
size:數組中實際裝入元素的長度
capacity:數組定義的長度(容量)
代碼示例:Array.java
public class Array { private int[] data; //定義int 型數組 data private int size; //data數組中有效元素的數量 // 構造函數,傳入數組的容量capacity構造Array public Array(int capacity){ data = new int[capacity]; size = 0; } // 無參數的構造函數,默認數組的容量capacity=10 public Array(){ this(10); } // 獲取數組的容量 public int getCapacity(){ return data.length; } // 獲取數組中的元素個數 public int getSize(){ return size; } // 返回數組是否爲空 public boolean isEmpty(){ return size == 0; } }
6.向數組中添加元素
向數組末添加元素:賦值給data[size],而後 size+1(右移便可)
向指定位置添加元素:將索引爲1的值及後面的值都向後移動;先將 size-1 的元素移動到size上,直到將值放入 1 中,最後 size+1
移動100
插入到 1 的位置
示例代碼:Array.java
public class Array { private int[] data; private int size; // 構造函數,傳入數組的容量capacity構造Array public Array(int capacity){ data = new int[capacity]; size = 0; } // 無參數的構造函數,默認數組的容量capacity=10 public Array(){ this(10); } // 獲取數組的容量 public int getCapacity(){ return data.length; } // 獲取數組中的元素個數 public int getSize(){ return size; } // 返回數組是否爲空 public boolean isEmpty(){ return size == 0; } // 向全部元素後添加一個新元素 public void addLast(int e){ // if(size == data.length) //判斷數組是否裝滿了 // throw new IllegalArgumentException("AddLast failed. Array is full."); // // data[size] = e; // size ++; add(size, e); //複用 add 方法 } // 在全部元素前添加一個新元素 public void addFirst(int e){ add(0, e); } // 在index索引的位置插入一個新元素e public void add(int index, int e){ if(size == data.length) //判斷數組是否裝滿了 throw new IllegalArgumentException("Add failed. Array is full."); if(index < 0 || index > size) //索引不合格的狀況 throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); for(int i = size - 1; i >= index ; i --) data[i + 1] = data[i]; //數組的值右移,前面的值覆蓋後面的值 data[index] = e; //e 覆蓋掉原來索引的值 size ++; } }
7.數組中查詢元素和修改元素
示例代碼:Array.java
public class Array { private int[] data; private int size; // 構造函數,傳入數組的容量capacity構造Array public Array(int capacity){ data = new int[capacity]; size = 0; } // 無參數的構造函數,默認數組的容量capacity=10 public Array(){ this(10); } // 獲取數組的容量 public int getCapacity(){ return data.length; } // 獲取數組中的元素個數 public int getSize(){ return size; } // 返回數組是否爲空 public boolean isEmpty(){ return size == 0; } // 向全部元素後添加一個新元素 public void addLast(int e){ add(size, e); } // 在全部元素前添加一個新元素 public void addFirst(int e){ add(0, e); } // 在index索引的位置插入一個新元素e public void add(int index, int e){ if(size == data.length) throw new IllegalArgumentException("Add failed. Array is full."); if(index < 0 || index > size) throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); for(int i = size - 1; i >= index ; i --) data[i + 1] = data[i]; data[index] = e; size ++; } // 獲取index索引位置的元素 public int get(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Get failed. Index is illegal."); return data[index]; } // 修改index索引位置的元素爲e public void set(int index, int e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set failed. Index is illegal."); data[index] = e; } @Override //覆蓋父類的方法 public String toString(){ StringBuilder res = new StringBuilder(); //新建字符串 res res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length)); //初始化字符串res res.append('['); for(int i = 0 ; i < size ; i ++){ res.append(data[i]); //使用索引的方式查詢數據 if(i != size - 1) //不是最後一個元素就添加 , res.append(", "); } res.append(']'); return res.toString(); } }
Main.java
public class Main { public static void main(String[] args) { Array arr = new Array(20); //添加容量爲20 for(int i = 0 ; i < 10 ; i ++) arr.addLast(i); System.out.println(arr); arr.add(1, 100); //在索引是 1 的位置插入 100 System.out.println(arr); arr.addFirst(-1); //在數組首位添加 -1 System.out.println(arr); } }
輸出:
8.數組中包含,搜索和刪除元素
刪除元素:插入元素的反過程,索引2的值 左移到 1 的值,實際是索引2賦值給索引1,覆蓋掉原來的值,size 的值覆蓋掉 size-1的值。size的值 -1(左移);由於要求訪問數組元素 < size,故用戶沒法訪問到 size 索引中的值(圖中的100)
刪除完成
示例代碼:Array.java
public class Array { private int[] data; private int size; // 構造函數,傳入數組的容量capacity構造Array public Array(int capacity){ data = new int[capacity]; size = 0; } // 無參數的構造函數,默認數組的容量capacity=10 public Array(){ this(10); } // 獲取數組的容量 public int getCapacity(){ return data.length; } // 獲取數組中的元素個數 public int getSize(){ return size; } // 返回數組是否爲空 public boolean isEmpty(){ return size == 0; } // 向全部元素後添加一個新元素 public void addLast(int e){ add(size, e); } // 在全部元素前添加一個新元素 public void addFirst(int e){ add(0, e); } // 在index索引的位置插入一個新元素e public void add(int index, int e){ if(size == data.length) throw new IllegalArgumentException("Add failed. Array is full."); if(index < 0 || index > size) throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); for(int i = size - 1; i >= index ; i --) data[i + 1] = data[i]; data[index] = e; size ++; } // 獲取index索引位置的元素 public int get(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Get failed. Index is illegal."); return data[index]; } // 修改index索引位置的元素爲e public void set(int index, int e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set failed. Index is illegal."); data[index] = e; } // 查找數組中是否有元素e(新增代碼) public boolean contains(int e){ for(int i = 0 ; i < size ; i ++){ if(data[i] == e) return true; } return false; } // 查找數組中元素e所在的索引,若是不存在元素e,則返回-1(新增代碼) public int find(int e){ for(int i = 0 ; i < size ; i ++){ if(data[i] == e) return i; } return -1; } // 從數組中刪除index位置的元素, 返回刪除的元素(新增代碼) public int remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed. Index is illegal."); int ret = data[index]; for(int i = index + 1 ; i < size ; i ++) data[i - 1] = data[i]; //數組左移 size --; return ret; } // 從數組中刪除第一個元素, 返回刪除的元素(新增代碼) public int removeFirst(){ return remove(0); } // 從數組中刪除最後一個元素, 返回刪除的元素(新增代碼) public int removeLast(){ return remove(size - 1); } // 從數組中刪除元素e(新增代碼) public void removeElement(int e){ int index = find(e); if(index != -1) remove(index); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length)); res.append('['); for(int i = 0 ; i < size ; i ++){ res.append(data[i]); if(i != size - 1) res.append(", "); } res.append(']'); return res.toString(); } }
Main.java
public class Main { public static void main(String[] args) { Array arr = new Array(20); for(int i = 0 ; i < 10 ; i ++) arr.addLast(i); System.out.println(arr); arr.add(1, 100); System.out.println(arr); arr.addFirst(-1); System.out.println(arr); // [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] arr.remove(2); //刪除索引爲2的元素(新增代碼) System.out.println(arr); arr.removeElement(4);//刪除元素 4(新增代碼) System.out.println(arr); arr.removeFirst(); System.out.println(arr);//刪除頭元素(新增代碼) } }
輸出:
8.使用泛型
泛型:使數據結構能夠放置全部的「數據類型」;但只能放置類對象,不能是基本數據類型(boolean、byte、char、short、int、long、float、double),爲了解決這個問題,Java 中每一個基本數據類型都有對應的包裝類(將原本不是類對象的變成了類對象);
基本數據類型對應的包裝類[Boolean、Byte、Char、Short、Int、Long、Float、Double ] 兩者之間能夠互相轉換
示例代碼(Array.java)
public class Array<E> { //聲明爲E類型的泛型數組 private E[] data; //(修改代碼) private int size; // 構造函數,傳入數組的容量capacity構造Array public Array(int capacity){ data = (E[])new Object[capacity];//(修改代碼,java 中不支持直接new出泛型數組) //解決方式:New Object,在 Java 中任意類都是 Object 類的子類;再通過強制類型轉換(E[])轉換成E類型) size = 0; } // 無參數的構造函數,默認數組的容量capacity=10 public Array(){ this(10); } // 獲取數組的容量 public int getCapacity(){ return data.length; } // 獲取數組中的元素個數 public int getSize(){ return size; } // 返回數組是否爲空 public boolean isEmpty(){ return size == 0; } // 在index索引的位置插入一個新元素e public void add(int index, E e){ //(修改代碼) if(size == data.length) throw new IllegalArgumentException("Add failed. Array is full."); if(index < 0 || index > size) throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); for(int i = size - 1; i >= index ; i --) data[i + 1] = data[i]; data[index] = e; size ++; } // 向全部元素後添加一個新元素 public void addLast(E e){ //(修改代碼) add(size, e); } // 在全部元素前添加一個新元素 public void addFirst(E e){ //(修改代碼) add(0, e); } // 獲取index索引位置的元素 public E get(int index){ //(修改代碼) if(index < 0 || index >= size) throw new IllegalArgumentException("Get failed. Index is illegal."); return data[index]; } // 修改index索引位置的元素爲e public void set(int index, E e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set failed. Index is illegal."); data[index] = e; } // 查找數組中是否有元素e public boolean contains(E e){ for(int i = 0 ; i < size ; i ++){ if(data[i].equals(e)) //(修改代碼,對象之間的比較用equals,值比較) return true; } return false; } // 查找數組中元素e所在的索引,若是不存在元素e,則返回-1 public int find(E e){ for(int i = 0 ; i < size ; i ++){ if(data[i].equals(e)) //(修改代碼,對象之間的比較用equals,值比較) return i; } return -1; } // 從數組中刪除index位置的元素, 返回刪除的元素 public E remove(int index){ //(修改代碼,int改成E) if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed. Index is illegal."); E ret = data[index]; for(int i = index + 1 ; i < size ; i ++) data[i - 1] = data[i]; size --; data[size] = null; // loitering objects != memory leak 使數組最後引用中的值被垃圾回收 return ret; } // 從數組中刪除第一個元素, 返回刪除的元素 public E removeFirst(){ //(修改代碼,int改成E) return remove(0); } // 從數組中刪除最後一個元素, 返回刪除的元素 public E removeLast(){ //(修改代碼,int改成E) return remove(size - 1); } // 從數組中刪除元素e public void removeElement(E e){ //(修改代碼,int改成E) int index = find(e); if(index != -1) remove(index); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length)); res.append('['); for(int i = 0 ; i < size ; i ++){ res.append(data[i]); if(i != size - 1) res.append(", "); } res.append(']'); return res.toString(); } }
Main.java
public class Main { public static void main(String[] args) { Array<Integer> arr = new Array<>(20); //(修改代碼,Array 後添加<Integer>,int 類型的包裝類) for(int i = 0 ; i < 10 ; i ++) arr.addLast(i); System.out.println(arr); arr.add(1, 100); System.out.println(arr); arr.addFirst(-1); System.out.println(arr); // [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] arr.remove(2); System.out.println(arr); arr.removeElement(4); System.out.println(arr); arr.removeFirst(); System.out.println(arr); } }
輸出:與以前同樣
新建 Student.java
public class Student { private String name; private int score; public Student(String studentName, int studentScore){ name = studentName; score = studentScore; } @Override public String toString(){ return String.format("Student(name: %s, score: %d)", name, score); } public static void main(String[] args) { Array<Student> arr = new Array<>(); arr.addLast(new Student("Alice", 100)); arr.addLast(new Student("Bob", 66)); arr.addLast(new Student("Charlie", 88)); System.out.println(arr); } }
輸出: