정렬 알고리즘

정렬 알고리즘에 대해 알아봅시다.

Imagem de capa

1.버블정렬

O(N^2)

placeholder

가장 평범한 비교로 왼쪽부터 2개씩 비교해나가 뒤에부터 정렬이 되어갑니다.


public class Main {
    public static void main(String[] args){

    	int data[] = {66, 10, 1, 34, 5};
    	sort(data);

    	for(int i=0; i<data.length; i++){
            System.out.println("data["+i+"] : " + data[i]);
        }

    }
    public static void sort(int[] data){
        int temp = 0;
        for(int i=data.length-1; i>=0; i--){
            for(int j=0; j<i; j++){
                if(data[j] > data[j+1]){
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                }
            }
        }
    }
}

2.선택정렬

O(N^2)

placeholder

첫번값을 최소값으로 잡아두고 뒤를 비교해 나가다가 더 작은게 있으면 바꿔주고 마지막에 바꿔줍니다.



public class Main {
    public static void main(String[] args){

    	int data[] = {66, 10, 1, 34, 5};
    	sort(data);

    	for(int i=0; i<data.length; i++){
            System.out.println("data["+i+"] : " + data[i]);
        }

    }
    public static void sort(int[] data){
        int size = data.length;
        int min; //최소값을 가진 데이터의 인덱스 저장 변수
        int temp;

        for(int i=0; i<size-1; i++){ // size-1 : 마지막 요소는 자연스럽게 정렬됨
            min = i;
            for(int j=i+1; j<size; j++){
                if(data[min] > data[j]){
                    min = j;
                }
            }
            temp = data[min];
            data[min] = data[i];
            data[i] = temp;
        }
    }
}


3.삽입정렬

O(N^2)

placeholder

하나씩 기준으로 잡고 그 기준으로부터 앞으로 비교해나가는 정렬.



public class Main{
    public static void main(String[] args){

    	int data[] = {66, 10, 1, 34, 5};
    	sort(data);

    	for(int i=0; i<data.length; i++){
            System.out.println("data["+i+"] : " + data[i]);
        }

    }
    public static void sort(int[] A){
        int size = A.length;
        int temp = 0;
        int j = 0;
        for(int i = 1; i < size; i++){
            temp = A[i];
            for(j=i-1; j>=0 && temp<A[j]; j--){
                A[j+1] = A[j];
            }
            A[j+1] = temp;
        }
    }

}


4.병합정렬

최소 O(NlogN)

placeholder



public class Main{

    public static void main(String[] args){

    	int data[] = {66, 10, 1, 34, 5};

        data=mergeSort(data);
        for(int i=0;i<data.length;i++){
        	System.out.println(data[i]);
        }
    }
    public static int[] mergeSort(int[] list) {
    	if (list.length <= 1) {
    		return list;
    	}
	//반을 나눈다.
    	int[] first = new int[list.length / 2];
    	int[] second = new int[list.length - first.length];
	//list의 0번째부터 first의 0번째에 first.length만큼 붙여넣는다.
    	System.arraycopy(list, 0, first, 0, first.length);
    	System.arraycopy(list, first.length, second, 0, second.length);
    	mergeSort(first); mergeSort(second);
	//하나씩 나눈 후에 merge 함수 호출.
    	merge(first, second, list);
    	return list;
	}
    private static void merge(int[] first, int[] second, int[] result) {
    	int iFirst = 0;
    	int iSecond = 0;
    	int j = 0;
    	while (iFirst < first.length && iSecond < second.length) {
    		if (first[iFirst] < second[iSecond]) {
    			result[j] = first[iFirst]; iFirst++;
		} else {
			result[j] = second[iSecond]; iSecond++;
		}
    		j++;
	}
    //비교안된 수를 넣는 작업.
    System.arraycopy(first, iFirst, result, j, first.length - iFirst); 
    System.arraycopy(second, iSecond, result, j, second.length - iSecond); 
    }
}


