본문 바로가기
컴퓨터공학/알고리즘

5장 정렬

by Daniel.kwak 2018. 10. 15.

*버블정렬은 한 번 수행할 때 마다 가장 큰 수가 가장 오른쪽으로 차곡차곡 쌓인다.(오름차순으로 정렬시)

*버블정렬의 일반화식은 n(n-1)/2 이므로, O(n^2) 이다.

void BubbleSort (int DataSet[] , int Length){
	int i = 0;
	int j = 0;
	int temp = 0;

	for ( i = 0 ; i < length -1 ; i ++ ) {
		for ( j = 0 ; j < length - (i+1) ; j ++ ) {
			if(DataSet[j] > DataSet[j+1]) {
				temp = DataSet[j+1];
				DataSet[j+1] = DataSet[j];
				DataSet[j] = temp;
			}
		}
	}
}


*삽입정렬과 버블정렬의 성능은 동일하다. 다만 삽입정렬의 경우 정렬된 데이터에 대해서는 비교를 수행하지 않는다.


void InsertionSort(int DataSet[] , int Length){
	int i = 0;
	int j = 0;
	int value = 0 ;
	for (i = 1 ; i < length ; i ++ ) {
		if( DataSet[i-1] <= DataSet[i])
			continue;
		value = DataSet[i];
		for( j = 0 ; j < i ; j ++ ) {
			if ( DataSet[j] > value) {
				memmove ( &DataSet[j+1], &DataSet[j] , sizeof(DataSet[0]) * (i-j));
				DataSet[j] = value;
				break;
			}
		}
	}
}


*퀵정렬은 분할정복(divide and conquer)방식이다.



#define SWAP(x,y,temp) ( (temp)=(x) , (x),(y) , (y) , (temp))

/*
피벗을 기준으로 2개의 부분 리스트로 분할한다.
피벗보다 작은 값은 왼쪽으로, 피벗보다 큰 값은 오른족 리스트로 옮긴다. 
 */

int partition (int list[] , int left , int right) {
	int pivot;
	int temp;
	int low; //왼쪽에서 올라가는 index
	int high; //오른쪽에 내려오는 index 
	low=left; //
	high = right +1;
	pivot = list[left]; //피벗은 임의로 첫번째 값으로 선택한다.

	/* low high가 교차될 때 까지 반복한다. */
	do{

		/* low가 기준인 피벗보다 클 때 까지 반복한다.*/
		do{
			low++;
		} while(low <= right && list[low] < pivot );

		/* high가 기준인 피벗보다 작을 때 까지 반복한다. */
		do {
			high --;
		} while ( high >= left && list[high] > pivot);

		/* low와 high가 교차하지 않았으면 교환한다. */
		if(low < high)
			SWAP(list[low] , list[high] , temp);
	} while ( low < high );

	/* low와 high가 교차했으면 left(pivot)와 high를 교환한다.*/
	SWAP(list[left] , swap[high] , temp);

	return high; //피벗의 위치를 반환한다. 
}

void QuickSort(int list[] , int left, int right){
	if(left < right){
		int pivotIndex = partition(list , left , right); //divide (리스트를 비균등분할한다.)
		QuickSort(list , left , q-1);
		QuickSort(list , q +1 , right );

	}
}


*반복된 재귀호출은 스택을 메모리에 계속 쌓게 되어 부하의 원인이 된다. 퀵 정렬의 경우 코드가 간결해지고 가독성이 좋기 때문에 재귀를 쓰는게 단점만은 아니지만, 재귀에 대한 부담이 있다면 '꼬리재귀'를 쓰는것도 방법일 수 있다. 

'컴퓨터공학 > 알고리즘' 카테고리의 다른 글

8장 해쉬  (0) 2018.10.21
7장 우선순위 큐와 힙  (0) 2018.10.21
6장 탐색  (0) 2018.10.18
4장 트리  (0) 2018.10.15
3장 큐  (0) 2018.10.14
2장 스택  (0) 2018.10.14