- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
#include <stdio.h>
#define XORSWAP(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
static int heap_size;
int parent(int i){
return i >> 1;
}
int left(int i){
return i << 1;
}
int right(int i){
return (i << 1) | 0x1;
}
void heapify(int *h, int i){
int l = left(i);
int r = right(i);
int largest;
if(l <= heap_size && h[l] > h[i])
largest = l;
else
largest = i;
if(r <= heap_size && h[r] > h[largest])
largest = r;
if(largest != i){
XORSWAP(h[i], h[largest]);
heapify(h, largest);
}
}
void make_heap(int *h, int len){
int i;
heap_size = len;
for(i = len/2; i >= 1; i--)
heapify(h, i);
}
int main(int argc, char *argv[]){
int i;
int h[11] = {0, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
make_heap(h, 11);
for(i = 1; i < 11; i++)
printf((i + 1 == 11) ? "%d" : "%d ", h[i]);
return 0;
}
laMer007 28.01.2016 21:59 # 0
bormand 28.01.2016 22:12 # +3
wvxvw 28.01.2016 23:34 # −1
Только вроде она должна быть с линейной сложностью, а тут что-то непонятное.
laMer007 29.01.2016 07:09 # +1
wvxvw 29.01.2016 13:42 # 0
Но похоже что у ОПа все нормально. Т.е. это только кажется что сложность выше.
bormand 28.01.2016 22:37 # +2
> XORSWAP
Нинужно. Делай нормальный свап в виде функции и не выябывайся знанием макросов и битовой магии.
> heap_size
Почему у тебя размер массива в глобалке? Передай его параметром.
> l <= heap_size
> for(i = 1; i < 11; i++)
Это залёт... за границу массива. В си массивы с нуля. Ну и все parent/child и .тп. у тебя тоже написаны для массивов с единицы.
> for(i = len/2; i >= 1; i--)
Деление пополам там точно нужно? Я не уверен, но вроде надо было все ноды окучивать.
P.S. Лабы на ГК не постят.
laMer007 28.01.2016 23:19 # 0
bormand 28.01.2016 23:20 # +1
HiewMorjowie 29.01.2016 00:16 # 0
И тогда не получится сделать хиккерскую магию здесь: return (i << 1) | 0x1;
У Кормена индексы тоже с единицы для общности, а у Левитина они с единицы сознательно, хотя все его псевдокоды заточены под си. Нулевой элемент не используется.
И да, это не лаба. Посоветуйте, где можно посмотреть профессиональную реализацию структур в реальных проектах. Гуглится одно только лабное говно с убогим, негибким интерфейсом.
bormand 29.01.2016 00:20 # 0
Ну окей, окей, уговорил. Только один хер за границу вылетаешь. Нету в этом массиве 11-го элемента.
HiewMorjowie 29.01.2016 00:22 # 0
bormand 29.01.2016 00:25 # 0
И навсегда забыть о тредах (можно в тредлокал засунуть, но это тот ещё костыль).
> либо передавать как параметр
Либо положить и указатель и длину в структуру и таскать их всегда вместе.
laMer007 29.01.2016 07:13 # 0
Ты ему так очень тонко предлагаешь уйти в С++ же?
j123123 29.01.2016 08:23 # +3
bormand 29.01.2016 17:56 # 0
bormand 29.01.2016 00:28 # +1
Ну не сделаешь ты на чистой сишке гибкий интерфейс. Смирись. Не знаю, что именно ты хочешь гибкого. Но если функцию, работающую с произвольными типами - то в итоге всё выльется в void* обёрнутый в какое-нибудь макроговно, или в memcpy или во вложенную структуру и container_of.
bormand 29.01.2016 00:31 # 0
А что это? :) Ну ок, проект для самообучения основам алгоритмов и проектирования. По сути та же лаба, только сдаёшь себе вместо препода.
HiewMorjowie 29.01.2016 00:34 # 0
Везде говорят, что иногда требуется писать структуры данных с нуля типа расширений красно-черных деревьев для нахождения порядковых статистик. На деле написать их не так сложно, как сделать их пригодными для использования.
bormand 29.01.2016 00:46 # 0
- состояние твоего контейнера загоняешь в структуру
- указатель на структуру передаешь во все "методы"
- ...
- профит
laMer007 29.01.2016 07:17 # 0
> Куча
> Профессиональная структура данных
/0
Обычно от неё толку, что с козла - молока. Оно вроде и есть, но никто его не пьет.
bormand 29.01.2016 17:56 # 0
laMer007 30.01.2016 12:15 # 0
И почему среди алгоритмов кучи, нет реализации для кучи как структуры данных на основе дерева через линки поинтеров, должно быстрее вставляться в такую кучу
bormand 30.01.2016 12:52 # +2
Для прикладных целей есть std::priority_queue. Зачем тебе нужна голая куча как контейнер? А если heap sort на её основе мутить - контейнер вместо алгоритма вообще палки в колёса будет вставлять.
> на основе дерева
Да ну... Памяти жрёт больше, хуёво кешируется, дрочит аллокатор на каждый чих (последние 2 пункта вроде как пофиксятся кастомным аллокатором)... Ну и скатывание элемента один фиг будет править кучу линков по дороге. Так что если элементы мелкие - можно и в проигрыше остаться.
laMer007 30.01.2016 13:52 # 0
bormand 30.01.2016 14:19 # 0
Проблемы начнутся при вытаскивании же, не при впихивании. У тебя в корне самый большой элемент, ты его выдираешь. Соотв. надо на его место скатить одного из потомков и т.п. Или я туплю?
roman-kashitsyn 26.02.2016 18:21 # 0
Use std::multiset, Luke.
nihau 29.01.2016 12:41 # 0
nihau 29.01.2016 12:37 # 0
Бля, вот я понимаю вашу(си\плюсовиков) любовь к макросам. Но почему тогда либо не все вынести в макросы, либо чуть более по-человечески в функции?
guest 30.01.2016 15:03 # 0
bormand 30.01.2016 15:17 # 0
guest 26.02.2016 17:42 # 0
bormand 26.02.2016 18:22 # 0