今日学习总结
今日算法学习
堆排序
实现大根堆
核心思想:
-
利用数组实现一个大根堆(完全二叉树,每棵子树的根节点是最大的)
-
插入一个元素时,将它放到heapsize的位置(数组最后一位),接着不断地跟它的父节点比较,直到小于自己的父节点
-
弹出一个元素时,将0位置的元素弹出,接着通过heapify调整大根堆,弹出后,将最后一个节点交换到0位置,接着0位置的节点不断下沉,直到小于自己的父节点
package day10;
import java.util.HashMap;
import java.util.Map;
public class Heap {
private int[] heap;
private Map<Integer, Integer> heapMap;
private int heapSize;
public Heap(int heapSize) {
this.heap = new int[heapSize];
this.heapMap = new HashMap<>();
this.heapSize = heapSize;
}
public void push(int value) {
heap[heapSize] = value;
insertHeap(heap, heapSize++);
}
public void insertHeap(int[] arr, int index) {
while (arr[index] > heap[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
public int pop() {
int ans = heap[0];
swap(heap, 0, --heapSize);
heapify(heap, 0, heapSize);
return ans;
}
//从index位置一直往下沉,直到子节点不比自己大
private void heapify(int[] heap, int index, int heapSize) {
int left = 2 * index + 1;
while (left<heapSize){
int largest = left+1<heapSize&&heap[left]>heap[left+1]?left:left+1;
largest = heap[largest]>heap[index]?largest:index;
if (largest == index){
break;
}
swap(heap,largest,index);
index = largest;
left = 2*index+1;
}
}
public void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
}
利用小根堆优化迪杰斯特拉算法
核心思想:
- 自己构建一个小根堆,里面存放的是节点元素
- 构建一个hashmap保存每个节点到源节点的距离
- 每次从小根堆中弹出一个节点记录(节点以及他到源节点的距离),这个节点就是离源节点最近的节点
- 将该节点的连接节点,都存入小根堆中,如果本来就在的话就比较距离,如果不在的话就直接插入,并调整小根堆
package day10;
import day08Graph.Edge;
import day08Graph.Node;
import java.util.HashMap;
public class NodeHeap {
private Node[] nodes;
private HashMap<Node, Integer> heapIndexMap;
private HashMap<Node, Integer> distanceMap;
private int size;
public NodeHeap(int size) {
nodes = new Node[size];
heapIndexMap = new HashMap<>();
distanceMap = new HashMap<>();
this.size = size;
}
public boolean isEmpty() {
return size == 0;
}
//有一个node,发现一个从原节点到node的距离为distance
//判断是否要更新,如果需要的话,就更新
public void addOrUpdateOrIgnore(Node node, int distance) {
//如果在堆中
if (inHeap(node)) {
distanceMap.put(node, Math.min(distanceMap.get(node), distance));
insertHeap(node, heapIndexMap.get(node));
}
if (!isEntered(node)) {
nodes[size] = node;
heapIndexMap.put(node, size);
distanceMap.put(node, distance);
insertHeap(node, size++);
}
}
public NodeRecord pop(){
NodeRecord nodeRecord = new NodeRecord(nodes[0],distanceMap.get(nodes[0]));
swap(0,size-1);
heapIndexMap.put(nodes[size-1],-1);
distanceMap.remove(nodes[size-1]);
nodes[size-1] = null;
heapify(0,--size);
return nodeRecord;
}
private void heapify(int index, int size) {
int left = index*2+1;
while (left < size) {
int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left])
? left + 1
: left;
smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index;
if (smallest == index) {
break;
}
swap(smallest, index);
index = smallest;
left = index * 2 + 1;
}
}
private boolean isEntered(Node node) {
return heapIndexMap.containsKey(node);
}
private boolean inHeap(Node node) {
return isEntered(node) && heapIndexMap.get(node) != -1;
}
private void insertHeap(Node node, int index) {
while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) {
swap(index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
private void swap(int index1, int index2) {
heapIndexMap.put(nodes[index1], index2);
heapIndexMap.put(nodes[index2], index1);
Node tmp = nodes[index1];
nodes[index1] = nodes[index2];
nodes[index2] = tmp;
}
//主要的改进点在于,之前需要遍历当前节点的所有节点取最近的,现在可以通小根堆获得距离原节点最近的点
public static HashMap<Node, Integer> dijkstra2(Node head, int size) {
NodeHeap nodeHeap = new NodeHeap(size);
nodeHeap.addOrUpdateOrIgnore(head, 0);
HashMap<Node, Integer> result = new HashMap<>();
while (!nodeHeap.isEmpty()) {
NodeRecord record = nodeHeap.pop();
Node cur = record.node;
int distance = record.distance;
for (Edge edge : cur.edges) {
nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);
}
result.put(cur, distance);
}
return result;
}
}
暴力递归
- 把问题转化为规模缩小了的同类问题的子问题
- 有明确的不需要继续进行递归的条件
- 有当得到了子问题的结果之后的决策过程
- 不记录每一个子问题的解
分布式框架学习-dubbo
搭建dubbo 框架demo
向zookeeper注册服务提供者
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 1.服务提供方在zookeeper中的别名-->
<dubbo:application name="dubbo-server"/>
<!--2.注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.21.128:2181"/>
<!-- 3.扫描类(将什么包下的类作为服务提供类-->
<dubbo:annotation package="service.impl"/>
</beans>
使用dubbo包下的service注解标注
import com.alibaba.dubbo.config.annotation.Service;
import service.HelloService;
@com.alibaba.dubbo.config.annotation.Service
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello,"+name;
}
}