1 public class Mycache { 2 private int count = 0; 3 private Node head = null; 4 5 class Node { 6 private String key; 7 private int value; 8 private Node next = null; 9 10 public Node(String key, int value, Node next) { 11 this.key = key; 12 this.value = value; 13 this.next = next; 14 } 15 public String getKey() { 16 return key; 17 } 18 public void setKey(String key) { 19 this.key = key; 20 } 21 public int getValue() { 22 return value; 23 } 24 public void setValue(int value) { 25 this.value = value; 26 } 27 public Node getNext() { 28 return next; 29 } 30 public void setNext(Node next) { 31 this.next = next; 32 } 33 } 34 35 public void save(String key, int value) { 36 if(head != null) { 37 Node item = head; 38 do { 39 if(item.getKey().equals(key)) { 40 item.setValue(value); 41 return; 42 } 43 item = item.next; 44 }while(item != null); 45 46 if(count < 5) { 47 item = head; 48 head = new Node(key, value, null); 49 head.next = item; 50 count++; 51 }else { 52 System.out.println("基於LRU緩存策略移除隊尾元素"); 53 54 Node itemToRemove = head; 55 while(itemToRemove.next != null) { 56 itemToRemove = itemToRemove.next; 57 } 58 59 item = head; 60 while(item.next != itemToRemove) { 61 item = item.next; 62 } 63 item.next = null; 64 65 item = head; 66 head = new Node(key, value, null); 67 head.next = item; 68 } 69 }else { 70 head = new Node(key, value, null); 71 count++; 72 } 73 } 74 public int get(String key) { 75 int result = 0; 76 Node itemToRemove = head; 77 do { 78 if(itemToRemove.getKey().equals(key)) { 79 result = itemToRemove.getValue(); 80 81 Node item = head; 82 while(item.next != itemToRemove) { 83 item = item.next; 84 } 85 item.next = itemToRemove.next; 86 87 itemToRemove.next = head; 88 head = itemToRemove; 89 90 return result; 91 } 92 itemToRemove = itemToRemove.next; 93 }while(itemToRemove != null); 94 95 throw new RuntimeException("緩存中沒有對應的數據"); 96 } 97 98 public void iterate() { 99 Node item = head; 100 while(item != null) { 101 System.out.println("【key=" + item.getKey() + ",value=" + item.getValue() + "】"); 102 item = item.next; 103 } 104 } 105 public static void main(String[] args) { 106 Mycache cache = new Mycache(); 107 cache.save("a", 1); 108 cache.iterate(); 109 System.out.println("----------------"); 110 cache.save("b", 2); 111 cache.iterate(); 112 System.out.println("----------------"); 113 cache.save("c", 3); 114 cache.iterate(); 115 System.out.println("----------------"); 116 cache.save("d", 4); 117 cache.iterate(); 118 System.out.println("----------------"); 119 cache.save("e", 5); 120 cache.iterate(); 121 System.out.println("----------------"); 122 cache.save("f", 6); 123 cache.iterate(); 124 System.out.println("----------------"); 125 int result = cache.get("b"); 126 System.out.println(result); 127 cache.iterate(); 128 } 129 }
//基於數組實現的順序棧 public class ArrayStack { private int[] items;//數組 private int n;//棧的大小 private int count;//棧中元素個數 public ArrayStack(int n) { items = new int[n]; this.n = n; this.count = 0; } //入棧操做 public boolean push(int value) { //數組空間不足,直接返回false,入棧失敗 if(count >= n) { return false; } //將item放到下標爲count的位置,而且count自增1 items[count++] = value; return true; } //出棧操做 public int pop() { //棧爲空,則直接返回null if(count <= 0) { return -9999; } //返回下標爲count-1的數組元素,而且棧中元素個數count自減1 return items[--count]; } public static void main(String[] args) { ArrayStack stack = new ArrayStack(3); stack.push(11); stack.push(22); stack.push(33); stack.push(44); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); stack.push(555); System.out.println(stack.pop()); System.out.println(stack.pop()); } }
//基於鏈表實現的鏈式棧 public class LinkedListStack { //哨兵機制,帶頭節點 private Node head = new Node(null); //入棧操做 public void push(String value) { if(value == null) { return; } Node newNode = new Node(value); newNode.next = head.next; head.next = newNode; } //出棧操做 public String pop() { Node result = head.next; if(result == null) { return null; } head.next = result.next; return result.value; } class Node{ private String value; private Node next = null; public Node(String value) { this.value = value; } } public static void main(String[] args) { LinkedListStack stack = new LinkedListStack(); stack.push("aa"); stack.push("bb"); stack.push("cc"); System.out.println(stack.pop()); System.out.println(stack.pop()); stack.push("1111"); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); } }
public class Expression { //操做數棧 private ArrayStack operandStack = new ArrayStack(20); //運算符棧 private LinkedListStack operatorStack = new LinkedListStack(); public int process(String expression) { int result = 0; String exp = expression; int firstOperatorIndex = 9999; do { firstOperatorIndex = getFirstOperatorIndex(exp); if(firstOperatorIndex == 9999) { break; } //操做數入棧 operandStack.push(Integer.parseInt(exp.substring(0, firstOperatorIndex))); //運算符入棧 String topOperator = operatorStack.pop(); String currOperator = exp.substring(firstOperatorIndex, firstOperatorIndex+1); boolean priorityCompare = true; while(!(priorityCompare = priorityCompare(currOperator, topOperator))) { int operand1 = operandStack.pop(); int operand2 = operandStack.pop(); int tmpResult = cal(operand1, operand2, topOperator); operandStack.push(tmpResult); topOperator = operatorStack.pop(); } operatorStack.push(topOperator); operatorStack.push(currOperator); exp = exp.substring(firstOperatorIndex + 1); }while(!exp.isEmpty()); operandStack.push(Integer.parseInt(exp)); String operand = null; while((operand = operatorStack.pop()) != null) { int operand1 = operandStack.pop(); int operand2 = operandStack.pop(); int tmpResult = cal(operand1, operand2, operand); operandStack.push(tmpResult); } return operandStack.pop(); } private int getFirstOperatorIndex(String expression) { int addIndex = expression.indexOf("+"); int minusIndex = expression.indexOf("-"); int mulIndex = expression.indexOf("*"); int divIndex = expression.indexOf("/"); int firstOperatorIndex = 9999; if(addIndex > 0) { firstOperatorIndex = Math.min(firstOperatorIndex, addIndex); } if(minusIndex > 0) { firstOperatorIndex = Math.min(firstOperatorIndex, minusIndex); } if(mulIndex > 0) { firstOperatorIndex = Math.min(firstOperatorIndex, mulIndex); } if(divIndex > 0) { firstOperatorIndex = Math.min(firstOperatorIndex, divIndex); } return firstOperatorIndex; } //若是source優先級比target高,則返回true,不然返回false private boolean priorityCompare(String source, String target) { if(target == null) { return true; } if((source.equals("*") || source.equals("/")) && (target.equals("+") || target.equals("-"))) { return true; } return false; } //運算 private int cal(int operand1, int operand2, String operator) { int result = 0; if(operator.equals("+")) { result = operand2 + operand1; }else if(operator.equals("-")) { result = operand2 - operand1; }else if(operator.equals("*")) { result = operand2 * operand1; }else if(operator.equals("/")) { result = operand2 / operand1; } return result; } public static void main(String[] args) { Expression expression = new Expression(); System.out.println(expression.process("2+5*4-8/2-1+3*2")); } }
/* * 問題:假設咱們有1000萬個整數數據,每一個數據佔8個字節,如何設計數據結構和算法,快速判斷某個整數是否出如今這1000萬數據中? * 分析:1000萬個整數數據,每一個數據佔8個字節,存儲在數組中,內存佔用差很少是80MB,採用二分查找時間複雜度爲O(logn),而且 * 二分查找除了數據自己以外,不須要額外存儲其餘信息,符合內存的限制。咱們說,二分查找是最省內存空間的快速查找算法。 */ /** * 二分查找算法:針對的是一個有序的數據集合,時間複雜度爲O(logn) * @author Administrator * * 二分查找應用場景的侷限性 * 一、二分查找只能用在數據是經過順序表來存儲的數據結構上,簡單點說就是二分查找只適合用於數組,由於二分查找算法 * 須要按照下標隨機訪問元素 * 二、二分查找針對的是有序數據,只適合用在插入、刪除操做不頻繁,一次排序屢次查找的場景中,不適用於動態變化的數據集合 * 三、數據量太大不適合二分查找,緣由是二分查找的底層依賴數組這種數據結構,而數組爲了支持隨機訪問的特性,要求使用 * 連續的內存空間,太大量的數據不適合用連續的內存空間存儲 */ public class BinarySearch { /** * 最簡單狀況(有序數組中不存在重複元素) 用循環實現 * @param a 給定的有序數組 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int simpleSearchBaseLoop(int[] a, int value) { //當前查找的區間範圍 int low = 0, high = a.length - 1; //中間位置 int mid = 0; //終止條件(一、區間縮小爲0(low>high) 二、 找到目標值) while(low <= high) { //計算當前查找區間範圍的中間位置 mid = (low + high)/2; //當前查找區間範圍的中間位置的值與目標值進行比較 if(a[mid] == value) { return mid; }else if(a[mid] < value) { low = mid + 1; }else { high = mid - 1; } } return -1; } /** * 須要注意的3個地方: * 一、循環執行條件是 low <= high,而不是low < high * 二、mid的取值 mid=(low+high)/2 這種寫法其實是有問題的,由於若是low和high比較大的話,二者之和就有可能會溢出。 * 改進的方法是將 mid 的計算方式寫成 mid=low+(high-low)/2。更進一步,若是要將性能優化到極致的話,咱們能夠將這裏 * 的除以2操做轉化成位運算 mid=low+((high-low)>>1),由於相比除法來講,計算機處理位運算要快得多 * 三、low和high的更新是 low=mid+1,high=mid-1,若是直接寫成low=mid,high=mid 就有可能會發生死循環,好比 * 當high=3,low=3,而且a[3]不等於value時,就會致使一直循環不退出 */ /** * 最簡單狀況(有序數組中不存在重複元素) 用遞歸實現 * @param a 給定的有序數組 * @param low 當前查找範圍的最小值 * @param high 當前查找範圍的最大值 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int simpleSearchBaseRecursion(int[] a, int low, int high, int value) { //判斷當前查找範圍是否已經縮小爲0 if(low > high) { return -1; } int mid = low + ((high-low)>>1); if(a[mid] == value) { //找到目標值直接返回 return mid; }else if(a[mid] < value) { //未找到目標值,縮小範圍遞歸查找 return simpleSearchBaseRecursion(a, mid+1, high, value); }else { //未找到目標值,縮小範圍遞歸查找 return simpleSearchBaseRecursion(a, low, mid-1, value); } } /** * 二分查找變種1:查找第一個值等於給定值的元素 * @param a 給定的有序數組 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int binarySearchVarietas1(int[] a, int value) { /*************簡潔寫法********************* int n = a.length; int low = 0, high = n - 1; int mid = 0; while(low <= high) { mid = low + ((high - low)>>1); if(a[mid] < value) { low = mid + 1; }else { high = mid - 1; } } //若是low<n,則說明value在[a[0], a[n-1]]範圍內,此時只須要判斷a[low]是否等於value便可 if(low < n && a[low] == value) { return low; }else { return -1; } ************************************/ int n = a.length; int low = 0, high = n - 1; int mid = 0; while(low <= high) { mid = low + ((high - low)>>1); if(a[mid] < value) { low = mid + 1; }else if(a[mid] > value) { high = mid - 1; }else { //判斷是不是第一個等於value的元素 if(mid == 0 || a[mid-1] != value) { return mid; } high = mid - 1; } } return -1; } /** * 二分查找變種2:查找最後一個值等於給定值的元素 * @param a 給定的有序數組 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int binarySearchVarietas2(int[] a, int value) { int n = a.length; int low = 0, high = n - 1; int mid = 0; while(low <= high) { mid = low + ((high - low)>>1); if(a[mid] < value) { low = mid + 1; }else if(a[mid] > value) { high = mid - 1; }else { //判斷是不是最後一個等於value的元素 if(mid == n-1 || a[mid+1] != value) { return mid; } low = mid + 1; } } return -1; } /** * 二分查找變種3:查找第一個大於等於給定值的元素 * @param a 給定的有序數組 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int binarySearchVarietas3(int[] a, int value) { int n = a.length; int low = 0, high = n - 1; int mid = 0; while(low <= high) { mid = low + ((high - low)>>1); if(a[mid] < value) { low = mid + 1; }else { //判斷是不是第一個小於等於value的元素 if(mid == 0 || a[mid-1] < value) { return mid; } high = mid - 1; } } return -1; } /** * 二分查找變種4:查找最後一個小於等於給定值的元素 * @param a 給定的有序數組 * @param value 待查找的目標值 * @return 查找結果的下標 */ public int binarySearchVarietas4(int[] a, int value) { int n = a.length; int low = 0, high = n - 1; int mid = 0; while(low <= high) { mid = low + ((high - low)>>1); if(a[mid] > value) { high = mid - 1; }else { //判斷是不是最後一個等於value的元素 if(mid == n-1 || a[mid+1] > value) { return mid; } low = mid + 1; } } return -1; } }