5.퀵소트 알고리즘

평균적으로 O(NlogN) 최악은 O(N^2) 퀵정렬의 속도는 피봇이 영향을 줍니다.

placeholder



public class Main{

    public static void main(String[] args){

    	int data[] = {66, 10, 1, 34, 5};

        sort(data, 0, data.length - 1);
        for(int i=0;i<data.length;i++){
        	System.out.println(data[i]);
        }
    }
    public static void sort(int[] data, int l, int r){
        int left = l;
        int right = r;
	//피봇은 임의로 설정한다.
        int pivot = data[(l+r)/2];
        //do-while문으로 하나의 피봇을 기준으로 왼쪽으로는 자기보다 작은 수, 오른쪽으로는 자기보다 큰 수로 나눈다.
        do{
            while(data[left] < pivot) left++;
            while(data[right] > pivot) right--;
            if(left <= right){
                int temp = data[left];
                data[left] = data[right];
                data[right] = temp;
                left++;
                right--;
            }
        }while (left <= right);
        //하나의 피봇을 기준으로 나누었으면 그 나눈 값들에서도 똑같이 실행한다.
        if(l < right) sort(data, l, right);
        if(r > left) sort(data, left, r);
    }
}


정렬속도를 비교한 영상이 있습니다. 영상보기

6.퀵정렬 개선 median of three quicksort

맨 앞,중간,맨 뒤의 값들을 우선적으로 정렬하고 3개의 값중 중간값을 피벗으로 잡고 “맨뒤-1”번째로 이동해주고 퀵소트 알고리즘으로 정렬



public class Main {

	public static void main(String[] args) {
		int inputArray[] = { 4, 6, 7, 1, 3, 18, 16, 15, 15, 20, 9 };
		System.out.println("Before Sort : PrintArray()");
		printArray(inputArray);
		quickSortPivotMedian(inputArray, 0, inputArray.length - 1);
		System.out.println("Arter Sort : PrintArray()");
		printArray(inputArray);
	}

	public static void quickSortPivotMedian(int[] array, int left, int right) {
		int size = right - left + 1;
		if (size <= 3) {
			manualSort(array, left, right, size);
		} else {
			int median = medianOf3(array, left, right);
			int partition = partitionIt(array, left, right, median);
			quickSortPivotMedian(array, left, partition - 1);
			quickSortPivotMedian(array, partition + 1, right);
		}
	}

	public static int medianOf3(int[] array, int left, int right) {
		int center = (left + right) / 2;
		if (array[left] > array[center])
			swap(array, left, center);
		if (array[left] > array[right])
			swap(array, left, right);
		if (array[center] > array[right])
			swap(array, center, right);

		swap(array, center, right - 1);
		return array[right - 1];
	}

	public static int partitionIt(int[] array, int left, int right, long pivot) {
		System.out.println(pivot);
		int leftPtr = left;
		int rightPtr = right - 1;

		while (true) {
			while (array[++leftPtr] < pivot)
				;
			while (array[--rightPtr] > pivot)
				;
			if (leftPtr >= rightPtr)
				break;
			else
				swap(array, leftPtr, rightPtr);
		}
		swap(array, leftPtr, right - 1);
		return leftPtr;
	}

	public static void manualSort(int[] array, int left, int right, int size) {

		if (size <= 1)
			return;
		if (size == 2) {
			if (array[left] > array[right])
				swap(array, left, right);
			return;
		} else{
			if (array[left] > array[right - 1])
				swap(array, left, right - 1);
			if (array[left] > array[right])
				swap(array, left, right);
			if (array[right - 1] > array[right])
				swap(array, right - 1, right);
		}
	}

	public static void swap(int[] array, int index1, int index2){
		int temp = array[index1];
		array[index1] = array[index2];
		array[index2] = temp;
	}

	public static final void printArray(int array[]) {
		for (int element : array) {
			System.out.print(element + " ");
		}
		System.out.println("");
	}

}