第一章 什麼是數據結構和算法java
數據結構的概述算法
數據結構是指 數據再計算機內存空間或磁盤空間中的組織形式數據庫
1.數據結構的特性數組
數據結構 | 優勢 | 缺點 |
數組 | 插入快,若是知道下標能夠快速存取 | 查找和刪除慢 大小固定 |
有序數組 | 比無序數組查找快 | 插入和刪除慢 大小固定 |
棧 | 後進先出 | 存取其餘項很慢 |
隊列 | 先進先出 | 存取其餘項很慢 |
鏈表 | 插入和刪除快 | 查找慢 |
二叉樹 | 查找,插入,刪除都快(若是保持平衡) | 刪除算法複雜 |
紅黑樹 | 查找,插入,刪除都快 樹老是是平衡的 | 算法複雜 |
2-3-4樹 | 查找,插入,刪除都快 樹老是平衡的 相似的數對磁盤存儲有用 | 算法複雜 |
哈希表 | 若是key已知則存取快,插入快 | 刪除慢 若是key不知存取慢 空間利用不足 |
堆 | 插入 刪除快,對最大數據存取快 | 對其餘項存取慢 |
圖 | 實現世界建模 | 有些算法慢 且 複雜 |
算法概述 數據結構
算法是完成特定任務的過程架構
database 數據庫dom
record 記錄數據結構和算法
field 字段工具
key 關鍵字性能
java基本數據類型
int ,short, char ,byte, long ,double, float,boolean
java 數據結構的類庫
java.until.*;
第二章 數組
1.有序數組二分法查找
public class SortArray { private int[] values = {2, 11, 44, 55, 357,358,400,414,505}; //查找某值得索引 private int find(int searchValue) { //|----------------------| //lower--> <--upper int lowerBound = 0; int upperBound = values.length - 1; int current; while (true) { current = (lowerBound + upperBound) / 2; //值判斷 if(values[current]==searchValue){ return current; }else if(lowerBound>upperBound){ //索引判斷 return -1;//can't find 跳出循環 }else { if(values[current]>searchValue){ //<--- upper (upper向內移動) upperBound=current-1; }else { //lower---> (lower向內移動) lowerBound=current+1; } } } } @Test public void test_find() { System.out.println(find(44)); System.out.println(find(358)); System.out.println(find(111)); } }
二分法查找與 log(N)成正比
大 O 表示法 不要常數
O(1)是優秀
性能良好
O(N) 性能通常
性能較差
大O時間圖(時間受數據項個數影響):
無序數組 快速插入 查找刪除慢
有序數據 可使用二分法查找
第三章 簡單排序
簡單排序包括
通常的排序 方法 (CAS : compare and swap)
1.比較兩個數據項
2.交換兩個數據項,或複製其中一項
冒泡排序
冒泡排序就是 比較相鄰 大的往右冒泡
1.比較兩個隊員
2.若是左邊的大 則交換位置
3.向右移一個位置 一次比較下面兩個
4.一直比較下去。。。。
(每一個的左邊 和其右邊進行比較)
。。。。。。
。。。。。。
冒泡排序第一趟 (挑出最大值)
冒泡排序java代碼
bubble [ˈbəbəl] 冒泡
public class BubbleSort { private int[] buildIntArray(int size){ int[] arr=new int[size]; for(int i=0;i<size;i++){ arr[i]= RandomUtils.nextInt(1,100); } return arr; } /* 冒泡排序 大的值往右冒泡 */ public void bubble(int[] arr){ int out,in,temp; //第一趟 最大的已經冒泡到最右邊, 因此第二趟不用再排。 減掉 out-- for(out=arr.length-1;out>0;out--){ //從左到右依次冒泡 因此 從0 依次比較 for(in=0;in<out;in++){ //往右冒泡 若左邊大於右邊 冒泡 if(arr[in]>arr[in+1]){ temp=arr[in+1]; arr[in+1]=arr[in]; arr[in]=temp; } } } } @Test public void testSort(){ int []arr=buildIntArray(9); System.out.println(Arrays.toString(arr)); bubble(arr); System.out.println(Arrays.toString(arr)); } }
冒泡排序的 時間級別
第一趟 須要比較 n-1次
第二趟 須要比較 n-2次
第三趟 須要比較 n-3次
。。。。。
=n(n-1)/2;
約爲 N的平方
因此冒泡排序的時間複雜度 爲
選擇排序
選擇排序改進了冒泡排序
選擇排序: 就是查找選擇最小值 放在最左邊,這樣左邊的就排好序了
選擇排序java代碼
public class SelectSort { private int[] buildIntArray(int size) { int[] arr = new int[size]; for (int i = 0; i < size; i++) { arr[i] = RandomUtils.nextInt(1,100); } return arr; } /* 選擇排序 選出最小的放在左邊 */ private void select(int[] arr) { int out, in, temp; //左邊是排好序的 不用排了 因此out++ for (out = 0; out < arr.length - 1; out++) { //out 左邊是排好了的 比較 out之後的 for (in = out + 1; in < arr.length; in++) { //out是左邊的值,in是右邊的值 由於 in=out+1 //若是 右邊的值小 把它交換到左邊 if (arr[in] < arr[out]) { temp = arr[in]; arr[in] = arr[out]; arr[out] = temp; } } } } @Test public void testSort() { int[] arr = buildIntArray(9); System.out.println(Arrays.toString(arr)); select(arr); System.out.println(Arrays.toString(arr)); } }
選擇 排序 時間複雜度
可是選擇排序的速度快於冒泡排序 由於它進行的交換次數少;
插入排序
插入排序 通常狀況下 比冒泡排序快一倍 ,比選擇排序還要快一點
採用 局部有序 的方法
java代碼
public class InsertSort { private int[] buildIntArray(int size) { int[] arr = new int[size]; for (int i = 0; i < size; i++) { arr[i] = RandomUtils.nextInt(0,100); } return arr; } public void insert(int[] arr){ int in,out; //外圍的 循環次數 逐漸增長, 由於 左邊排好的個數逐漸增長 for(out=1;out<arr.length;out++){ int temp=arr[out];//被標記的值,要排序的值 in=out;//和左邊已經排好的值 進行比較 //從最大值 依次向左 逐個比較 // 若是 左邊的最大值 大於 temp ,再往左 找個小的值 和 temp比較 //while 沒我大 排到後面去 while (in>0&&arr[in-1]>=temp){ arr[in]=arr[in-1]; --in; } arr[in]=temp; } } @Test public void testSort() { int[] arr = buildIntArray(9); System.out.println(Arrays.toString(arr)); insert(arr); System.out.println(Arrays.toString(arr)); } }
插入排序的時間複雜度也是
第四章 棧和隊列
受限訪問 ,更加抽象 做爲構思算法的輔助工具
棧(stack)
後進先出
棧只容許訪問一個數據項,即最後插入的數據項。移除第一個數據項後 ,才能夠訪問第二個數據項。
用數組實現一個簡單的棧
peek [pēk] :窺視
public class StackA { private int[] arr; private int max; private int top; public StackA(int max) { this.max = max; this.arr=new int[max]; this.top=-1; } public void push(int v){ arr[++top]=v; } public int pop(){ return arr[top--]; } /* Look at the obj at the top of stack without remove it */ public int peek(){ return arr[top]; } public boolean isEmpty(){ return top==-1; } public boolean isFull(){ return top==max-1; } }
測試
public void test(){ StackA stackA=new StackA(7); stackA.push(1); stackA.push(2); stackA.push(3); stackA.push(4); stackA.push(5); while (!stackA.isEmpty()){ System.out.println(stackA.pop()); } }
寫個demo檢測 輸入內容的 括號是否正確
bracket [ˈbrakit] : 括號
public class Bracket { private String input; public Bracket(String input) { this.input = input; } public void check() { if (StringUtils.isNotBlank(input)) { StackA stackA = new StackA(input.length()); for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); switch (c) { case '{': case '[': case '(': stackA.push(c); break; case '}': case ']': case ')': if (!stackA.isEmpty()) { char store = (char) stackA.pop(); if ((c == '}' && store != '{') || (c == ']' && store != '[') || (c == ')' && store != '(') ) { System.out.println("Error " + c + " at " + i); return; } } else { System.out.println("Error " + c + " at " + i); return; } break; default: break; } } if (!stackA.isEmpty()) { System.out.println("Error no bracket match with " + (char) stackA.peek()); } } } }
測試
public void test(){ Bracket bracket=new Bracket("test(just test}"); bracket.check(); bracket=new Bracket("test :just test {"); bracket.check(); }
運行結果