Упорядоченное множество — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
м (Наивная реализация на массиве)
(successor)
(не показаны 43 промежуточные версии 4 участников)
Строка 4: Строка 4:
  
 
== Операции над упорядоченным множеством ==
 
== Операции над упорядоченным множеством ==
Над упорядоченным множеством <tex>Set</tex> заданы следующие операции:
+
Над упорядоченным множеством <tex>set</tex> заданы следующие операции:
* <tex>\mathrm {insert(Set, elem, key)}</tex> {{---}} добавляет заданный элемент <tex>elem</tex>, имеющий ключ <tex>key</tex>, в подходящее место множества <tex>Set</tex> (сохраняя свойство упорядоченности),
+
* <tex>\mathrm {insert(set, elem)}</tex> {{---}} добавляет заданный элемент <tex>elem</tex> в подходящее место множества <tex>set</tex> (сохраняя свойство упорядоченности),
* <tex>\mathrm {delete(Set, key)}</tex> {{---}} удаляет элемент, имеющий ключ <tex>key</tex> (сохраняя свойство упорядоченности),
+
* <tex>\mathrm {delete(set, elem)}</tex> {{---}} удаляет элемент <tex>elem</tex> (сохраняя свойство упорядоченности),
* <tex>\mathrm {search(Set, key)}</tex> {{---}} получает на вход искомый ключ <tex>key</tex> и возвращает указатель на элемент множества <tex>Set</tex> или специальное значение <tex>null</tex>, если такого элемента нет,
+
* <tex>\mathrm {search(set, elem)}</tex> {{---}} получает на вход искомое значение элемента <tex>elem</tex> и возвращает <tex>true</tex> при наличии элемента в множестве или <tex>false</tex> в противном случае,
* <tex>\mathrm {minimum(Set)}</tex> {{---}} возвращает указатель на минимальный элемент множества <tex>Set</tex>,
+
* <tex>\mathrm {minimum(set)}</tex> {{---}} возвращает минимальный элемент множества <tex>set</tex>,
* <tex>\mathrm {maximum(Set)}</tex> {{---}} возвращает указатель на максимальный элемент множества <tex>Set</tex>,
+
* <tex>\mathrm {maximum(set)}</tex> {{---}} возвращает максимальный элемент множества <tex>set</tex>,
* <tex>\mathrm {predecessor(Set, elem)}</tex> {{---}} возвращает указатель на элемент, стоящий перед элементом <tex>elem</tex> множества <tex>Set</tex>.
+
* <tex>\mathrm {predecessor(set, elem)}</tex> {{---}} возвращает элемент, стоящий перед элементом <tex>elem</tex> множества <tex>set</tex>.
* <tex>\mathrm {successor(Set, elem)}</tex> {{---}} возвращает указатель на элемент, стоящий после элемента <tex>elem</tex> множества <tex>Set</tex>.
+
* <tex>\mathrm {successor(set, elem)}</tex> {{---}} возвращает элемент, стоящий после элемента <tex>elem</tex> множества <tex>set</tex>.
  
 
== Наивная реализация на массиве ==
 
== Наивная реализация на массиве ==
Упорядоченное множество <tex>Set</tex>, содержащее <tex>n</tex> элементов, можно реализовать с помощью массива <tex>elements[0..n-1]</tex>. Оно будет обладать следующими полями:
+
Упорядоченное множество <tex>s</tex>, содержащее <tex>n</tex> элементов, можно реализовать с помощью [[Сортировки | отсортированного]] массива <tex>elements[0..n-1]</tex>.
* <tex>elem</tex> {{---}} элемент множества,
+
 
* <tex>key</tex> {{---}} ключ элемента.
+
Рассмотрим реализацию на примере отсортированного по возрастанию целочисленного массива.
  
 
<code>
 
<code>
  '''struct''' Set<T>
+
  '''struct''' Set<T>:
 
   '''int''' n                            <font color=green>// количество элементов множества</font color=green>
 
   '''int''' n                            <font color=green>// количество элементов множества</font color=green>
   '''T'''[] elements                     <font color=green>// массив элементов множества типа T</font color=green>
