青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 42  文章 - 3  trackbacks - 0
<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用鏈接

留言簿(2)

隨筆檔案

文章檔案

網頁收藏

搜索

  •  

最新評論

閱讀排行榜

評論排行榜


The original post is
http://igoro.com/archive/efficient-auto-complete-with-a-ternary-search-tree/

Over the past couple of years, auto-complete has popped up all over the web. Facebook, YouTube, Google, Bing, MSDN, LinkedIn and lots of other websites all try to complete your phrase as soon as you start typing.

Auto-complete definitely makes for a nice user experience, but it can be a challenge to implement efficiently. In many cases, an efficient implementation requires the use of interesting algorithms and data structures. In this blog post, I will describe one simple data structure that can be used to implement auto-complete: a ternary search tree.

Trie: simple but space-inefficient

Before discussing ternary search trees, let’s take a look at a simple data structure that supports a fast auto-complete lookup but needs too much memory: a trie. A trie is a tree-like data structure in which each node contains an array of pointers, one pointer for each character in the alphabet. Starting at the root node, we can trace a word by following pointers corresponding to the letters in the target word.

Each node could be implemented like this in C#:

class TrieNode
{
public const int ALPHABET_SIZE = 26;
public TrieNode[] m_pointers = new TrieNode[ALPHABET_SIZE];
public bool m_endsString = false;
}

Here is a trie that stores words AB, ABBA, ABCD, and BCD. Nodes that terminate words are marked yellow:

 

gif_1

 

Implementing auto complete using a trie is easy. We simply trace pointers to get to a node that represents the string the user entered. By exploring the trie from that node down, we can enumerate all strings that complete user’s input.

But, a trie has a major problem that you can see in the diagram above. The diagram only fits on the page because the trie only supports four letters {A,B,C,D}. If we needed to support all 26 English letters, each node would have to store 26 pointers. And, if we need to support international characters, punctuation, or distinguish between lowercase and uppercase characters, the memory usage grows becomes untenable.

Our problem has to do with the memory taken up by all the null pointers stored in the node arrays. We could consider using a different data structure in each node, such as a hash map. However, managing thousands and thousands of hash maps is generally not a good idea, so let’s take a look at a better solution.

Ternary search tree to the rescue

A ternary tree is a data structure that solves the memory problem of tries in a more clever way. To avoid the memory occupied by unnecessary pointers, each trie node is represented as a tree-within-a-tree rather than as an array. Each non-null pointer in the trie node gets its own node in a ternary search tree.

For example, the trie from the example above would be represented in the following way as a ternary search tree:

image

The ternary search tree contains three types of arrows. First, there are arrows that correspond to arrows in the corresponding trie, shown as dashed down-arrows. Traversing a down-arrow corresponds to “matching” the character from which the arrow starts. The left- and right- arrow are traversed when the current character does not match the desired character at the current position. We take the left-arrow if the character we are looking for is alphabetically before the character in the current node, and the right-arrow in the opposite case.

For example, green arrows show how we’d confirm that the ternary tree contains string ABBA:

 image

And this is how we’d find that the ternary string does not contain string ABD:

image 

Ternary search tree on a server

On the web, a significant chunk of the auto-complete work has to be done by the server. Often, the set of possible completions is large, so it is usually not a good idea to download all of it to the client. Instead, the ternary tree is stored on the server, and the client will send prefix queries to the server.

The client will send a query for words starting with “bin” to the server:

  image

And the server responds with a list of possible words:

image 

Implementation

Here is a simple ternary search tree implementation in C#:

public class TernaryTree
{
private Node m_root = null;
private void Add(string s, int pos, ref Node node)
{
if (node == null) { node = new Node(s[pos], false); }
if (s[pos] < node.m_char) { Add(s, pos, ref node.m_left); }
else if (s[pos] > node.m_char) { Add(s, pos, ref node.m_right); }
else
{
if (pos + 1 == s.Length) { node.m_wordEnd = true; }
else { Add(s, pos + 1, ref node.m_center); }
}
}
public void Add(string s)
{
if (s == null || s == "") throw new ArgumentException();
Add(s, 0, ref m_root);
}
public bool Contains(string s)
{
if (s == null || s == "") throw new ArgumentException();
int pos = 0;
Node node = m_root;
while (node != null)
{
int cmp = s[pos] - node.m_char;
if (s[pos] < node.m_char) { node = node.m_left; }
else if (s[pos] > node.m_char) { node = node.m_right; }
else
{
if (++pos == s.Length) return node.m_wordEnd;
node = node.m_center;
}
}
return false;
}
}

And here is the Node class:

class Node
{
internal char m_char;
internal Node m_left, m_center, m_right;
internal bool m_wordEnd;
public Node(char ch, bool wordEnd)
{
m_char = ch;
m_wordEnd = wordEnd;
}
}

Remarks

For best performance, strings should be inserted into the ternary tree in a random order. In particular, do not insert strings in the alphabetical order. Each mini-tree that corresponds to a single trie node would degenerate into a linked list, significantly increasing the cost of lookups. Of course, more complex self-balancing ternary trees can be implemented as well.

And, don’t use a fancier data structure than you have to. If you only have a relatively small set of candidate words (say on the order of hundreds) a brute-force search should be fast enough.

Further reading

Another article on tries is available on DDJ (careful, their implementation assumes that no word is a prefix of another):

http://www.ddj.com/windows/184410528

If you like this article, also check out these posts on my blog:


