int _tmain(int argc, _TCHAR* argv[]) { binaryNode_t *p; int arr[100] = {4, 10, 3, 5, 1, 9, 9, 9, 1000, 2, 7, 0}; int n = 12; // n nodes int last[100]; int m = 0; int i; int temp; for (i = n / 2 - 1; i >= 0; i--) { // create heap heapfy(arr, n, i); } temp = arr[0]; arr[0] = arr[n - 1]; arr[n - 1] = temp; for (i = n - 1; i > 0; i--) { heapfy(arr, i, 0); temp = arr[0]; arr[0] = arr[i - 1]; arr[i - 1] = temp; } return 0; }
// n nodes with root 'root' void heapfy(int arr[], int n, int root) { int maxIndex; int left; int right; int temp; if (root > n / 2 - 1) { return; } left = 2 * root + 1; right = 2 * root + 2; if (right <= n - 1) { // range maxIndex = (arr[left] >= arr[right]) ? left : right; // max index } else { maxIndex = left; } if (arr[root] < arr[maxIndex]) { temp = arr[root]; arr[root] = arr[maxIndex]; arr[maxIndex] = temp; heapfy(arr, n, maxIndex); } }
void pop(){ pos[heap[1].second] = -1; neltos--; if(neltos == 0)return; pos[heap[neltos+1].second] = 1; heap[1] = heap[neltos+1]; heapfy(1); }
/* BUILD HEAP * * Running time: O(n). Because it iterates over n/2 nodes and calls HEAPFY for * each of them, we are attempted to say that it's an O(n * log(n)) algorithm. * However, mathematical proof shows that this bound can be tighter to O(n). * It's jut a matter of summations and getting a better bound. * * The underlying idea is to call HEAPFY for all internal nodes. */ void build(int *a, int n) { heap_size = length = n; a[0] = -1; // sentinel n >>= 1; // only iterate over non-leaves until reach the root while(n >= 1) { heapfy(a, n); n--; } }
void gerarHeap( int *array, int tamanho ) { int i; for ( i = tamanho / 2; i >= 1; i-- ) { heapfy( array, i, tamanho ); } }
void ordenarHeapSort( int *array, int tamanho ) { int i; for ( i = tamanho; i >= 2; i-- ) { swap( &array[1], &array[i] ); heapfy( array, 1, i - 1 ); } }
/* Heap Sort * * Like INSERTION SORT, it's a in-place sorting algorithm * Like MERGE SORT, it's a linear-logarithmic sorting O(n * log(n)) * * Unlike the mentioned algorithms, HEAP SORT uses a DATA STRUCTURE to manage * information (the HEAP). * * The underlying idea of HEAP SORT is organizing a list of keys in a MAX-HEAP, * then we exchange the ROOT with A[heap_size]. After that is just a matter of * excluding the last element and calling HEAPFY to the root. */ void heapsort(int *a, int n) { build(a, n); int i = 1; while (i <= heap_size) { int tmp = a[heap_size]; a[heap_size] = a[i]; a[i] = tmp; // this HAVE to be decreased before calling HEAPFY and AFTER swapping // the values. What would happen if we decrease after calling HEAPFY? heap_size--; heapfy(a, i); } }
/* HEAPFY (max-heap) * * Running time: O(log(n)) * * Responsible to maintain the HEAP PROPERTY. * Assumes the children of i obeys the heap property but it's not guaranteed * that i is in the right place. * * "floats" down the improper element. As we saw previously, it's an operation * from a node to the root. Worst case is that the node floats from the root to * the leaf, therefore height = log(n). */ void heapfy(int *a, int i) { int lft = left(i); int rght = right(i); int largest = i; if (lft <= heap_size && a[i] < a[lft]) largest = lft; if (rght <= heap_size && a[largest] < a[rght]) largest = rght; if (largest != i) { int tmp = a[i]; a[i] = a[largest]; a[largest] = tmp; // A[largest] has the old A[i] value! heapfy(a, largest); // Needs to check if i is in the proper place } }
void heapfy( int *array, int raiz, int tamanho ) { int maior = raiz; int filhoEsquerda = 2 * raiz + 1; int filhoDireita = 2 * raiz; if ( filhoEsquerda <= tamanho ) { // o nó que está sendo analisado // tem filhos para a esquerda e direita if ( array[filhoEsquerda] >= array[filhoDireita] && array[filhoEsquerda] > array[raiz] ) { maior = filhoEsquerda; } else if ( array[filhoDireita] > array[filhoEsquerda] && array[filhoDireita] > array[raiz] ) { maior = filhoDireita; } } else if ( filhoDireita <= tamanho ) { // o nó que está sendo analizado // tem filho apenas para a direita if ( array[filhoDireita] > array[raiz] ) { maior = filhoDireita; } } if ( maior != raiz ) { swap( &array[raiz], &array[maior] ); heapfy( array, maior, tamanho ); } }
int main() { int n; scanf("%d", &n); // heap initialization int *values = new int[n+1]; heap_size = 0; length = n; values[0] = -1; // sentinel // inserting elements for (int i=1; i <= n; i++) { scanf("%d", (values+i)); heap_size++; }; heapfy(values, 2); print(values); // Testing build heap scanf("%d", &n); int *a = new int[n+1]; for (int i=1; i <= n; i++) { scanf("%d", (a+i)); }; build(a, n); print(a); // Testing heapsort printf("Sorting the following heap: "); print(values); heapsort(values, n); print(values); printf("Sorting the following heap: "); print(a); heapsort(a, n); print(a); delete [] values; delete [] a; return 0; }