+
   '''T'''[n] elements                   <font color=green>// массив элементов множества типа ''T''</font color=green>
 
</code>
 
</code>
  
 
=== '''insert''' ===
 
=== '''insert''' ===
 
<code>
 
<code>
  '''func''' insert(Set, elem, key):
+
  '''func''' insert(Set<T> s, T elem):
     Set.n = Set.n + 1                     <font color=green>//Увеличиваем размер массива на единицу</font color=green>
+
     s.n = s.n + 1                                   <font color=green>// Увеличиваем количество элементов множества на единицу,</font color=green>
     Set.elements[key] = elem             <font color=green>//и добавляем элемент с ключом key.</font color=green>
+
                                                      <font color=green>// увеличиваем размер массива с элементами множества на единицу.</font color=green>
 +
     s.elements[s.n - 1] = elem                       <font color=green>// Вставляем ''elem'' в конец массива</font color=green>
 +
    '''int''' i = s.n - 1
 +
    '''while''' s.elements[i] < s.elements[i - 1]          <font color=green>// Сортируем массив,</font color=green>
 +
        swap(s.elements[i], s.elements[i - 1])      <font color=green>// пока ''elem'' не окажется в нужном месте.</font color=green>
 
</code>
 
</code>
Время выполнения {{---}} <tex>O(1)</tex>.
+
Время выполнения {{---}} <tex>O(n)</tex>.
  
 
=== '''delete''' ===
 
=== '''delete''' ===
 
<code>
 
<code>
  '''func''' delete(Set, key):
+
  '''func''' delete(Set<T> s, T elem):
     '''if''' key < Set.n - 1                                <font color=green>//Если key {{---}} не последний элемент,</font color=green>
+
    '''int''' i = 0                                        <font color=green>// Устанавливаем счетчик на первый элемент.</font color=green>
         '''for''' i = key '''to''' Set.n - 2                     <font color=green>//то сдвигаем все элементы множества, начиная с key, влево.</font color=green>
+
    '''while''' i < s.n '''and''' s.elements[i] != elem          <font color=green>// Ищем индекс элемента ''elem''.</font color=green>
             Set.elements[i] = Set.elements[i + 1]
+
        i++
         Set.n = Set.n - 1                             <font color=green>//Затем удаляем последний элемент (уменьшаем количество элементов множества на единицу).</font color=green>
+
     '''if''' i != s.n                                       <font color=green>// Если элемент найден, то</font color=green>
 +
         '''for''' j = i '''to''' s.n - 2                         <font color=green>// сдвигаем все элементы массива, большие ''elem'',</font color=green>
 +
             s.elements[j] = s.elements[j + 1]         <font color=green>// на одну позицию влево (elem удаляется).</font color=green>
 +
         s.n = s.n - 1                                 <font color=green>// Уменьшаем число элементов массива на единицу.</font color=green>
 
</code>
 
</code>
 
Время выполнения {{---}} <tex>O(n)</tex>.
 
Время выполнения {{---}} <tex>O(n)</tex>.
  
 +
=== '''search''' ===
 +
Для нахождения результата используем [[Целочисленный двоичный поиск|бинарный поиск]].
  
=== '''search''' ===
 
 
<code>
 
<code>
  '''T''' search(Set, key):
+
  '''bool''' search(Set<T> s, T elem):
     '''for''' i = 0 '''to''' Set.n - 1
+
     '''int''' i = binSearch(s.elements, elem)
        '''if''' i == key                                <font color=green>//Если элемент с ключом key существует, возвращаем указатель на него,</font color=green>
+
    '''return''' s.elements[i] == elem                        <font color=green>// Сравниваем найденное значение с искомым...</font color=green>
            '''return''' *(Set.elements + key)
 
    '''return''' ''null''                                    <font color=green>//в противном случае возвращаем ''null''.</font color=green>
 
 
</code>
 
</code>
Время выполнения {{---}} <tex>O(n)</tex>.
+
Время выполнения {{---}} <tex>O(\log n)</tex>.
  
 +
