Python三元搜索算法

时间:2015-07-12 17:42:50

标签: python algorithm search time-complexity ternary-search-tree

我正在尝试编写三元搜索算法函数,该函数使用整数和值的排序列表。它类似于二分搜索,除了通过选择两个索引ind1和ind2(ind1< ind2)将搜索区域在每次迭代中划分为三个较小的区域(长度尽可能相等):

•区域1包含索引值小于ind1

的所有项目

•区域2包含索引值大于ind1但小于ind2

的所有项目

•区域3包含索引值大于ind2的所有项目

如果可能,这些区域的大小应相等。如果不可能,那么区域1的大小必须大于或等于区域2的大小,区域2的大小必须大于或等于区域3的大小。任何两个区域的大小可能最多只有一个。

我想要遵循的格式是:

如果搜索区域的大小是< = 4

执行v

的线性搜索

否则

如果L [ind1]等于v

,则选择索引ind1和ind2

停止,我们发现如果v< L [IND1]

如果L [ind2]等于v

,则

重复,区域1是新的搜索区域

停止,我们发现如果v< L [IND2]

重复,区域2是新的搜索区域

重复,区域3是新的搜索区域

~~~~~

在搜索列表时,我还需要在算法检查时生成步骤。

~~~~~

例如:

ternary_search([6,12,18,22,29,37,38,41,51,53,55,67,73,75,77,81,8 6,88,94],88)应该打印:

检查88是否等于38

检查88是否小于38

检查88是否等于75

检查88是否小于75

检查88是否等于81

检查88是否小于81

检查88是否等于88

搜索成功

88位于指数17

共进行了7次比较

~~~~~ 我写的代码是:

    `def ternary_search (L, key):
        left = 0
        right = len(L) - 1
        while left <= right:
           ind1 = left
           ind2 = left + (right - left) // 3
           ind3 = left + 2 * (right - left) // 3
           n = 0

           if key == L[left]:
              n += 1
              print("Checking if " + str(key) + " is equal to " + str(left))
              print("Search successful")
              print(str(key) + " is located at index " + str(left))
              print("A total of " + str(n) + " comparisons were made")
              return

           elif key == L[right]:
              n += 1
              print("Checking if " + str(key) + " is equal to " + str(right))
              print("Search successful")
              print(str(key) + " is located at index " + str(right))
              print("A total of " + str(n) + " comparisons were made")
              return

           elif key < L[left] or key > L[right]:
              n += 1
              print("Search not successful")
              print("A total of " + str(n) + " comparisons were made")
              return

           elif key <= L[ind2]:
              n += 1
              print("Checking if " + str(key) + " is less than " + str(L[ind2]))
              right = ind2 -1

           elif key > L[ind2] and key <= L[ind3]:
              n += 1
              print("Checking if " + str(key) + " is less than " + str(L[ind2]))
              print("Checking if " + str(key) + " is equal to " + str(L[ind3]))
              print("Checking if " + str(key) + " is less than " + str(L[ind3]))         
              left = ind2 + 1
              right = ind3

           else:
              n += 1
              print("Checking if " + str(key) + " is less than " + str(L[ind3]))         
              left = ind3 + 1

        return`

我打电话的时候: ternary_search([6,12,18,22,29,37,38,41,51,53,55,67,73,75,77,81,86,88,94], 51)

打印:

Checking if 51 is less than 38 Checking if 51 is equal to 73 Checking if 51 is less than 73 Checking if 51 is less than 51 Search not successful A total of 1 comparisons were made

什么时候打印:

Checking if 51 is equal to 38 Checking if 51 is less than 38 Checking if 51 is equal to 75 Checking if 51 is less than 75 Checking if 51 is equal to 53 Checking if 51 is less than 53 Checking if 51 is equal to 41 Checking if 51 is equal to 51 Search successful 51 is located at index 8 A total of 8 comparisons were made

1 个答案:

答案 0 :(得分:1)

是的,您说得对,上面的代码有很多问题。我发现的一些不正确的事情是:

  1. 列表的长度应该大于最右边的元素。
  2. 在你的情况下,最左边的范围总是从0开始。
  3. 许多不必要的elif条件,但我认为这仅用于打印。
  4. 代码应该与二进制搜索非常相似。下面简单介绍一下你所描述的内容。 (编辑:修复了代码中的一些错误:前一个错误并不完全是三元搜索。)

    def ternary_search (L, key):
       left = 0
       right = len(L) - 1
       while left <= right:
          ind1 = left
          ind2 = left + (right - left) // 3
          ind3 = left + 2 * (right - left) // 3
          if key == L[left]:
             print("Key found at:" + str(left))
             return
          elif key == L[right]:
             print("Key found at:", str(right))
             return
          elif key < L[left] or key > L[right]:
             print("Unable to find key")
             return
          elif key <= L[ind2]:
             right = ind2
          elif key > L[ind2] and key <= L[ind3]:
             left = ind2 + 1
             right = ind3
          else:
             left = ind3 + 1
       return
    

    测试:

    ternary_search([6,12,18,22,29,37,38,41,51,53,55,67,73,75,77,81,86,88,94],88)
    ('Key found at:', '17')
    

    请注意,可以证明二进制搜索在所有n元搜索中的比较方面是最佳的。