接尾辞配列

WEB+DB Magazineを読んでいます。
書籍内記事にて言及されていた接尾辞配列の理解のため、記載されている動きをC#で組んでみました。
圧縮接尾辞配列は理解できていません…
(理解を目的としているのでString#SubStringを多用していたりArray#BinarySearchを使ってなかったりといった点はとりあえず置いてます)

using System;
using System.Collections.Generic;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main()
        {
            string text = @"
『はてなダイアリー』の容量は無制限だから、毎日たくさんブログを書いても全く問題なし! 
広告が勝手に表示されないので、思う存分デザインを楽しめます。
ブログの見た目を決めるデザインテーマは300以上。
自分のブログを本にすることも可能です。";

            string[] words = new string[] { 
                                    "はてな", 
                                    "容量", 
                                    "勝手に表示されない", 
                                    "30", 
                                    "ふがふが" };

            List<int>    suffixIndexList = MakeSAList(text);
            List<string> results = SearchWords(words, text, suffixIndexList);
            results.ForEach(Console.WriteLine);
            Pause();
        }

        static List<int> MakeSAList(string text)
        {
            List<int>  result = new List<int>();
            for (int i = 0; i < LastIndex(text); i++) result.Add(i);
            result.Sort(delegate(int x, int y) 
            {
                string xText = GetText(text, x);
                string yText = GetText(text, y);
                return xText.CompareTo(yText);
            });
            return result;
        }
        static List<string> SearchWords(string[] words, string text, List<int> suffixIndexList)
        {
            List<string> results = new List<string>();
            foreach (string word in words)
            {
                int i = Search(word, text, suffixIndexList, 0 , LastIndex(text));
                string result = (i > -1) ?
                                    string.Format("{0} : {1}〜", i, GetText(text, i).Substring(0, 5)) :
                                    "(NotFound!)";

                results.Add( string.Format("@ {0} : {1}", word, result));
            }
            return results;
        }
        static void Pause()
        {
            Console.ReadLine();
        }

        static int Search(string word, string text, List<int> suffixIndexList, int head, int tail)
        {
            if (head > tail) return -1;

            int pibot = (head + tail) / 2;
            string result = GetText(text, suffixIndexList[pibot]);

            if (result.StartsWith(word))
                return suffixIndexList[pibot];
            else if (word.CompareTo(result) < 0)
                return Search(word, text, suffixIndexList, head, pibot - 1);
            else
                return Search(word, text, suffixIndexList, pibot + 1, tail);
        }
        static string GetText(string text, int i)
        {
            return text.Substring(LastIndex(text) - i);
        }
        static int LastIndex(string text)
        {
            return text.Length - 1;
        }
    }
}

実行結果。

@ はてな : 121 : はてなダイ〜
@ 容量 : 111 : 容量は無制〜
@ 勝手に表示されない : 74 : 勝手に表示〜
@ 30 : 26 : 300以上〜
@ ふがふが : (NotFound!)