Индексно-последовательный поиск

Индексно-последовательный поиск

Индексно-последовательный поиск предполагает, что в дополнение к отсортированной таблице ключей заводится вспомогательная таблица, называемая индексной.

Каждый элемент индексной таблицы состоит из ключа и указателя на запись в основной таблице, соответствующей этому ключу. Элементы в индексной таблице, как и элементы в основной таблице, должны быть отсортированы по этому ключу.

Если индекс имеет размер, составляющий 1/5 от размера основной таблицы, то каждая пятая запись основной таблицы будет представлена в индексной таблице. Шаг формирования индексной таблицы может быть задан в каждой конкретной реализации.

Если размер основной таблицы — n, то размер индексной таблицы — ind_size = n/step, где step — шаг формирования индексной таблицы.

Достоинство алгоритма индексно-последовательного поиска заключается в том, что сокращается время поиска, так как последовательный поиск первоначально ведется в индексной таблице, имеющей меньший размер, чем основная таблица. Когда найден правильный индекс, второй последовательный поиск выполняется по небольшой части записей основной таблицы.

Реализация индексно-последовательного поиска на языке Си
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define _CRT_SECURE_NO_WARNINGS // для корректной работы scanf() в Visual Studio
#include <stdio.h>
#include <stdlib.h> // для использования функций system()
int main()
{
  // массив ключей основной таблицы
  int k[] = {  8,  14,  26,  38,  72, 115, 206, 221, 
         229, 307, 318, 389, 411, 413, 473, 504, 518}; 
  const int size = sizeof(k) / sizeof(int); // размер массива ключей
  const int step = 5;  // шаг индексной таблицы
  int r[size]; // массив записей основной таблицы
  const int ind_size = size/step+1;
  int key, j;
  int kindex[ind_size]; // массив ключей индексной таблицы
  int pindex[ind_size]; // массив индексов индексной таблицы
  system("chcp 1251"); // перевод русского языка в консоли
  system("cls");     // очистка окна консоли
  // Ввод записей
  for (int i = 0; i < size; i++)
  {
    printf("k[%2d]=%3d: r[%2d]= ", i, k[i], i);
    scanf("%d", &r[i]);
  }
  // Формирование индексной таблицы
  for (int i = 0, j = 0; i < size; i = i + step, j++)
  {
    kindex[j] = k[i]; // переносим каждый step-ключ в индексную таблицу
    pindex[j] = i;    // запоминаем текущий индекс
  }
  printf("Индексная таблица:\n");
  for (int i = 0; i < ind_size; i++)
  {
    printf("p[%2d]=%3d: индекс %3d\n", i, kindex[i], pindex[i]);
  }
  // Поиск
  printf("Введите k: "); // вводим ключевое поле
  scanf("%d", &key);
  // Просматриваем элементы индексной таблицы
  int beg, end;  // начало и конец диапазона поиска
  for (j = 0; j < ind_size; j++)
  {
    if (key < kindex[j]) // если находим ключ меньше введенного,
    {
      break;           // выходим из цикла - мы нашли нужную область основной таблицы
    }
  }
  int flag = 0;
  if (j > 0)     // если находимся в середине индексной таблицы
    beg = pindex[j - 1];
  else           // если находимся до начального элемента индексной таблицы
    beg = 0;
  if (j == ind_size)  // если дошли до конца таблицы
    end = size;      // ищем до последнего элемента основной таблицы
  else                              
    end = pindex[j]; // иначе ищем до следующего индекса
  for (int i = beg; i < end; i++)   // осуществляем поиск в основной таблице
  {
    if (k[i] == key)  // если найдено введенное значение, выводим его
    {
      printf("Найдена запись %2d: k=%3d, r=%3d\n", i, k[i], r[i]);
      flag = 1;
    }
  }
  if (flag == 0)
  {
    printf("Запись не найдена!\n");
  }
  system("pause");
  return 0;
}

Результат выполнения

3 комментария к “Индексно-последовательный поиск”

  1. Эффективность индексно-последовательного поиска O(корень квадратный из n)
    Количество сравнений — корень квадратный из n + 1

  2. Дмитрий

    Отличный коммент выше, при сложности N + n/N, получается что бинарный поиск сильно лучше
    При n=10000, для бинарного log2(n) = 13, а для N + n/N = 100 + 10000/100 = 200

  3. Максимальная вычислительная сложность, или количество сравнений, равно
    N + n/N, где N — размер индексной таблицы,
    n — общее количество элементов.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх