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

隨筆 - 42  文章 - 3  trackbacks - 0
<2011年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用鏈接

留言簿(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>
            久久人人97超碰人人澡爱香蕉| 久久―日本道色综合久久| 欧美日韩国产色综合一二三四 | 在线不卡a资源高清| 欧美性猛交视频| 欧美午夜精品久久久久久孕妇| 久久久久久一区二区| 久久综合激情| 免费久久精品视频| 久久久久久久激情视频| 99国产精品视频免费观看| 国产自产2019最新不卡| 国产精品视频99| 你懂的网址国产 欧美| 久久精品91久久久久久再现| 欧美在线日韩| 亚洲欧美网站| 久久精品一区二区三区不卡牛牛| 久久精品午夜| 亚洲综合首页| 欧美成va人片在线观看| 欧美喷潮久久久xxxxx| 国产精品免费观看视频| 一区二区三区四区精品| 亚洲一区二区三区在线视频| 免费成人av| 亚洲另类自拍| 欧美激情视频一区二区三区不卡| 亚洲精品视频二区| 欧美激情第9页| 久久久午夜电影| 亚洲欧美国产77777| 国产欧美一区二区精品秋霞影院| 久久久久一区二区三区四区| 亚洲三级免费电影| 一区二区三区产品免费精品久久75 | 欧美成年人网| 国产精品久久久久久久久果冻传媒 | 午夜精品一区二区三区在线| 久久精品视频亚洲| 欧美高清在线| 欧美中日韩免费视频| 看欧美日韩国产| 国产欧美在线观看| 亚洲精品美女久久7777777| 欧美亚洲日本一区| 日韩性生活视频| 久久精品亚洲一区二区三区浴池| 国产精品无码专区在线观看| 欧美激情1区2区3区| 99精品免费| 欧美1区2区| 久久精品国产999大香线蕉| 亚洲欧洲中文日韩久久av乱码| 国产精品素人视频| 亚洲在线免费| 在线观看免费视频综合| 亚洲精品欧美| 欧美极品在线视频| 欧美高清一区| 在线视频日本亚洲性| 最新高清无码专区| 亚洲一区二区免费视频| 亚洲欧美国产另类| 亚洲人体1000| 欧美午夜宅男影院| 日韩一级黄色片| 欧美本精品男人aⅴ天堂| 在线视频欧美一区| 欧美亚韩一区| 夜夜嗨av一区二区三区中文字幕 | 亚洲深夜福利网站| 美日韩精品免费| 亚洲区中文字幕| 免费美女久久99| 欧美一级片在线播放| 国产一区日韩一区| 久久精品91久久香蕉加勒比| 久久高清国产| 国产一区二区三区丝袜 | 久久综合电影一区| 亚洲精品影视| 亚洲精品国产精品国自产在线 | 亚洲视频一二区| 亚洲九九精品| 快播亚洲色图| 亚洲一区二区高清| 亚洲久色影视| 久久久蜜桃一区二区人| 亚洲国产精品v| 亚洲国产成人av在线| 欧美三级视频在线播放| 亚洲网站视频| 欧美激情第1页| 欧美国产日本在线| 亚洲午夜久久久| 亚洲美女色禁图| 欧美性色综合| 久久亚洲视频| 欧美一级电影久久| 在线观看日韩| 99riav国产精品| 欧美理论电影在线观看| 亚洲国产日韩欧美在线99 | 国产综合色精品一区二区三区| 99热这里只有精品8| 国产精品成人一区| 亚洲性xxxx| 久久国产精品久久久久久| 欧美啪啪一区| 久久国产婷婷国产香蕉| 亚洲精品国产精品国自产在线| 亚洲国产综合在线| 国产精品美女视频网站| 亚洲女人天堂成人av在线| 久久激情综合| 亚洲欧洲视频在线| 欧美视频在线观看| 欧美一区三区二区在线观看| 玖玖精品视频| 亚洲直播在线一区| 国产精品视区| 久久午夜激情| 亚洲一区二区三区精品在线 | 久久婷婷国产综合国色天香| 亚洲伊人一本大道中文字幕| 亚洲图片激情小说| 伊人影院久久| 欧美日韩国语| 欧美大香线蕉线伊人久久国产精品| 亚洲欧洲一区二区三区| 久久视频免费观看| 亚洲在线一区| 亚洲激情黄色| 亚洲第一狼人社区| 国内精品久久久久久久果冻传媒| 欧美日韩和欧美的一区二区| 久久精品国产亚洲高清剧情介绍| 99精品视频网| 亚洲午夜性刺激影院| 麻豆精品精华液| 久久精品国产精品亚洲| 午夜久久久久| 久久激情一区| 久久久久久久久久久久久女国产乱 | 在线观看国产成人av片| 国产精品美女一区二区在线观看| 欧美婷婷在线| 欧美日韩在线第一页| 玖玖国产精品视频| 欧美人成在线| 欧美日韩亚洲一区二| 国产精品日韩久久久| 欧美日韩免费观看一区| 欧美日韩美女| 国产亚洲午夜| 亚洲精品一区二区三区av| 午夜电影亚洲| 亚洲春色另类小说| 在线一区亚洲| 欧美激情国产日韩| 免费不卡在线观看| 欧美一区二区三区精品电影| 亚洲视频欧洲视频| 亚洲欧美视频| 欧美日韩在线视频观看| 国模吧视频一区| av成人免费在线观看| 午夜精品电影| 亚洲精品美女在线观看| 久久国产精品久久精品国产| 欧美日韩一区国产| 在线看不卡av| 久久免费精品日本久久中文字幕| 亚洲精品一区二区三区福利| 久久在精品线影院精品国产| 欧美日韩免费网站| 欧美视频一区在线| 国产精品a久久久久| 一区二区三区国产盗摄| 久久亚洲综合色| 久久久精品国产免大香伊| 国产精品系列在线播放| 亚洲性感美女99在线| 亚洲视频专区在线| 国产日韩欧美中文在线播放| 亚洲天堂av在线免费观看| 日韩午夜在线电影| 欧美午夜无遮挡| 免费久久99精品国产| 久久久国产精品一区二区三区| 国产一区在线视频| 亚洲电影激情视频网站| 欧美午夜片在线免费观看| 篠田优中文在线播放第一区| 在线视频欧美精品| 亚洲电影第三页| 一区二区三区视频观看| 激情综合视频| 在线视频中文亚洲|