임베디드 개발(before)/IoT 임베디드 SW 개발자 양성과정

[24일차] 정렬 알고리즘(선택, 삽입, 거품, 쉘, 퀵, 기수, 힙)

주운녕 2020. 8. 13. 18:31

여러 정렬 알고리즘에 대해 배웠다.

-----------구현 단순 but 느림----------------

  • 선택 정렬
  • 삽입 정렬
  • 버블 정렬
  • 쉘 정렬

-----------구현 복잡 but 빠름----------------

  • 퀵 정렬
  • 기수 정렬
  • 힙 정렬

 

 

  • 방법론
    - 기본 동작 : 판단(decision)과 교환(exchange).
  • 데이터의 표현
    - 파일(file) : 정렬 대상. 정렬되지 않은 레코드들의 무리.(?)
    - 레코드 : 정보 단위. 교환의 대상. 느낌상 구조체라 생각하면 이해됨.
    - 필드(field) : 각 레코드의 정보를 담고 있는 멤버. 느낌상 구조체 멤버(?)

    - 키(key) : 정렬의 기준이 되는 필드. 비교(판단)의 기준이 되는 데이터. (데이터 필드)

 

  • 선택 정렬
더보기

 

 

- 구현 코드

# include <stdio.h>
# define SWAP(x, y, temp) ( (temp)=(x), (x)=(y), (y)=(temp) )
# define MAX_SIZE 5

