10.图
-
邻接表
-
邻接矩阵
-
点集、边集,入读、出度
1.宽度优先遍历
public static void bfs(Node node)
{
if(node==null)
{
return;
}
Queue<Node> queue = new Queue<Node>();
HashSet<Node> set = new HashSet<Node>();
queue.add(node);
set.add(node);
while(!queue.isEmpty)
{
Node p = queue.poll();
System.out.println(p);
for(Node next:p.nexts){
if(!set.contains(next))
{
set.add(next);
queue.add(next);
}
}
}
}
2.深度优先
public static void dfs(Node node)
{
if(node==null)
{
return;
}
Stack<Node> stack = new Stack<Node>();
HashSet<Node> set = new HashSet<Node>();
stack.add(node);
set.add(set);
System.out.println(node.value);
while(!stack.isEmpty)
{
Node p = stack.pop();
for(Node cur:p.nexts)
{
if(!set.contains(cur))
{
stack.push(p);
stack.push(cur);
set.add(cur);
break;
}
}
}
}
3.拓扑排序
入度为0,放在最前面,然后消除堆剩余点的入度、出度影响
4.最小生成树
k算法:将边从小到大排序,遍历,若加上边后,没有形成环,就加上,否则不要
怎么判断环:将点分成一个个集合,每次加上边时,若from点和to点不在同一个点,则可以加上,然后把两个集合合并,如果在一个集合,则不能加上这个边
public HashMap<Node,List<Node>> setMap;
public MySets(List<Node> nodes){
for(Node cur:nodes){
List<Node> set = new List<Node>();
set.add(cur);
setMap.put(cur,set);
}
}
public boolean isSameSet(Node from,Node to){
List<Node> fromList = setMap.get(from);
List<Node> toList = setMap.get(to);
return fromList == toList;
}
public void union(Node from,Node to){
List<Node> fromList = setMap.get(from);
List<Node> toList = setMap.get(to);
for(Node toNode : toList){
fromList.add(toNode);
setMap.put(toNode,fromList);
}
}
p算法:从任意点开始,选择最小的边,如果边的两边都已经加入,将该边舍去,重新找最小的边,如果没有,将边的另一个点加入,并将该点的边都加入可选择的边集合中
priorityQueue优先级队列;
Set<Edge> result = new HashSet<>();
HashSet<Node> set = new HashSet<>();
PriorityQueue<Edge> priorityQueue = new priorityQueue(有一个比较器);
for(Node node:graph.nodes.values()){//
if(!set.contains(node)){
set.add(node);
for(Edge edge:node.edges){
priority.add(edge);
}
while(!priorityQuwuw.isEmpty()){
Edge edge = priorityQueue.poll();
Node toNode = edge.toNode;
if(!set.contains(node)){
set.add(node);
result.add(edge);
for(Edge edge:node.edges){
priority.add(edge);
}
}
}
}
}
5.Dijkstra算法
可以有负数的边,不能有和为负数的环,如果有的话,那么环可以一直循环下去,直到无穷小
HashMap<Node,Integer> distanceMap = new HashMap<>();
distanceMap.put(head,0);
//head点到key点最近距离为value
HashSet<Node> selectNode = new HashSet<>();
//已经更新过的点放在selectNode中
Node minNode = gewMinAndUnselected();
while(midNode!=null){
int distance = distanceMap.get(minNode);
for(Edge edge:minNode.Edges){
Node toNode = edge.toNode;
if(!distanceMap.containsKey(toNode)){
distanceMap.put(toNode,edge.value+distance);
}
distanceMap.put(toNode,Math.min(edge.value+distance,distanceMap.get(toNode)));
}
selectNode.add(midNode);
minNode = gewMinAndUnselected();
}
return distanceMap;
优化:改写堆,系统给出的堆能弹出最小(最大值),但加入后不能再变,所以要改写
11贪心
1.前缀树
//数据结构
public Trie(){
root = new TrieNode();
}
public static class TrieNode{
public int pass;//经过该字符的字符串树
public int end;//以该字符结束的字符串树
//可换成HashMap<char,Node>
//可换成TreeMap<char,Node>有序表
public TrieNode[] nexts;
public TrieNode(){
pass=0;
end=0;
nexts=new TrieNode[26];
}
}
//创建前缀树
public void insert(String word)
{
if(word==null)
{
return ;
}
char[] str = word.toCharArray();
TrieNode node = root;
node.pass++;
ine index = 0;
for(int i=0;i<str.length;i++)
{
index = str[i]-'a';
if(node.nexts[index]==null)
{
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.pass++;
}
node.end++;
}
//word插入过几次
public int search(String word)
{
if(word==null)
{
return 0;
}
char[] str = word.toCharArray();
TrieNode node = root;
int index = 0;
for(int i=0;i<str.length;i++)
{
index = char[i]-'a';
if(node.nexts[index]==null)
{
return 0;
}
node = node.nexts[index];
}
return node.end;
}
//有几个以pre为前缀的字符串
public int preCount(String pre){
if(pre==null)
{
return 0;
}
char[] str = pre.toCharArray();
TrieNode node = root;
int index=0;
for(int i=0;i<str.length;i++)
{
index=str[i]-'a';
if(node.nexts[index]==null)
{
return 0;
}
node = node.nexts[index];
}
return node.pass;
}
//删除delete
public void delete(String word){
id(!search(word)){
char str = word.toCharArray();
TrieNode node = root;
node.pass--;
int index = 0;
for(int i=0;i<str.length;i++)
{
index = str[i]-'a';
node.nexts[index].pass--;
if(node.nexts[index].pass==0)
{
node.nexts[index]=null;
}
node = node.nexts[index];
}
node.end--;
}
}
2.贪心算法
比较器
//Program是自定义的类
public static class ProgramComparator implements Comparator<Program>{
public int compare(Program 01,proGram o2){
return o1.end-o2.end;
}
}
Arrays.sort(programs,new ProgramComparator());
a.compareto(b);//比较a、b的字典序
字符串组合 结果字典序最小的结果
a.b <= b.a的时候,a放在前面,b放后面
数据流中的中位数
//首先一个数,加入到大跟堆
再来一个数
如果<=大根堆堆顶,放到大根堆,否则放在小根堆,
然后比较大、小根堆元素个数差值==2,就弹出一个到另一个