=== '''minimum''' ===
 +
Первый элемент множества минимальный, так как массив отсортирован по возрастанию.
  
=== '''minimum''' ===
 
 
<code>
 
<code>
  '''T''' minimum(Set):
+
  '''T''' minimum(Set<T> s):
     '''T''' min = Set.elements[0]               <font color=green>//Принимаем первый элемент множества за минимальный.</font color=green>
+
     '''T''' min = s.elements[0]
     '''int''' res = 0
+
     '''return''' min
    '''for''' i = 1 '''to''' Set.n - 1
 
        '''if''' min > Set.elements[i]          <font color=green>//Если есть элементы меньше min,</font color=green>
 
            min = Set.elements[i]        <font color=green>//то записывает элемент в min</font color=green>
 
            res = i                      <font color=green>//и его ключ в res.</font color=green>
 
    '''return''' *(Set.elements + key)
 
 
</code>
 
</code>
Время выполнения {{---}} <tex>O(n)</tex>.
+
Время выполнения {{---}} <tex>O(1)</tex>.
 
 
  
 
=== '''maximum''' ===
 
=== '''maximum''' ===
<code>
+
Выполняется аналогично операции <tex>\mathrm {minimum(set)}</tex>.
'''T''' maximum(Set):
 
    '''T''' max = Set.elements[0]              <font color=green>//Принимаем первый элемент множества за максимальный.</font color=green>
 
    '''int''' res = 0
 
    '''for''' i = 1 '''to''' Set.n - 1
 
        '''if''' max < Set.elements[i]          <font color=green>//Если есть элементы больше max,</font color=green>
 
            max = Set.elements[i]        <font color=green>//то записывает элемент в max</font color=green>
 
            res = i                      <font color=green>//и его ключ в res.</font color=green>
 
    '''return''' *(Set.elements + key)
 
</code>
 
Время выполнения {{---}} <tex>O(n)</tex>.
 
 
 
  
=== '''predecessor''' ===
 
 
<code>
 
<code>
  '''T''' predecessor(Set, elem):
+
  '''T''' maximum(Set<T> s):
     '''for''' i = 1 '''to''' Set.n - 1
+
     '''T''' max = s.elements[s.n - 1]
        '''if''' elem == Set.elements[i]
+
     '''return''' max
            '''return''' *(Set.elements + i - 1)
 
     '''return''' ''null''
 
 
</code>
 
</code>
Время выполнения {{---}} <tex>O(n)</tex>.
+
Время выполнения {{---}} <tex>O(1)</tex>.
  
 +
=== '''successor''' ===
 +
В операции используется [[Целочисленный двоичный поиск|правосторонний бинарный поиск]], который вернет такое <tex>i</tex>, что <tex> s.elements[i - 1]\leqslant elem < s.elements[i] </tex>.
  
=== '''successor''' ===
 
 
<code>
 
<code>
  '''T''' successor(Set, elem):
+
  '''T''' successor(Set<T> s, T elem):
     '''for''' i = 0 '''to''' Set.n - 2
+
     '''if''' elem > s.elements[s.n - 1]                            <font color=green>// Если элемент больше максимального,</font color=green>
        '''if''' elem == Set.elements[i]
+
        '''return''' ''null''                                         <font color=green>// возвращаем ''null''.</font color=green>
            '''return''' *(Set.elements + i + 1)
+
    '''else if''' elem < s.elements[0]
    '''return''' ''null''
+
        '''return''' min(s)                                        <font color=green>// Если элемент меньше минимального, возвращаем минимальный элемент.</font color=green>
 +
    '''int''' i = binSearch(s.elements, elem)                     <font color=green>// Иначе ищем элемент, больший ''elem''.</font color=green>
 +
    '''return''' s.elements[i]
 
</code>
 
</code>
Время выполнения {{---}} <tex>O(n)</tex>.
+
Время выполнения {{---}} <tex>O(\log n)</tex>. Операция <tex>\mathrm{predecessor}</tex> выполняется аналогичным образом.
  
 
+
== Замечания ==
В случае, когда упорядоченность элементов коллекции не важна, возможно использование [[Хеш-таблица|''хешей'']].
+
* В случае, когда упорядоченность элементов коллекции не важна, возможно использование [[Хеш-таблица|''хешей'']].
  
 
== Примеры ==  
 
