Многое зависит от количества IP-адресов, которые вы, вероятно, будете иметь в своей таблице.
Для небольшого числа сбалансированное двоичное дерево (например, дерево AVL) должно работать достаточно хорошо. Он требует значительных накладных расходов (2 указателя на узел), но, пока количество узлов невелико, это, вероятно, не является большой проблемой (если вы не ориентируетесь на систему с ограниченной памятью). Вы также можете использовать гибрид, где один узел хранит до N IP-адресов в массиве. При полуобращенном выборе N это может снизить затраты на указатель и улучшить использование кэша.
Если у вас больше 10 КБ или около того, возможно, стоит подумать об использовании три.
Если у вас может быть действительно большое число, вы можете рассмотреть возможность использования простого набора битов, один бит на IP-адрес.
Редактировать: я должен добавить, что это также может зависеть от частоты вставок / удалений по сравнению с поиском. Одна гибридная структура, которую я нашел полезной в многих ситуациях, состоит в том, чтобы начать с отсортированного основного массива, а затем при добавлении элементов хранить их в отдельном массиве, который не отсортирован. Когда / если вторичный массив становится слишком большим, вы сортируете его и объединяете с основным массивом.