▶ 书中第六章部分程序,包括在加上自己补充的代码,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的更多相关文章

  1. 《算法》第六章部分程序 part 7

    ▶ 书中第六章部分程序,加上自己补充的代码,包括全局最小切分 Stoer-Wagner 算法,最小权值二分图匹配 ● 全局最小切分 Stoer-Wagner 算法 package package01; ...

  2. 《算法》第六章部分程序 part 6

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...

  3. 《算法》第六章部分程序 part 5

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,网络最大流 Ford - Fulkerson 算法,以及用到的流量边类和剩余流量网络类 ● 网络最大流 Ford - Fulkerson 算法 pac ...

  4. 《算法》第六章部分程序 part 8

    ▶ 书中第六章部分程序,加上自己补充的代码,包括单纯形法求解线性规划问题 ● 单纯形法求解线性规划问题 // 表上作业法,I 为单位阵,y 为对偶变量,z 为目标函数值 // n m 1 // ┌── ...

  5. 《算法》第六章部分程序 part 4

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,利用后缀树查找最长重复子串.查找最大重复子串并输出其上下文(Key word in context,KWIC).求两字符串的最长公共子串 ● 利用后缀 ...

  6. 《算法》第六章部分程序 part 3

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,后缀树的两种实现 ● 后缀树实现一 package package01; import java.util.Arrays; import edu.pr ...

  7. 《算法》第六章部分程序 part 1

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,粒子碰撞系统及用到的粒子类 ● 粒子系统 package package01; import java.awt.Color; import edu.p ...

  8. 《算法》第一章部分程序 part 1

    ▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法 ● 代码,二分搜索 package package01; import java.util.Arrays; ...

  9. 《算法》第二章部分程序 part 5

    ▶ 书中第二章部分程序,加上自己补充的代码,包括利用优先队列进行多路归并和堆排序 ● 利用优先队列进行多路归并 package package01; import edu.princeton.cs.a ...

随机推荐

  1. servet概述

    1定义 Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 使用 Servl ...

  2. plsql 创建表空间、用户、赋予权限

    plsql 创建表空间.用户.赋予权限 --用户名:testuser --密码:bzhs!*6 --1.创建表空间--用SYSTEM用户登陆数据库,执行下面语句创建表空间CREATE TABLESPA ...

  3. Oracle 字符集更改

    sqlplus sys/player as sysdba SQL*Plus: Release 11.2.0.1.0 Production shutdown immediate; startup mou ...

  4. GitHub版本控制入门(新手学习)

    要使用GitHub功能,首先要登陆官方网站https://github.com,注册GitHub账号. 在浏览器中的操作: 新建一个仓库.一个项目一旦被Git控制了版本历史,在GitHub上就有另外一 ...

  5. linux开机出现一下错误Give root password for maintenance (or type Control-D to continue):

    由于错误的编辑/etc/fstab文件 而引起的不能正常进入系统.假如你将某一个分区或者磁盘最后一个参数设置为1或2时,系统默认会在开机过程中检查这个磁盘的扇区.假如系统检查不到这个磁盘,或者这个磁盘 ...

  6. ALGO-143_蓝桥杯_算法训练_字符串变换

    问题描述 相信经过这个学期的编程训练,大家对于字符串的操作已经掌握的相当熟练了.今天,徐老师想测试一下大家对于字符串操作的掌握情况.徐老师自己定义了1,,,,5这5个参数分别指代不同的5种字符串操作, ...

  7. Flume的Source

    source学习网址: http://flume.apache.org/FlumeUserGuide.html 一.Avro 类型的Source 监听Avro 端口来接收外部avro客户端的事件流.和 ...

  8. json--处理框架

    1.Android 中的Json解析工具fastjson .序列化.反序列化 2.Android Gson的使用总结 可以处理含有内部类的类,或包含集合内部类的类: 3.Android-JSONToo ...

  9. VMware虚拟机上配置nginx后,本机无法访问问题(转载)

    转自:http://www.server110.com/nginx/201407/10794.html 把nginx装在CentOS上,用本机访问虚拟机的时候却出现了不能访问的问题,查了资料以后,原来 ...

  10. man iptables 8

    IPTABLES(8) iptables 1.6.0 IPTABLES(8) NAME iptables/ip6tables — administration tool for IPv4/IPv6 p ...