
多叉树

p - pass 经过该结点的字符串个数
e - end 以该结点结束的字符串个数
比hash表强在可以查找前缀
hash表的增删改查是O(1),但是计算hash本身要遍历计算key的hash,所以时间代价是o(k),k是key的长度。
前缀树的添加代价是o(m),m是字符串的长度,查询代价是o(k),k是前缀的长度。
代码设计:
准备头结点(伪结点作为起点)
—
前缀树结点类型。
Node[] nexts; // 子结点。字符数量不多,可以用new Node[26]来表示a-z种结点类型。
int pass ;
int end
—
计数排序 — 桶排序
统计员工各年龄排序。(桶排序,不基于排序,年龄发到桶里,这里的桶是0 1 2 … 100 岁)。
桶排序的桶应该是有限。
基于比较排序 — O(NlogN)顶好,桶排序—-可能做到o(N)
计数排序(属于桶排序)
流程:
元素位数一致(若有负数,可以加一个正值,都不影响排序)
准备桶 : 根据个位数进桶,再按桶顺序到倒出桶; 再根据十位数进桶倒桶;。。。。最后倒出来 ,有序。 有点order by 样子。
桶的等价优化
count是各个桶的元素个数
count’是count的累计和,那么按照桶从右到左遍历元素时,都可以根据它的左边有多少个元素,以此决定它可以放在输出的数组的何处,当它安置后,它对应的桶的元素个数应该减一。
稳定性:同样值再排序之后相对次序不变。
用处:int\double等基础类型没用,再非基础类型中有用,比如购物时,先按价格升序,再按好评降序,结果就能找物美价廉的东西。
冒泡排序可以实现成稳定的 —- 相等时不交换
归并排序可以实现成稳定的 — 相等时先拷贝左边的
快排不是稳定的 - partition不是稳定的。
堆排序不是稳定的—改变

固定数组实现前缀树
设计Node结点,构建多叉树。
多叉树的头结点是伪结点,作为起始点。
相关查找的方法,都是基于 public Node startsWith_(String prefix){ }方法,其返回值是Node,通过Node可以查询pass和end变量。
class Node{// 本质是多叉树// 结点信息int pass=0; // 经过该结点的字符串数int end=0; // 以该结点结尾的字符串数Node[] nexts=new Node[26]; // 子结点索引}class Trie {Node root; // 伪头结点/** Initialize your data structure here. */public Trie() {root = new Node();}/** Inserts a word into the trie. */public void insert(String word) {if (word == null){return;}char[] arr = word.toCharArray();Node cur = root;for (int i=0; i < arr.length;i++){int idx = arr[i] - 'a';if (cur.nexts[idx] == null){cur.nexts[idx] = new Node();}cur = cur.nexts[idx];cur.pass++; // 到此一游}cur.end++; // 到此结束}/** Returns if the word is in the trie. */public boolean search(String word) {Node node = startsWith_(word);return node != null && node.end > 0;}/** Returns if there is any word in the trie that starts with the given prefix. */public boolean startsWith(String prefix) {Node node = startsWith_(prefix);return node != null && node.pass > 0;}// 前缀对应的最后结点,通过它可以知道pass和end信息。public Node startsWith_(String prefix){if (prefix == null){return null;}char[] arr = prefix.toCharArray();Node cur = root;for (int i=0;i < arr.length;i++){int idx = arr[i] - 'a';if (cur.nexts[idx] == null){return null;}cur = cur.nexts[idx];}return cur;}// -------------public void delete(String word){if (search(word)){char[] arr = word.toCharArray();Node cur = root;for (int i=0;i< arr.length;i++){int idx = arr[i] - 'a';if (--cur.nexts[idx].pass == 0){cur.nexts[idx] = null;return;}cur = cur.nexts[idx];}cur.end--;}}}/*** Your Trie object will be instantiated and called as such:* Trie obj = new Trie();* obj.insert(word);* boolean param_2 = obj.search(word);* boolean param_3 = obj.startsWith(prefix);*/
