Cod sursa(job #240079)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 6 ianuarie 2009 20:05:53
Problema Sortare prin comparare Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 4.79 kb
/*

IntroSort implementat de mana

*/


#include <stdio.h>

#define N 1000010

#define Type int
int cmp(Type a,Type b){
    if (a>b)
       return 1;
    if (a<b)
       return -1;
    return 0;
}
void swap (Type array[], int i, int k){
	Type swap = array[i];
	array[i] = array[k];
	array[k] = swap;
}
void quicksort (Type array[], int left, int right){
	if (left >= right){
		// done sorting
		return;
	}
	else if (left == right - 1){
		// two element list
		if (cmp(array[left],array[right])>0){
			// left is greater than the right — swap them
			swap(array, left, right);
		}		
		// done sorting
		return;
    }
	// since this method is recursive avoid placing these variables on the
	//   stack until the last moment
	int i = left;
	int k = right;
	// choose a pivot and move it to the end of the list
	int pivotIndex = (left + right) >> 1; // (left + right) / 2
	Type pivot = array[pivotIndex];
	array[pivotIndex] = array[right];
	array[right] = pivot;
	while (i < k){
		// move the i index to the k until something is found that is
		//  greater than the pivot
		while (cmp(array[i],pivot) <= 0 && i < k)
			++i;
		// move the k index to the i until something is found that is
		//  less than the pivot
		while (cmp(pivot,array[k]) <= 0 && i < k)
			--k;
		if (i < k){
			// swap i and k
			swap(array, i, k);
		}
	}	
	// put the pivot back
	array[right] = array[k];
	array[k] = pivot;
	// sort the left side
	quicksort(array, left, i - 1);
	// sort the right side
	quicksort(array, k + 1, right);
}
void siftDown (Type array[], int offset, int start, int end){
	int root = start;
	int child;
	// keep going while the root has at least one child
	while (((root - offset) * 2 + 1) <= (end - offset)){
		// get the left child
		child = ((root - offset) * 2 + 1) + offset;
		// if the child has a sibling and the child’s value is less than its
		//   siblings
		if (child < end && cmp(array[child],array[child+1])<0){	
			// point to the right child instead
			--child;
		}		
		if (cmp(array[root],array[child])<0){
			// out of max-heap order
			swap(array, root, child);
			// repeat to continue sifting down the child
			root = child;
		}	
		else{	
			// all sifted
			break;
		}		
	}
}
void hsort (Type array[], int start, int end){
	// to begin, place the array in max-heap order
	// get the index in array of the last parent node
	int left = start + ((end - start) >> 1);
	int right = end;
	int offset = start;
	//while (left >= 0)
	while (left >= start){	
		// sift down the node at index left to the proper place so that all
		//   nodes below the left index are in heap order
		//SiftDown(array, left, array.Length - 1);
		siftDown(array, offset, left, end);
	        --left;
	}
	// all nodes should now be in max-heap order
	while (right > start){
		// swap the maximum value of the heap with the last element of the
		//   heap
		swap(array, right, start);
		// decrease the size of the heap by one so that the previous max
		//   value will stay in its proper placement
		--right;
		// put the heap back in max-heap order
		siftDown(array, offset, start, right);
	}	
}
void sort (Type array[], int left, int right, int depthLimit){
	if (left >= right){
		// done sorting
		return;
	}
	else if (left == right - 1){
		// two element list
		if (cmp(array[left],array[right])>0){
			// left is greater than the right swap them
			swap(array, left, right);
		}
		// done sorting
		return;
	}
	else if (depthLimit == 0){
		// depth limit has reached maximum
		hsort(array, left, right);
		return;
	}
	// decrement depth limit
	depthLimit -= 1;
	// since this method is recursive avoid placing these variables on the
	// stack until the last moment
	int i = left;
	int k = right;
	// choose a pivot and move it to the end of the list
	Type pivotIndex = (left + right) >> 1; // (left + right) / 2
	Type pivot = array[pivotIndex];
	array[pivotIndex] = array[right];
        array[right] = pivot;
	while (i < k){
		// move the i index to the k until something is found that is
		//  greater than the pivot
		while (cmp(array[i],pivot)<=0 && i<k)
			++i;
 		// move the k index to the i until something is found that is
		//  less than the pivot
		while (cmp(pivot,array[k])<=0 && i<k)
			--k;
		if (i < k){
			// swap i and k
			swap(array, i, k);
		}
	}
	// put the pivot back
	array[right] = array[k];
	array[k] = pivot;
	// sort the left side
	sort(array, left, i - 1, depthLimit);
	// sort the right side
	sort(array, k + 1, right, depthLimit);
}


int n,v[N];
int main(void){
    int i;
    freopen("algsort.in","r",stdin);
    freopen("algsort.out","w",stdout);
    scanf("%d",&n);
    for (i=1;i<=n;++i)
        scanf("%d",&v[i]);
    sort(v,1,n,n);
    for (i=1;i<=n;++i)
        printf("%d ",v[i]);
    return 0;
}