== Примеры ==  
* Простые приверы множеств:
+
* Пустое множество <tex>  \varnothing </tex>,
** {1, 2, 3, ...},
 
** {..., 3, 2, 1},
 
** {1, 3, 5, ..., 2, 4, 6, ...},
 
** {1, 3, 5, ..., 6, 4, 2},
 
** {..., 5, 3, 1, 2, 4, 6, ...},
 
** {..., 5, 3, 1, ..., 6, 4, 2},
 
* пустое множество <tex>  \varnothing </tex>,
 
 
* множество натуральных чисел <tex>  \mathbb N </tex>,
 
* множество натуральных чисел <tex>  \mathbb N </tex>,
* файлы в директории, отсортированные в алфавитном порядке.
+
* множество целых чисел  <tex>  \mathbb Z </tex>,
 +
* строки, отсортированные в [[лексикографический порядок|лексикографическом порядке]].
  
 
== Источники информации ==
 
== Источники информации ==
Строка 122: Строка 106:
 
* Александров П. С. Введение в теорию множеств и общую топологию. — М.: Наука, 1977. — 368 с.
 
* Александров П. С. Введение в теорию множеств и общую топологию. — М.: Наука, 1977. — 368 с.
 
* Н. К. Верещагин, А. Шень. Часть 1. Начала теории множеств // Лекции по математической логике и теории алгоритмов. — 2-е изд., испр. — М.: МЦНМО, 2002. — 128 с.
 
* Н. К. Верещагин, А. Шень. Часть 1. Начала теории множеств // Лекции по математической логике и теории алгоритмов. — 2-е изд., испр. — М.: МЦНМО, 2002. — 128 с.
 