posted on 2012-06-25 23:26 鷹擊長空 閱讀(484) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品一区二区三区不卡牛牛| 亚洲国产精品成人综合色在线婷婷| 最新日韩在线| 好吊色欧美一区二区三区四区| 欧美一区二区| 午夜精品电影| 久久久欧美精品| 欧美黄在线观看| 国产精品久久久久久久久久三级| 午夜电影亚洲| 免费亚洲电影在线观看| 欧美激情中文不卡| 最新国产拍偷乱拍精品| 亚洲精品一区中文| 亚洲午夜羞羞片| 久久精品麻豆| 欧美日韩麻豆| 国语自产精品视频在线看8查询8| 欧美大香线蕉线伊人久久国产精品| 亚洲精品日韩激情在线电影| 亚洲美女在线观看| 欧美在线视频a| 欧美精品在线观看91| 国产精品美女久久久浪潮软件| 久久人91精品久久久久久不卡| 99www免费人成精品| 欧美一区2区视频在线观看 | 欧美成人第一页| 欧美丝袜一区二区| 国产视频不卡| 一本久久精品一区二区| 欧美综合国产| 日韩亚洲不卡在线| 久久中文字幕导航| 国产精品亚洲综合| 99re亚洲国产精品| 六月婷婷一区| 午夜电影亚洲| 国产精品久久久久久久久久久久久久 | 久久久久久电影| 欧美婷婷久久| 经典三级久久| 欧美中文在线观看国产| 亚洲欧洲一区| 久久九九全国免费精品观看| 欧美日韩一区三区四区| 亚洲国产精品一区二区尤物区| 国产精品日韩在线一区| 亚洲毛片在线免费观看| 免费看黄裸体一级大秀欧美| 在线亚洲精品| 欧美三区在线视频| 日韩小视频在线观看专区| 欧美黄色大片网站| 美女国产一区| 亚洲人成网站999久久久综合| 亚洲黑丝在线| 欧美与黑人午夜性猛交久久久| 欧美中文字幕精品| 亚洲系列中文字幕| 国产精品久久久久毛片软件| 亚洲自拍啪啪| 亚洲一区在线免费| 亚洲精品一区二区三区樱花| 久久在线91| 久久久久免费视频| 国产一级揄自揄精品视频| 欧美淫片网站| 久久成人精品电影| 一区免费观看视频| 亚洲第一黄网| 欧美日韩精品欧美日韩精品一| 欧美视频二区| 一区二区福利| 一本色道久久88综合亚洲精品ⅰ| 亚洲系列中文字幕| 国产精品每日更新| 久久久久久午夜| 麻豆国产精品777777在线| 在线精品视频在线观看高清| 欧美国产免费| 欧美日韩一区二区在线观看 | 欧美午夜不卡| 一本色道久久综合狠狠躁篇怎么玩 | 午夜亚洲一区| 久久久99爱| av成人国产| 亚洲欧美另类国产| 亚洲国产另类久久精品| 亚洲国产综合91精品麻豆| 欧美精品www| 久久精品男女| 欧美日韩八区| 久久久国产精品一区二区三区| 亚洲激情一区| 国产精品美女主播在线观看纯欲| 在线观看欧美一区| 亚洲日韩欧美视频一区| 欧美视频福利| 免费欧美在线视频| 国产精品视频内| 亚洲国产老妈| 韩国欧美国产1区| 99国产精品久久久| 国模精品娜娜一二三区| 亚洲毛片av在线| 精品动漫3d一区二区三区免费版| 亚洲欧美视频| 两个人的视频www国产精品| 亚洲一区尤物| 欧美高清视频在线 | 国产欧美视频一区二区| 欧美在线欧美在线| 欧美电影在线免费观看网站 | 欧美a级一区二区| 欧美三级在线播放| 欧美成黄导航| 国产欧美一区二区三区在线看蜜臀| 亚洲美洲欧洲综合国产一区| 亚洲欧美不卡| 亚洲视频碰碰| 欧美精品福利| 欧美黑人多人双交| 一区二区亚洲精品| 亚洲欧美在线另类| 亚洲欧美高清| 国产精品高潮视频| 日韩一级裸体免费视频| 亚洲美女区一区| 欧美不卡一卡二卡免费版| 欧美成人免费全部| 亚洲第一福利在线观看| 久久精品免费播放| 久久综合综合久久综合| 一区在线视频观看| 久久男女视频| 欧美国产日韩一区二区| 亚洲国产欧洲综合997久久| 久久亚洲捆绑美女| 欧美成人午夜剧场免费观看| 在线欧美日韩精品| 免费在线观看精品| 久久天天狠狠| 亚洲国产精品福利| 欧美丰满高潮xxxx喷水动漫| 欧美黑人多人双交| 一区二区三区产品免费精品久久75| 亚洲精品视频中文字幕| 亚洲精品一区二区三区在线观看| 亚洲国产精品123| 亚洲国产成人久久| 欧美激情一区二区三区成人| 亚洲国产精品综合| 亚洲一二三区精品| 国产精品欧美一区喷水| 性伦欧美刺激片在线观看| 久久久亚洲一区| 亚洲国产高清在线| 欧美精品一区在线播放| 亚洲一区二区三区在线看| 久久午夜国产精品| 亚洲欧洲日产国码二区| 欧美日韩在线直播| 欧美一区二区在线视频| 亚洲电影毛片| 亚洲在线电影| 在线电影国产精品| 欧美日韩中文另类| 久久精品国亚洲| 亚洲美女精品一区| 久久久久久久精| 99视频超级精品| 国产日韩欧美麻豆| 欧美韩国日本综合| 欧美在线视频免费| 亚洲高清不卡在线| 欧美一区二区高清| 亚洲黄色天堂| 国产色综合久久| 欧美日韩国产123区| 久久精品一区二区三区四区| 日韩午夜黄色| 欧美成人在线网站| 欧美一级夜夜爽| 一区二区三欧美| 麻豆国产精品777777在线| 韩国视频理论视频久久| 欧美日韩亚洲在线| 久久精品日韩| 中文在线不卡| 亚洲黄色视屏| 免费成人高清| 欧美在线视频观看免费网站| 一区二区三区av| 亚洲卡通欧美制服中文| 国产一区二区三区在线观看精品 | 亚洲国产女人aaa毛片在线| 中文亚洲免费| 亚洲黄色尤物视频| 国内揄拍国内精品久久|