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; } }