《算法》第六章部分程序 part 2
▶ 书中第六章部分程序,包括在加上自己补充的代码,B-树
● B-树
package package01; import edu.princeton.cs.algs4.StdOut; public class class01<Key extends Comparable<Key>, Value>
{
private static final int M = 4; // 子节点数量为 M-1 private Node root; // 根节点
private int height; // 树高
private int n; // 键值对的数量 private static final class Node // 节点类
{
private int m; // 当前子节点数量
private Entry[] children = new Entry[M]; // 子节点列表 private Node(int k) // 构造有 k 个子节点的节点
{
m = k;
}
} private static class Entry // 子节点列表类,内部结点使用 key 和 next,外部节点使用 key 和 value
{
private Comparable key;
private Node next;
private final Object val; public Entry(Comparable inputKey, Object inputVal, Node inputNext)
{
key = inputKey;
next = inputNext;
val = inputVal;
}
} public class01()
{
root = new Node(0);
} public int size()
{
return n;
} public boolean isEmpty()
{
return size() == 0;
} public int height()
{
return height;
} public Value get(Key key)
{
if (key == null)
throw new IllegalArgumentException("\n<get> key == null.\n");
return search(root, key, height);
} private Value search(Node x, Key key, int ht) // 穿如数奉告,每次进入更深层时减一
{
Entry[] children = x.children;
if (ht == 0) // 到达的是叶节点,遍历列表
{
for (int j = 0; j < x.m; j++)
{
if (eq(key, children[j].key)) // 找到了,返回 val
return (Value)children[j].val;
}
}
else // 到达的是内部节点
{
for (int j = 0; j < x.m; j++)
{
if (j == x.m - 1 || less(key, children[j + 1].key)) // j 到达最后或找到合适的子节点,进入下一层
return search(children[j].next, key, ht - 1);
}
}
return null;
} public void put(Key key, Value val)
{
if (key == null)
throw new IllegalArgumentException("\n<put> key == null.\n");
Node u = insert(root, key, val, height); // 执行插入插座并调整总键值对数量
n++;
if (u == null) // 没有需要调整的节点
return;
Node t = new Node(2); // 根节点需要分裂,新建一个具有 2 个子节点的节点
t.children[0] = new Entry(root.children[0].key, null, root); // 第一个子节点是原来的根节点
t.children[1] = new Entry(u.children[0].key, null, u); // 第二个子节点是插入操作导致新增加的节点
root = t; // root 编程新建的 t,并增加一层树高
height++;
} private Node insert(Node h, Key key, Value val, int ht)
{
int j;
Entry t = new Entry(key, val, null);
if (ht == 0) // 到达的是外部节点
{
for (j = 0; j < h.m; j++)
{
if (less(key, h.children[j].key)) // 找到合适的位置就脱出循环
break;
}
}
else // 到达的是内部节点
{
for (j = 0; j < h.m; j++)
{
if ((j + 1 == h.m) || less(key, h.children[j + 1].key)) // j 到达最后或找到合适的子节点,进入下一层
{
Node u = insert(h.children[j++].next, key, val, ht - 1);// 在 h.children[j] 进行插入
if (u == null)
return null;
t.key = u.children[0].key; // 把 u 的信息改造到 t 上
t.next = u; // 真正 next 是在这里赋值的,指向下一个子节点
break;
}
}
}
for (int i = h.m; i > j; i--) // 调整本层,排在插入位置之后的元素都向后移动一格
h.children[i] = h.children[i - 1];
h.children[j] = t; // 插入节点 t,增加 h 的子节点数量
h.m++;
return (h.m < M) ? null : split(h); // 节点 h 满了就需要扩容,返回扩容后多出来的节点,用于上一层调整
} private Node split(Node h) // 分裂节点 h,并返回分裂出来的后一半节点
{
Node t = new Node(M / 2);
h.m = M / 2; // 改 h 的子节点数为一半,相当于废弃后一半记录
for (int j = 0; j < M / 2; j++) // 后一半元素搬进 t
t.children[j] = h.children[M / 2 + j];
return t;
} public String toString()
{
return toStringKernel(root, height, "") + "\n";
} private String toStringKernel(Node h, int ht, String indent) // 遍历树转化为字符串
{
StringBuilder s = new StringBuilder();
Entry[] children = h.children;
if (ht == 0) // 叶节点,输出
{
for (int j = 0; j < h.m; j++)
s.append(indent + children[j].key + " " + children[j].val + "\n"); // 注意换行
}
else // 非叶节点,遍历子节点列表
{
for (int j = 0; j < h.m; j++)
{
if (j > 0)
s.append(indent + "(" + children[j].key + ")\n");
s.append(toStringKernel(children[j].next, ht - 1, indent + " "));
}
}
return s.toString();
} private boolean less(Comparable k1, Comparable k2)
{
return k1.compareTo(k2) < 0;
} private boolean eq(Comparable k1, Comparable k2)
{
return k1.compareTo(k2) == 0;
} public static void main(String[] args) // 输入一堆网站和 IP 建立 B-树
{
class01<String, String> st = new class01<String, String>(); st.put("www.cs.princeton.edu", "128.112.136.12");
st.put("www.cs.princeton.edu", "128.112.136.11");
st.put("www.princeton.edu", "128.112.128.15");
st.put("www.yale.edu", "130.132.143.21");
st.put("www.simpsons.com", "209.052.165.60");
st.put("www.apple.com", "17.112.152.32");
st.put("www.amazon.com", "207.171.182.16");
st.put("www.ebay.com", "66.135.192.87");
st.put("www.cnn.com", "64.236.16.20");
st.put("www.google.com", "216.239.41.99");
st.put("www.nytimes.com", "199.239.136.200");
st.put("www.microsoft.com", "207.126.99.140");
st.put("www.dell.com", "143.166.224.230");
st.put("www.slashdot.org", "66.35.250.151");
st.put("www.espn.com", "199.181.135.201");
st.put("www.weather.com", "63.111.66.11");
st.put("www.yahoo.com", "216.109.118.65"); StdOut.println("cs.princeton.edu: " + st.get("www.cs.princeton.edu"));
StdOut.println("hardvardsucks.com: " + st.get("www.harvardsucks.com"));
StdOut.println("simpsons.com: " + st.get("www.simpsons.com"));
StdOut.println("apple.com: " + st.get("www.apple.com"));
StdOut.println("ebay.com: " + st.get("www.ebay.com"));
StdOut.println("dell.com: " + st.get("www.dell.com"));
StdOut.println(); StdOut.println("size: " + st.size());
StdOut.println("height: " + st.height());
StdOut.println(st);
StdOut.println();
}
}
● 测试函输出,即生成的树
cs.princeton.edu: 128.112.136.12
hardvardsucks.com: null
simpsons.com: 209.052.165.60
apple.com: 17.112.152.32
ebay.com: 66.135.192.87
dell.com: 143.166.224.230 size: 17
height: 2
www.amazon.com 207.171.182.16
www.apple.com 17.112.152.32
www.cnn.com 64.236.16.20
(www.cs.princeton.edu)
www.cs.princeton.edu 128.112.136.12
www.cs.princeton.edu 128.112.136.11
www.dell.com 143.166.224.230
(www.ebay.com)
www.ebay.com 66.135.192.87
www.espn.com 199.181.135.201
www.google.com 216.239.41.99
(www.microsoft.com)
www.microsoft.com 207.126.99.140
www.nytimes.com 199.239.136.200
(www.princeton.edu)
www.princeton.edu 128.112.128.15
www.simpsons.com 209.052.165.60
(www.slashdot.org)
www.slashdot.org 66.35.250.151
www.weather.com 63.111.66.11
(www.yahoo.com)
www.yahoo.com 216.109.118.65
www.yale.edu 130.132.143.21
《算法》第六章部分程序 part 2的更多相关文章
- 《算法》第六章部分程序 part 7
▶ 书中第六章部分程序,加上自己补充的代码,包括全局最小切分 Stoer-Wagner 算法,最小权值二分图匹配 ● 全局最小切分 Stoer-Wagner 算法 package package01; ...
- 《算法》第六章部分程序 part 6
▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...
- 《算法》第六章部分程序 part 5
▶ 书中第六章部分程序,包括在加上自己补充的代码,网络最大流 Ford - Fulkerson 算法,以及用到的流量边类和剩余流量网络类 ● 网络最大流 Ford - Fulkerson 算法 pac ...
- 《算法》第六章部分程序 part 8
▶ 书中第六章部分程序,加上自己补充的代码,包括单纯形法求解线性规划问题 ● 单纯形法求解线性规划问题 // 表上作业法,I 为单位阵,y 为对偶变量,z 为目标函数值 // n m 1 // ┌── ...
- 《算法》第六章部分程序 part 4
▶ 书中第六章部分程序,包括在加上自己补充的代码,利用后缀树查找最长重复子串.查找最大重复子串并输出其上下文(Key word in context,KWIC).求两字符串的最长公共子串 ● 利用后缀 ...
- 《算法》第六章部分程序 part 3
▶ 书中第六章部分程序,包括在加上自己补充的代码,后缀树的两种实现 ● 后缀树实现一 package package01; import java.util.Arrays; import edu.pr ...
- 《算法》第六章部分程序 part 1
▶ 书中第六章部分程序,包括在加上自己补充的代码,粒子碰撞系统及用到的粒子类 ● 粒子系统 package package01; import java.awt.Color; import edu.p ...
- 《算法》第一章部分程序 part 1
▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...
- 《算法》第二章部分程序 part 5
▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...
随机推荐
- bzoj5019: [Snoi2017]遗失的答案
Description 小皮球在计算出答案之后,买了一堆皮肤,他心里很开心,但是一不小心,就忘记自己买了哪些皮肤了.==|||万 幸的是,他还记得他把所有皮肤按照1-N来编号,他买来的那些皮肤的编号( ...
- C#应用jstree实现无限级节点的方法
下载jstree.js下载地址: http://jstree.com/ 当前下载版本: jsTree 3.3.1 第一步:下载完成后引用js+css <link href="~/plu ...
- 廖雪峰Java2面向对象编程-1面向对象-1面向对象基础
1.对象的概念 面向对象编程:Object-Oriented Programming 对现实世界建立计算机模型的一种编程方法. 现实世界 计算机模型 Java代码 人 类/class class Pe ...
- openstack云主机硬盘复制查询
假定客户在自己的电脑上创建文件后 #宿主机查看客户使用的是哪个磁盘 [root@compute1 ~]# lvs LV VG Attr LSize Pool Origin Data% Meta ...
- GO中DEFER的理解--DEFER执行的原理
在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是return之后添加一个函数调用.因此,defer通常用来释放函数内 ...
- IP地址基础
第一台计算机的名字 1946年2月14日,世界上第一台电脑ENIAC在美国宾夕法尼亚大学诞生,名叫ENIAC(爱尼阿克). 第一个网络的名字: arpanet 计算机网络定义: 物理位置不同.功能 ...
- echarts折现图配置
js引用和div容器 <div id="container" style="height: 100%"></div> <scrip ...
- Centos7.3安装部署Zabbix3.4.15(成功可用)
1.Xshell 远程连接到Centos7.3.连接centos 系统后,首先关闭防火墙和SELINUX,如不关闭会各种拦截,网页访问等故障,容易造成蛋疼哦.#systemctl stop firew ...
- IDEA远程调试
问题: 通常在java打成可运行的Jar项目时,运行jar时调试很不方便,特别是要在linux上面执行jar包的情况.此时需要将这个项目打成Jar包(如果是maven项目,直接使用pa ...
- mysql 取整数或小数或精确位数
select cast(3.1415926 as decimal(9,2))精确到几位 select round(1024.5); 四舍五入 select floor(1024.5);取整数部分 se ...