《算法》第六章部分程序 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 ...
随机推荐
- XE5 Android 开发数据访问手机端[转]
把供手机端调用的web服务完成,接下来实现手机端调用webservices获取数据 1.新建firemonkey mobile application 2.选择blank application 3. ...
- RGB颜色空间、HSV颜色空间的理解
HSV是把H(色相),S(饱和度),V(亮度)当做色值来定位颜色的空间. 1.HSV模型 色相:取值范围是0~360度,用来表示颜色的类别.其中红色是0度,绿色是120度,蓝色是240度.饱和度:取值 ...
- IIS7 UNC File caching issue
You have to either choose dir-monitoring and file-change-notification with its drawback of using SMB ...
- Ubuntu16.04 创建桌面快捷方式
一.基本概念 Linux 系统中的Desktop Entry 文件以desktop为后缀名.Desktop Entry 文件是 Linux 桌面系统中用于描述程序启动配置信息的文件. 进入/usr/s ...
- python之冒泡排序(一)
冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来. 遍历数列的工作是重复地进行直到没有再需要交换, ...
- spring4.0之五:@Conditional在满足特定条件下,才会实例化对象
这篇文章介绍Spring 4的@Conditional注解. 一.在Spring的早期版本你可以通过以下方法来处理条件问题 3.1之前的版本,使用Spring Expression Language( ...
- jQuery 闪动的文字提示
原文地址:http://www.cnblogs.com/kiter/archive/2013/02/22/2922242.html 声明,本文转自网络. jQuery 闪动的文字提示,仿QQ头像闪烁闪 ...
- HDOJ 2002 计算球体积
#include<cstdio> #define PI 3.1415927 int main() { double r; while (scanf_s("%lf", & ...
- 云端搭建内网局域网+NAT冗余上网:vps-centos6.10 +pptp client +2个ros 实现默认走pptp上网,万一pptp断了,走另外一个ros路由+centos7补充了下
介绍下环境: 1.ROS1也是PPTP SERVER,IP为172.16.22.3/24,pptp pool为172.16.23.0/24,pptp的默认帐号是111,密码是123 2.ROS2的IP ...
- [UE4]最简单的虚幻4网络游戏,使用虚幻4内置服务器
一.设置游戏窗口合适的大小 二.在新窗口中运行游戏.玩家数量改成大于1. 三.运行游戏就会打开多个窗口 在打包完成的游戏中进行网络游戏: 一.虚幻4打包好的文件是放在WindowsNoEditor ...