|
905 | 905 | 退出循环的条件:
|
906 | 906 | 1. 遍历的lo已经大于hi,可以退出循环,说明没有找到该元素。
|
907 | 907 | 2. 得到当前mid值已经和所查找的key相同,当前mid元素就是要查找的值。
|
| 908 | + |
| 909 | +4. 二叉查找树(BST): |
| 910 | + 二叉树由结点组成,结点包含的链接可以指向空或者其他结点。除了根节点以外,只能有一个父结点指向自己。 |
| 911 | + BST: |
| 912 | + ->每个结点都含有一个键,一个值,一条左链接,一条右链接和一个节点计数器。 |
| 913 | + ->左链接指向一棵由小于该节点的所有键组成的二叉查找树。 |
| 914 | + ->右链接指向一棵由大于该节点的所有键组成的二叉查找树。 |
| 915 | + ->size(x) = size(x.left) + size(x.right) + 1 |
| 916 | + ->***对于某一个结点,左边的结点小于父结点的值,右结点大于父结点的值,所以将所有的结点映射在一条线上,所有的数据是顺序排列的。 |
| 917 | + |
| 918 | + 二叉树的抽象类: |
| 919 | + 实现:ca.mcmaster.chapter.three.bitree.BinaryTreeSymbolTableAbstract<K, V> |
| 920 | + public abstract class BinaryTreeSymbolTableAbstract<K extends Comparable<K>, V> { |
| 921 | + protected class Node{ |
| 922 | + protected K k; |
| 923 | + protected V v; |
| 924 | + protected Node left, right; |
| 925 | + protected int N; |
| 926 | + public Node(K k, V v, int n) { |
| 927 | + this.k = k; this.v = v; N = n; |
| 928 | + } |
| 929 | + } |
| 930 | + protected Node root; |
| 931 | + public int size(Node x){ |
| 932 | + if(x == null) return 0; |
| 933 | + else return x.N; |
| 934 | + } |
| 935 | + public int size(){ return size(root); } |
| 936 | + public abstract V get(K k); |
| 937 | + public abstract void put(K k, V v); |
| 938 | + } |
| 939 | + Node是树上的某个结点,一个结点有如下的特征: |
| 940 | + ->K,键:用于确定该结点在树中的位置。 |
| 941 | + ->V,值:某个结点存储的值。 |
| 942 | + ->left, right:某个父结点所拥有的左子节点和右子结点。 |
| 943 | + ->N:当前节点(包括当前节点)的子结点的个数。 |
| 944 | + |
| 945 | + 实现:ca.mcmaster.chapter.three.bitree.BinaryTreeSymbolTable<K, V> |
| 946 | + public class BinaryTreeSymbolTable<K extends Comparable<K>, V> extends |
| 947 | + BinaryTreeSymbolTableAbstract<K, V> { |
| 948 | + public V get(K k) { return get(root, k); } |
| 949 | + public V get(Node node, K k){ //以当前结点为根结点,往下遍历子结点找到键值并返回对应的value |
| 950 | + if(node == null) return null; //对于每一次的结点遍历,只比较当前结点,左子结点,右子结点。 |
| 951 | + int cmp = k.compareTo(node.k); //比较键的大小,如果小于该键开始遍历左子结点,右子结点。 |
| 952 | + if(cmp > 0) return get(node.right, k); |
| 953 | + else if(cmp < 0) return get(node.left, k); |
| 954 | + else return node.v; |
| 955 | + } |
| 956 | + public void put(K k, V v) { |
| 957 | + root = put(root, k, v); |
| 958 | + } |
| 959 | + public Node put(Node node, K k, V v){ //将某一个键值对放入树中。 |
| 960 | + if(node == null) return new Node(k, v, 1); //如果已经遍历到了树的底部,创建一个新的结点并返回 |
| 961 | + int cmp = k.compareTo(node.k); |
| 962 | + if(cmp < 0) node.left = put(node.left, k, v); //如果键小于左边,将左子键当作父结点,递归调用。 |
| 963 | + else if(cmp > 0) node.right = put(node.right, k, v); //如果键小于右边,将右子键当作父结点,递归调用。 |
| 964 | + else node.v = v; |
| 965 | + node.N = size(node.left) + size(node.right) + 1; |
| 966 | + return node; |
| 967 | + } |
| 968 | + } |
| 969 | + |
908 | 970 |
|
909 | 971 |
|
910 | 972 |
|
|
913 | 975 |
|
914 | 976 |
|
915 | 977 |
|
| 978 | + |
| 979 | + |
| 980 | + |
| 981 | + |
| 982 | + |
| 983 | + |
| 984 | + |
| 985 | + |
| 986 | + |
| 987 | + |
| 988 | + |
| 989 | + |
| 990 | + |
| 991 | + |
916 | 992 |
|
917 | 993 |
|
918 | 994 |
|
|
0 commit comments