+
* [http://ru.wikipedia.org/wiki/Упорядоченное_множество Википедия — Упорядоченное множество]
== Ссылки ==
 
* [http://ru.wikipedia.org/wiki/Упорядоченное_множество Упорядоченное множество — Википедия]
 
  
 
[[Категория: Дискретная математика и алгоритмы]]
 
[[Категория: Дискретная математика и алгоритмы]]
 
[[Категория:Деревья поиска]]
 
[[Категория:Деревья поиска]]
 
[[Категория: Структуры данных]]
 
[[Категория: Структуры данных]]

Версия 00:57, 1 июля 2015

Упорядоченное множество (англ. ordered set) представляет собой коллекцию элементов, каждому из которых присваивается определенный ключ, отвечающий за порядок этого элемента в множестве. Бинарное отношение на упорядоченном множестве является отношением порядка.

Вполне упорядоченным множеством, которое явяется важнейшим частным случаем, называется упорядоченное множество, каждое непустое подмножество которого содержит минимальный элемент.

Операции над упорядоченным множеством

Над упорядоченным множеством [math]set[/math] заданы следующие операции:

  • [math]\mathrm {insert(set, elem)}[/math] — добавляет заданный элемент [math]elem[/math] в подходящее место множества [math]set[/math] (сохраняя свойство упорядоченности),
  • [math]\mathrm {delete(set, elem)}[/math] — удаляет элемент [math]elem[/math] (сохраняя свойство упорядоченности),
  • [math]\mathrm {search(set, elem)}[/math] — получает на вход искомое значение элемента [math]elem[/math] и возвращает [math]true[/math] при наличии элемента в множестве или [math]false[/math] в противном случае,
  • [math]\mathrm {minimum(set)}[/math] — возвращает минимальный элемент множества [math]set[/math],
  • [math]\mathrm {maximum(set)}[/math] — возвращает максимальный элемент множества [math]set[/math],
  • [math]\mathrm {predecessor(set, elem)}[/math] — возвращает элемент, стоящий перед элементом [math]elem[/math] множества [math]set[/math].
  • [math]\mathrm {successor(set, elem)}[/math] — возвращает элемент, стоящий после элемента [math]elem[/math] множества [math]set[/math].

Наивная реализация на массиве

Упорядоченное множество [math]s[/math], содержащее [math]n[/math] элементов, можно реализовать с помощью отсортированного массива [math]elements[0..n-1][/math].

Рассмотрим реализацию на примере отсортированного по возрастанию целочисленного массива.

struct Set<T>:
  int n                            // количество элементов множества
  T[n] elements                    // массив элементов множества типа T

insert

func insert(Set<T> s, T elem):
    s.n = s.n + 1                                    // Увеличиваем количество элементов множества на единицу,
                                                     // увеличиваем размер массива с элементами множества на единицу.
    s.elements[s.n - 1] = elem                       // Вставляем elem в конец массива
    int i = s.n - 1
    while s.elements[i] < s.elements[i - 1]          // Сортируем массив,
        swap(s.elements[i], s.elements[i - 1])       // пока elem не окажется в нужном месте.

Время выполнения — [math]O(n)[/math].

delete

func delete(Set<T> s, T elem):
    int i = 0                                         // Устанавливаем счетчик на первый элемент.
    while i < s.n and s.elements[i] != elem           // Ищем индекс элемента elem.
        i++
    if i != s.n                                       // Если элемент найден, то
        for j = i to s.n - 2                          // сдвигаем все элементы массива, большие elem,
            s.elements[j] = s.elements[j + 1]         // на одну позицию влево (elem удаляется).
        s.n = s.n - 1                                 // Уменьшаем число элементов массива на единицу.

Время выполнения — [math]O(n)[/math].

search

Для нахождения результата используем бинарный поиск.

bool search(Set<T> s, T elem):
    int i = binSearch(s.elements, elem)
    return s.elements[i] == elem                         // Сравниваем найденное значение с искомым...

Время выполнения — [math]O(\log n)[/math].

minimum

Первый элемент множества минимальный, так как массив отсортирован по возрастанию.

T minimum(Set<T> s):
    T min = s.elements[0]
    return min

Время выполнения — [math]O(1)[/math].

maximum

Выполняется аналогично операции [math]\mathrm {minimum(set)}[/math].

T maximum(Set<T> s):
    T max = s.elements[s.n - 1]
    return max

Время выполнения — [math]O(1)[/math].

successor

В операции используется правосторонний бинарный поиск, который вернет такое [math]i[/math], что [math] s.elements[i - 1]\leqslant elem \lt s.elements[i] [/math].

T successor(Set<T> s, T elem):
    if elem > s.elements[s.n - 1]                            // Если элемент больше максимального,
        return null                                          // возвращаем null.
    else if elem < s.elements[0]
        return min(s)                                        // Если элемент меньше минимального, возвращаем минимальный элемент.
    int i = binSearch(s.elements, elem)                      // Иначе ищем элемент, больший elem.
    return s.elements[i]

Время выполнения — [math]O(\log n)[/math]. Операция [math]\mathrm{predecessor}[/math] выполняется аналогичным образом.

Замечания

  • В случае, когда упорядоченность элементов коллекции не важна, возможно использование хешей.

Примеры

  • Пустое множество [math] \varnothing [/math],
  • множество натуральных чисел [math] \mathbb N [/math],
  • множество целых чисел [math] \mathbb Z [/math],
  • строки, отсортированные в лексикографическом порядке.

Источники информации

  • Кормен, Т., Лейзерсон, Ч., Ривест, Р., Алгоритмы: построение и анализ = Introduction to Algorithms / — 1-е изд. — Пер. с англ под ред. А. Шеня. — М.: МЦНМО, 2002.—960 с. — ISBN 5-900916-37-5
  • Александров П. С. Введение в теорию множеств и общую топологию. — М.: Наука, 1977. — 368 с.
  • Н. К. Верещагин, А. Шень. Часть 1. Начала теории множеств // Лекции по математической логике и теории алгоритмов. — 2-е изд., испр. — М.: МЦНМО, 2002. — 128 с.
  • Википедия — Упорядоченное множество