ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [알고리즘] 특수정렬 - (계수 정렬, 기수 정렬, 버킷 정렬)
    카테고리 없음 2023. 7. 17. 16:45

    계수 정렬이란 ? 주어진 배열의 값 범위가 작은 경우 빠른 속도를 갖는 정렬 알고리즘이다. 최댓값과 입력 배열의 원소 값 개수를 누적합으로 구성한 배열로 정렬을 수행함

    과정 : 

    1. 배열을 쭉 돌면서 해당 값을 index로 하는 새로운 배열의 값을 1 증가시킨다.

    array[0] = 1 → counting[1]값 1증가

    array[1] = 3 → counting[3]값 1증가

    counting배열은 1의 개수는 3개, 2의 개수는 1개, … 등 해당 인덱스 값의 개수를 담는 배열이다.

    2. 완성된 counting 배열의 누적합을 계산한다.

    counting[1] → counting[0] + counting[1]

    counting[2] → counting[1] + counting[2]

    counting[5] → counting[4] + counting[5]

    3. 최종 정렬하기

    counting 배열은 시작값을 알려주기 때문에 해당 값을 counting 배열의 값을 보고 넣어주면 된다.

    array[9] = 1, counting[1] = 3 으로 counting 배열의 값에서 1을 빼주고 새로운 result 배열에 넣어주면 된다. result 배열에 넣어준 후에는 다음 값을 위해서 counting 배열의 값을 -1 해주어야 한다.

    package Sort;
    
    public class CountingSort {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    
    		int[] array = new int[30];
    		int[] counting = new int[10];
    		int[] result = new int[30];
    
    		// 랜덤값 생성하기 (0 ~ 9)
    		for (int i = 0; i < array.length; i++) {
    			array[i] = (int) (Math.random() * 10);
    		}
    
    		// 1번과정
    		for (int i = 0; i < array.length; i++) {
    			counting[array[i]]++;
    		}
    
    		// 2번과정
    		for (int i = 1; i < counting.length; i++) {
    			counting[i] = counting[i] + counting[i - 1];
    		}
    
    		// 3번과정
    		for (int i = array.length - 1; i >= 0; i--) {
    			int value = array[i];
    			counting[value]--;
    			result[counting[value]] = value;
    
    		}
    		// 결과 출력
    		System.out.println("정렬된 결과:");
    		for (int i = 0; i < result.length; i++) {
    			System.out.print(result[i] + " ");
    		}
    	}
    
    }

    기수 정렬이란 ? 원소들이 모두 상수 k개 이하의 자릿수를 가진 자연수와 같은 특수한 경우에 사용할 수 있는 방법

    예를들어, {28, 93, 39, 81, 62, 72, 38, 26}로 구성된 배열이 있다.

    먼저 1의 자릿수로 정렬을 하게 되면 {81, 62, 72, 93, 26, 28, 38, 39}로 정렬이 될 것이다. 이제 10의 자릿수로 정렬을 하게 되면 {26, 28, 38, 39, 62, 72, 81, 93}으로 배열의 원소들이 정렬된 것을 확인할 수 있다.

    package Sort;
    
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class RadixSort {
    
    	static final int bucketSize = 10;
    	
    	public static void main(String[] args) {
    		int[] arr = {28, 93, 39, 81, 62, 72, 38, 26};
    		
    		radix_Sort(arr.length, arr);
    		
    		for (int i = 0; i < arr.length; ++i) {
    			System.out.print(arr[i] + " ");
    		}
    	}
    	
    	public static void radix_Sort(int n, int[] arr) {
    		//bucket 초기화
    		Queue<Integer>[] bucket = new LinkedList[bucketSize];
    		for (int i = 0; i < bucketSize; ++i) {
    			bucket[i] = new LinkedList<>();
    		}
    		
    		int factor = 1;
    		
    		//정렬할 자릿수의 크기 만큼 반복한다.
    		for (int d = 0; d < 2; ++d) {
    			for (int i = 0; i < n; ++i) {
    				bucket[(arr[i] / factor) % 10].add(arr[i]);
    			}
    			
    			for (int i = 0, j = 0; i < bucketSize; ++i) {
    				while (!bucket[i].isEmpty()) {
    					arr[j++] = bucket[i].poll();
    				}
    			}
    			
    			factor *= 10;
    		}
    	}
    }

    3. 버킷 정렬이란 ? 정렬하고자 하는 원소들이 균등 분포 할때를 가정한 유용한 정렬 알고리즘

    과정 : 

    1. N=10(배열의 인덱스가 정수 0-9까지 필요로함)인 빈 버킷 또는 리스트 B를 생성힌다.

    2. 배열 A의 모든 원소 A[i] 에 대해  B[N*A[i]] 버킷에 A[i]를 추가한다.

    ex) A[0] = 0.78 -> B[10*0.78 = 7] = 0.78 ...

    3. B[N*A[i]] 버킷에 A[i]를 추가시 삽입정렬(insertion sort)을 사용하여 각 버킷에 추가된 자료를 정렬한다.

    4. 모든 버킷들 (B[0] 부터 B[N-1])에 정렬된데이터를 순차적으로 연결한다.

    package Sort;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class BucketSort {
    
        public static void main(String[] args) {
            // 입력 데이터 배열
            float[] datasets = { 0.897f, 0.156f, 0.565f, 0.556f, 0.656f, 0.1234f, 0.665f, 0.3434f };
    
            // 버킷 정렬 수행
            bucketSort(datasets);
    
            // 정렬된 결과 출력
            for (int i = 0; i < datasets.length; i++) {
                System.out.print(datasets[i] + " ");
            }
        }
    
        public static void bucketSort(float[] datasets) {
            // 0-9까지 버킷 리스트 생성
            List<Float>[] buckets = new ArrayList[10];
            for (int i = 0; i < datasets.length; i++) {
                int index = (int) (datasets[i] * 10); // 0.0~0.9의 값은 0-9의 버킷에 할당
                if (buckets[index] == null) {
                    buckets[index] = new ArrayList<>();
                }
    
                // 맨 뒤에 값을 추가하고 삽입 정렬 수행
                buckets[index].add(datasets[i]);
                insertionSort(buckets[index], datasets[i]);
            }
    
            int c = 0;
            // 버킷들을 합치면서 최종 정렬된 배열로 복사
            for (int i = 0; i < 10; i++) {
                if (buckets[i] != null) {
                    int size = buckets[i].size();
                    for (int j = 0; j < size; j++) {
                        datasets[c++] = buckets[i].get(j);
                    }
                }
            }
        }
    
        // 버킷 내에서 삽입 정렬 수행
        public static void insertionSort(List<Float> list, float v2) {
            int bucketSize = list.size() - 1;
            int i = 0;
            for (i = bucketSize - 2; i >= 0; i--) {
                float v1 = list.get(i);
                if (list.get(i) < v2)
                    break;
                list.set(i + 1, v1);
            }
    
            if (i >= 0) {
                list.set(i, v2);
            }
        }
    }

     

     

Designed by Tistory.