// 선택 정렬
void selection_sort(int list[], int n){
  int i, j, least, temp;

  // 마지막 숫자는 자동으로 정렬되기 때문에 (숫자 개수-1) 만큼 반복한다.
  for(i=0; i<n-1; i++){
    least = i;

    // 최솟값을 탐색한다.
    for(j=i+1; j<n; j++){
      if(list[j]<list[least])
        least = j;
    }

    // 최솟값이 자기 자신이면 자료 이동을 하지 않는다.
    if(i != least){
        SWAP(list[i], list[least], temp);
    }
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {9, 6, 7, 3, 5};

  // 선택 정렬 수행
  selection_sort(list, n);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

  • 삽입 정렬
    정렬이 어느 정도 돼있을수록 성능이 좋다. 손에 들고 있는 카드를 정리하는 방식을 떠올리면 이해하기 쉽다.
    정렬된 데이터에서는 실행시간이 '0'
더보기

 

 - So simple하게 구현한 코드

# include <stdio.h>
# define MAX_SIZE 5

// 삽입 정렬
void insertion_sort(int list[], int n){
  int i, j, key;

  // 인텍스 0은 이미 정렬된 것으로 볼 수 있다.
  for(i=1; i<n; i++){
    key = list[i]; // 현재 삽입될 숫자인 i번째 정수를 key 변수로 복사

    // 현재 정렬된 배열은 i-1까지이므로 i-1번째부터 역순으로 조사한다.
    // j 값은 음수가 아니어야 되고
    // key 값보다 정렬된 배열에 있는 값이 크면 j번째를 j+1번째로 이동
    for(j=i-1; j>=0 && list[j]>key; j--){
      list[j+1] = list[j]; // 레코드의 오른쪽으로 이동
    }

    list[j+1] = key;
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {8, 5, 6, 2, 4};

  // 삽입 정렬 수행
  insertion_sort(list, n);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

- 배열로 구현 - 배열 자리를 이동할 때 memmove 함수를 사용했다. 괜히 어려워 보인다.

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

// 삽입 정렬 함수
void InsertionSort(int *arr, int size)
{
    int i, j;
    int card;

    for(i = 1; i < size; i++)
    {
        // [i]를 카드로 선택
        card = arr[i];

        // 카드인 [i]의 왼쪽부터 끝[0]까지
        // 카드보다 작은 데이터의 인덱스를 탐색한다
        for(j = i - 1;  j >= 0;  j--)
            if(arr[j] < card)
                break;

        // 루프를 빠져나왔을 때의 j는
        // 1) 선택한 [i]보다 작은 데이터가 있는 인덱스
        // 2) 또는 카드보다 작은 데이터가 없으면 -1이 된다
        memmove(&arr[j + 2], &arr[j + 1], sizeof(arr[0]) * (i - j - 1));
        
        arr[j + 1] = card;
    }
}

// 배열 데이터 출력 함수
void __print_data(int *arr, int size)
{
    int i;

    for(i=0; i<size; i++)
        printf("%4d ", arr[i]);

    printf("\n");
}

int main(void)
{
    int i, idx, cnt = 0;
    int data[100] = {0, };
    int size = sizeof(data) / sizeof(data[0]);

    for(i=0; cnt < size; i++)
    {
        idx = rand() % size;

        if(data[idx] == 0)
            data[idx] = ++cnt;
    }

    printf("----- Origin data ----- \n");
    __print_data(data, size);

    InsertionSort(data, size);

    printf("\n\n----- Sorted ----- \n");
    __print_data(data, size);  return 0;
}

 

- 리스트로 구현. 복잡하다..ㅎ

#include <stdio.h>
#include <stdlib.h>

#define ARR_SIZE 100

typedef struct _dnode
{
    struct _dnode *prev;
    struct _dnode *next;
    char key;
} dnode;

dnode *head, *tail;

void init_dlist(void)
{
    head = (dnode*)malloc(sizeof(dnode));
    tail = (dnode*)malloc(sizeof(dnode));
    head->next = tail;
    head->prev = head;
    tail->next = tail;
    tail->prev = head;
}

void Insert_sort(char a[])
{
	int i,j;
	char t;
	for(i=1;i<ARR_SIZE;i++)
	{
		t=a[i];
		for(j=i; j>0 && a[j-1]>t ;j--)
		{
			a[j] = a[j-1];
		}
		a[j]=t;
	}
}

void Insert_list_sort(dnode a[])
{
	dnode * i,*j,*t;
	
	/* Todo 1. 삽입 정렬의 개선 - list로 구현하기
	* 1. a 다음노드를 i에 대입
	* 2. 만약 i 다음노드가 널포인터가 아니면 반복
	* 2.1 t와 j는 i값을 대입
	* 2.2 만약 j앞 노드의 key값이 t의 key값보다 크면 j는 j의 앞노드로 치환 반복
	* 2.3 i는 i다음노드
	* 2.4 만약 t와 j가 같지 않으면
	* 2.4.1 t 앞노드의 다음에 t다음노드값을 대입
	* 2.4.2 t 다음노드의 앞에 t앞노드값을 대입
	* 2.4.3 t다음노드는 j
	* 2.4.4 t앞노드는 j앞노드
	* 2.4.5 j앞노드의 다음은 t
	* 2.4.6 j앞노드는 t
	*/
	i=a->next;
	while(i->next!=0)
	{
		t=i;
		j=i;
		while(j->prev->key > t->key)
		{
			j = j->prev;
		}
		i=i->next;
		if(t!=j)
		{
			t->prev->next = t->next;
			t->next->prev = t->prev;
			t->next=j;
			t->prev=j->prev;
			j->prev->next = t;
			j->prev = t;
		}
	}
}

int insert_dnode(char data)
{
    dnode *New;

    New=(dnode *)malloc(sizeof(dnode));

    New->key=data;   
    New->next=NULL;    
    New->prev=tail->prev;
    New->prev->next = New;
    tail->prev=New;    
	
    return New->key;
}

void DList(char a[])
{
	int i;
    init_dlist();

    for(i=0;i<ARR_SIZE;i++)	
 		insert_dnode(a[i]);
}

void main(void)
{
	int i;
	static char data1[ARR_SIZE];
	dnode * d; 
	for(i=0;i<ARR_SIZE;i++)		data1[i]=i*1358%146;
	DList(data1);
	
	Insert_list_sort(head->next);

//	display here

	Insert_sort(data1);

//	display here

	puts("end");

	return ;
}

 

 

  • 버블 정렬
    내 기준 가장 구현하기 쉽다(ㅎ)
더보기

 

- 이중 반복문의 반복 범위를 잘 보자.

# include <stdio.h>
# define MAX_SIZE 5

// 버블 정렬
void bubble_sort(int list[], int n){
  int i, j, temp;

  for(i=n-1; i>0; i--){
    // 0 ~ (i-1)까지 반복
    for(j=0; j<i; j++){
      // j번째와 j+1번째의 요소가 크기 순이 아니면 교환
      if(list[j]<list[j+1]){
        temp = list[j];
        list[j] = list[j+1];
        list[j+1] = temp;
      }
    }
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {7, 4, 5, 1, 3};

  // 버블 정렬 수행
  bubble_sort(list, n);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

 - 보드에 올려서 수행시간을 보는 용도의 코드.
버블 정렬의 개선은 FLAG를 추가하였는데 무슨 차이인지 잘 모르겠다. 아마 반복 횟수를 줄이기 위해 중간에 완료가 되었을 시 정렬을 종료하는 것 같다.

/* ==============================================================================
 *   File Name : Bubble.c
 *   Date : 2013/1/14
 *   Author : Seonghye, Son
 * ==============================================================================
 */

#include "uart.h"
#include "clkcon.h"

#define ARR_SIZE 20

typedef enum {F, T}Bool;

void Bubble_sort(int a[])
{
	int i,j,t;
	for(i=0;i<ARR_SIZE-1;i++)
	{
		for(j=1;j<ARR_SIZE-i;j++)
		{
			if(a[j-1] > a[j])
			{
				t=a[j-1];
				a[j-1] = a[j];
				a[j]=t;
			}
		}
	}
}

void Bubble_sort2(int a[])
{
	int i,j,t;
	Bool Flag=F;
	/* Todo 1. 버블 정렬의 개선
	* 1. i값은 0에서부터 배열크기-1보다 작은동안에 1씩증가하면서 반복
	* 1.1 Flag변수를 이용하여 한단계 끝날 때마다 False로 초기화
	* 1.2 j값은 1에서부터 배열크기-i보다 작은동안에 1씩증가하면서 반복
	* 1.2.1 만약 배열의 j-1값이 j값보다 크면 swap하고, Flag 값을 True로 변경 
	* 1.3 만약 Flag값이 False이면 교환이 한번도 일어나지 않았으므로 루프문 탈출
	*/
	for(i=0;i<ARR_SIZE-1;i++)
	{
		Flag=F;
		for(j=1;j<ARR_SIZE-i;j++)
		{
			if(a[j-1] > a[j])
			{
				t=a[j-1];
				a[j-1] = a[j];
				a[j]=t;
				Flag=T;
			}
		}
		if(Flag==F)break;
	}
}

void Bubble_main(void)
{
	int i,t1,t2;
	int data1[ARR_SIZE]={10,25,42,4,26,8,1,2,5,3,15,2,5,47,5,88,9,34,17,22};
	int data2[ARR_SIZE]={10,25,42,4,26,8,1,2,5,3,15,2,5,47,5,88,9,34,17,22};
	
	Uart_Printf("\n");
	for(i=0;i<ARR_SIZE;i++)		Uart_Printf("%d ",data1[i]);
	StartTimer();
	Bubble_sort(data1);
	t1 = GetElapsedTime();
	StopTimer();
	StartTimer();
	Bubble_sort(data1);
	t2 = GetElapsedTime();
	StopTimer();
	Uart_Printf("\n");
	for(i=0;i<ARR_SIZE;i++)		Uart_Printf("%d ",data1[i]);
	Uart_Printf("\n Bubble sort : in %d ns", t1);
	Uart_Printf("\n Bubble sort after : in %d ns", t2);
	
	
	Uart_Printf("\n\n");
	for(i=0;i<ARR_SIZE;i++)		Uart_Printf("%d ",data2[i]);
	StartTimer();
	Bubble_sort2(data2);
	t1 = GetElapsedTime();
	StopTimer();
	StartTimer();
	Bubble_sort2(data2);
	t2=GetElapsedTime();
	StopTimer();
	Uart_Printf("\n");
	for(i=0;i<ARR_SIZE;i++)		Uart_Printf("%d ",data2[i]);
	Uart_Printf("\n Bubble sort2 : in %d ns", t1);
	Uart_Printf("\n Bubble sort2 after : in %d ns", t2);
}

 

  • 쉘 정렬
    삽입 정렬은 데이터 집합의 정렬이 많이 이루어져 있을수록 성능이 좋다.
    쉘 정렬은 이 점을 활용한 방법.
    갭을 활용하여 대략적인 정렬을 한 뒤, 삽입 정렬을 실시하는 경우로 볼 수 있다.
더보기

 

 

- 쉘 정렬 하나로 만든 방식

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void shell_sort(int a[], int n){
	int i, j, k, h, v;
	for(h = n/2; h>0; h/=2){
		for(i=0; i<h; i++){
			for(j=i+h; j<n; j+=h){
				v = a[j];
				k = j;
				while(k>h-1 && a[k-h] > v){
					a[k] = a[k-h];
					k -= h;
				}
				a[k] = v;
			}
		}
	}
}

int main(){
	int a[10] = {9, 7, 2, 8, 1, 3, 5, 11, 6, 10 };
	
	printf("Original\n");
	for(int i=0; i< sizeof(a)/sizeof(a[0]); i++){
	printf("%d ", a[i]);
	}
	printf("%\n");

	shell_sort(a,  sizeof(a)/sizeof(a[0]));

	printf("shellsort\n");
	for(int i=0; i<  sizeof(a)/sizeof(a[0]); i++){
	printf("%d ", a[i]);
	}
	printf("%\n");

	return 0;
}

 

 

- 쉘 정렬 부분과 삽입 정렬을 함수 구분해서 만든 방식

# include <stdio.h>
# define MAX_SIZE 10

// gap만큼 떨어진 요소들을 삽입 정렬
// 정렬의 범위는 first에서 last까지
void inc_insertion_sort(int list[], int first, int last, int gap){
  int i, j, key;

  for(i=first+gap; i<=last; i=i+gap){
    key = list[i]; // 현재 삽입될 숫자인 i번째 정수를 key 변수로 복사

    // 현재 정렬된 배열은 i-gap까지이므로 i-gap번째부터 역순으로 조사한다.
    // j 값은 first 이상이어야 하고
    // key 값보다 정렬된 배열에 있는 값이 크면 j번째를 j+gap번째로 이동
    for(j=i-gap; j>=first && list[j]>key; j=j-gap){
      list[j+gap] = list[j]; // 레코드를 gap만큼 오른쪽으로 이동
    }

    list[j+gap] = key;
  }
}

// 셸 정렬
void shell_sort(int list[], int n){
  int i, gap;

  for(gap=n/2; gap>0; gap=gap/2){
    if((gap%2) == 0)(
      gap++; // gap을 홀수로 만든다.
    )

    // 부분 리스트의 개수는 gap과 같다.
    for(i=0; i<gap; i++){
      // 부분 리스트에 대한 삽입 정렬 수행
      inc_insertion_sort(list, i, n-1, gap);
    }
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {10, 8, 6, 20, 4, 3, 22, 1, 0, 15, 16};

  // 셸 정렬 수행
  shell_sort(list, n);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

 

  • 퀵 정렬
    알고리즘 문제를 풀면서 몇 번 사용해본 정렬 알고리즘이다. C 라이브러리에 선언되어있어 함수로 사용할 수 있다.
    정렬되어 있거나 역순인 데이터에 대해서는 성능이 떨어진다. O(N^2)
더보기

 

- 재귀식으로 구현한 퀵 정렬.

# include <stdio.h>
# define MAX_SIZE 9
# define SWAP(x, y, temp) ( (temp)=(x), (x)=(y), (y)=(temp) )

// 1. 피벗을 기준으로 2개의 부분 리스트로 나눈다.
// 2. 피벗보다 작은 값은 모두 왼쪽 부분 리스트로, 큰 값은 오른쪽 부분 리스트로 옮긴다.
/* 2개의 비균등 배열 list[left...pivot-1]와 list[pivot+1...right]의 합병 과정 */
/* (실제로 숫자들이 정렬되는 과정) */
int partition(int list[], int left, int right){
  int pivot, temp;
  int low, high;

  low = left;
  high = right + 1;
  pivot = list[left]; // 정렬할 리스트의 가장 왼쪽 데이터를 피벗으로 선택(임의의 값을 피벗으로 선택)

  /* low와 high가 교차할 때까지 반복(low<high) */
  do{
    /* list[low]가 피벗보다 작으면 계속 low를 증가 */
    do {
      low++; // low는 left+1 에서 시작
    } while (low<=right && list[low]<pivot);

    /* list[high]가 피벗보다 크면 계속 high를 감소 */
    do {
      high--; //high는 right 에서 시작
    } while (high>=left && list[high]>pivot);

    // 만약 low와 high가 교차하지 않았으면 list[low]를 list[high] 교환
    if(low<high){
      SWAP(list[low], list[high], temp);
    }
  } while (low<high);

  // low와 high가 교차했으면 반복문을 빠져나와 list[left]와 list[high]를 교환
  SWAP(list[left], list[high], temp);

  // 피벗의 위치인 high를 반환
  return high;
}

// 퀵 정렬
void quick_sort(int list[], int left, int right){

  /* 정렬할 범위가 2개 이상의 데이터이면(리스트의 크기가 0이나 1이 아니면) */
  if(left<right){
    // partition 함수를 호출하여 피벗을 기준으로 리스트를 비균등 분할 -분할(Divide)
    int q = partition(list, left, right); // q: 피벗의 위치

    // 피벗은 제외한 2개의 부분 리스트를 대상으로 순환 호출
    quick_sort(list, left, q-1); // (left ~ 피벗 바로 앞) 앞쪽 부분 리스트 정렬 -정복(Conquer)
    quick_sort(list, q+1, right); // (피벗 바로 뒤 ~ right) 뒤쪽 부분 리스트 정렬 -정복(Conquer)
  }

}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {5, 3, 8, 4, 9, 1, 6, 2, 7};

  // 퀵 정렬 수행(left: 배열의 시작 = 0, right: 배열의 끝 = 8)
  quick_sort(list, 0, n-1);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

 

- 배열 스택으로 구현한 퀵 정렬.

#include <stdio.h>
 
#define MAX_NUM 50
int stack[MAX_NUM];
int top = 0;
 
void init_stack()
{
        top = 0;
}
 
void push(int i)
{
 
        if( top >= MAX_NUM) {
                printf("stack full\n");
                return;
        }
        else
                stack[top++] = i;
}
 
int pop()
{
 
        if( top == 0)
                return 0;
        else
                return stack[--top];
 
}
 
int is_stack_empty()
{
 
        if( top == 0)
                return 1;
        else
                return 0;
 
}
void qsort(int a[], int n)
{
        int p, t;
        int i, j;
        int l, r;
 
        init_stack();  
 
        l = 0;		// left most one
        r = n - 1;	//right most one
 
        push(r);
        push(l);
 
        while(!is_stack_empty()) {
                l = pop();
                r = pop();
 
                if( r-l+1 > 1) {  // 종료조건 :: 남아 있는 분할의 원소 개수가 1개 이상일 경우
                        p = a[r];
                        i = l - 1;
                        j = r;
 
                        while(1) {
                                while(a[++i] < p);
                                while(a[--j] > p);
 
                                if( i >= j)
                                        break;

                                t = a[i];
                                a[i] = a[j];
                                a[j] = t;
 
                        }
 
/*
	TODO:               // pivot과 i값을 교환
**/
                        t = a[i];
                        a[i] = a[r];
                        a[r] = t;
 
                        push(r);    // 오른쪽 분할의 오른쪽 끝		||----------@
                        push(i+1);  // 오른쪽 분할의 왼쪽 끝		||@----------
                        push(i-1);  // 왼쪽 분할의 오른쪽 끝		----------@||
                        push(l);    // 왼쪽 분할의 왼쪽 끝		@----------||
 
                } // if
        } // while
 }


void main(){
  int i;
  int n = 5;
  int list[5] = {9, 6, 7, 3, 5};
 
  qsort(list, n);

 
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}

 

  • 기수 정렬
더보기

설명 블로그

 

06 정렬 알고리즘 - 기수 정렬(Radix Sort)

기수정렬 (Radix Sort) 기수정렬은 낮은 자리수부터 비교하여 정렬해 간다는 것을 기본 개념으로 하는 정렬 알고리즘입니다. 기수정렬은 비교 연산을 하지 않으며 정렬 속도가 빠르지만 데이터 전�

lktprogrammer.tistory.com

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>


/*****************************************************************************
*                                                                            *
*  -------------------------------- rxsort --------------------------------  *
*                                                                            *
*****************************************************************************/

int rxsort(int *data, int size, int p, int k) {

int                *counts,
                   *temp;

int                index,
                   pval,
                   i,
                   j,
                   n;

/*****************************************************************************
*                                                                            *
*  Allocate storage for the counts.                                          *
*                                                                            *
*****************************************************************************/

if ((counts = (int *)malloc(k * sizeof(int))) == NULL)
   return -1;

/*****************************************************************************
*                                                                            *
*  Allocate storage for the sorted elements.                                 *
*                                                                            *
*****************************************************************************/

if ((temp = (int *)malloc(size * sizeof(int))) == NULL)
   return -1;

/*****************************************************************************
*                                                                            *
*  Sort from the least significant position to the most significant.         *
*                                                                            *
*****************************************************************************/

for (n = 0; n < p; n++) {

   /**************************************************************************
   *                                                                         *
   *  Initialize the counts.                                                 *
   *                                                                         *
   **************************************************************************/

   for (i = 0; i < k; i++)
      counts[i] = 0;

   /**************************************************************************
   *                                                                         *
   *  Calculate the position value.                                          *
   *                                                                         *
   **************************************************************************/

   pval = (int)pow((double)k, (double)n);

   /**************************************************************************
   *                                                                         *
   *  Count the occurrences of each digit value.                             *
   *                                                                         *
   **************************************************************************/

   for (j = 0; j < size; j++) {

      index = (int)(data[j] / pval) % k;
      counts[index] = counts[index] + 1;

   }

   /**************************************************************************
   *                                                                         *
   *  Adjust each count to reflect the counts before it.                     *
   *                                                                         *
   **************************************************************************/

   for (i = 1; i < k; i++)
      counts[i] = counts[i] + counts[i - 1];

   /**************************************************************************
   *                                                                         *
   *  Use the counts to position each element where it belongs.              *
   *                                                                         *
   **************************************************************************/

   for (j = size - 1; j >= 0; j--) {

      index = (int)(data[j] / pval) % k;
      temp[counts[index] - 1] = data[j];
      counts[index] = counts[index] - 1;

   }

   /**************************************************************************
   *                                                                         *
   *  Prepare to pass back the data as sorted thus far.                      *
   *                                                                         *
   **************************************************************************/

   memcpy(data, temp, size * sizeof(int));

}

/*****************************************************************************
*                                                                            *
*  Free the storage allocated for sorting.                                   *
*                                                                            *
*****************************************************************************/

free(counts);
free(temp);

return 0;

}




/*****************************************************************************
*                                                                            *
*  ------------------------------ print_idata -----------------------------  *
*                                                                            *
*****************************************************************************/

static void print_idata(const int *array, int size) {

int                i;

/*****************************************************************************
*                                                                            *
*  Display the array of integers.                                            *
*                                                                            *
*****************************************************************************/

for (i = 0; i < size; i++)
   fprintf(stdout, "A[%02d]=%d\n", i, array[i]);

return;

}


/*****************************************************************************
*                                                                            *
*  --------------------------------- main ---------------------------------  *
*                                                                            *
*****************************************************************************/

int main(int argc, char **argv) {

int                iarray[10],
                   rarray[10];



int                size = 10;

/*****************************************************************************
*                                                                            *
*  Load the arrays with data to sort.                                        *
*                                                                            *
*****************************************************************************/


rarray[0] = 11111323;
rarray[1] = 99283743;
rarray[2] = 98298383;
rarray[3] = 99987444;
rarray[4] = 43985209;
rarray[5] = 99911110;
rarray[6] = 11111324;
rarray[7] = 39842329;
rarray[8] = 97211029;
rarray[9] = 99272928;



/*****************************************************************************
*                                                                            *
*  Perform radix sort.                                                       *
*                                                                            *
*****************************************************************************/

fprintf(stdout, "Before rxsort\n");
print_idata(rarray, size);

if (rxsort(rarray, size, 8, 10) != 0)
   return 1;

fprintf(stdout, "After rxsort\n");
print_idata(rarray, size);

return 0;

}

 

  • 힙 정렬
더보기

설명 블로그

 

[알고리즘] 힙 정렬(heap sort)이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

#include <stdio.h>
#include <stdlib.h>

void swap(int* a, int* b)
{
	int t; 
	t = *a; 
	*a = *b;
	*b = t;
}

// To heapify a subtree rooted with node i which is 
// an index in arr[]. n is size of heap 

void heapify(int arr[], int n, int i) 
{ 
	int largest = i; // Initialize largest as root 
	int l = 2*i + 1; // left = 2*i + 1 
	int r = 2*i + 2; // right = 2*i + 2 

	// If left child is larger than root 
	if (l < n && arr[l] > arr[largest]) 
		largest = l; 

	// If right child is larger than largest so far 
	if (r < n && arr[r] > arr[largest]) 
		largest = r; 

	// If largest is not root 
	if (largest != i) 
	{ 
		swap( &arr[i], &arr[largest]); 

		// Recursively heapify the affected sub-tree 
		heapify(arr, n, largest); 
	} 
} 

// main function to do heap sort 
void heapSort(int arr[], int n) 
{ 
	int i;
	// Build heap (rearrange array) 
	for (i = n / 2 - 1; i >= 0; i--) 
		heapify(arr, n, i); 

	// One by one extract an element from heap 
	for (i=n-1; i>0; i--) 
	{ 
/*
TODO: 
**/
		// Move current root to end 
		swap(&arr[0], &arr[i]); 

		// call max heapify on the reduced heap 
		heapify(arr, i, 0); 
	} 
} 

/* A utility function to print array of size n */
void printArray(int arr[], int n) 
{ 
	int i;
	
	for (i=0; i<n; ++i) 
		printf("%d ", arr[i] );

	putchar('\n');

} 

// Driver program 
int main() 
{ 
	int arr[] = {12, 11, 13, 5, 6, 7}; 
	int n = sizeof(arr)/sizeof(arr[0]); 

	heapSort(arr, n); 

	puts("Sorted array is "); 

	printArray(arr, n); 
} 

 


* 개인적인 학습 목적으로 작성한 글이기에 내용에 잘못된 정보가 있을 수 있습니다.

* 참고 출처 :

https://gmlwjd9405.github.io/

https://lktprogrammer.tistory.com/

 

Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io