Uploaded by wlsdn2749

비교정렬

advertisement
과제3
이름 : 정진우
학번 : 201868024 / 2학년
학교 : 전주대학교
학과 : 컴퓨터공학과
과목 : 알고리즘
교수님 : 장홍준 교수님
문제 본문
문제 해결 아이디어
를 모두 ascending order로 구현 했다.
2. quickSort, MergeSort 또한 모두 ascending order로 구현했다
3. 랜덤함수(random_device rRand; 하드웨어 리소스를 기반으로 바뀌는 함수) "c++11" 으로
배열에 모두넣고 랜덤함수로 셔플하게끔하여 중복없이 1~1000, 1~10000개를 만들게 하였다.
4. 성능은 c++에서 제공하는 clock_t 를 사용하여 시작할때를 start, 끝날때를 finish로 두어
finish-start = 런타임을 CLOCK_PER_SEC(초단위)으로 나누어 초단위로 출력하게 끔 하고
float형식으로 출력하게 하였다.
1. selectionSort, bubbleSort, insertionSort
문제점 & 해결방식
1. mergeSort
a.
과제3
처음 실행했을때 시간이 너무 오래걸렸다 병합정렬은 입력에 관계없이 항상 O(nlogn)을 가지기 때문에 기초 비교정렬
에 비하면 줄긴 커녕 오히려 오래 걸렸다, 이유는 함수를 call by value로 호출방식을 정했기 때문에 호출이 될때마다
array를 복사해야했기에 메모리를 할당할때 O(n)이 걸리기때문에 O(n2 ) 이 소요된 것이다. 해결방법으로는 call by
reference로 바꿨다.
1
를 사용하여 push_back으로 임시배열을 동적으로 할당해주려 했는데 이것 또한 재귀함수에서 연속적으
로 동적할당하게 되면 메모리를 x2 추가로 할당하게 되는데 이렇게 할당하게 되면 더 시간이 오래걸리는 문제가 있어
서 tmp배열(LAST-START+1)로 할당하고 push_back을 직접 대입으로 바꾸어 최적화 하였다.
b. c++ vector
https://www.acmicpc.net/board/view/31887
2. quickSort
와 마찬가지로 call by value 때는 오래 걸렸지만 call by reference로 바꾸어 해결했다.
b. i , j를 조절해가며 피벗보다 크거나, 또는 피벗보다 작은 값을 찾을때 조건을 잘못주어서 무한루프에 빠지는 경우가 있
었다. 조건을 바꾸어서 해결했다.
a. mergeSort
프로세스 동작과정
입력 N = {"500" or "5000" or "50000"}을 받고 이 수가아닐시 다시시도하게끔
2. 각 입력에 맞는 if문을 실행하여 선택정렬 , 버블정렬, 삽입정렬, 합병정렬, 퀵정렬, STL내장 정렬을 시행하여 시간을 재고
출력하게 하였다.
1.
OUTPUT
랜덤 출력했을때 나타나는 화면이다
과제3
2
결과
컴퓨터가 1초에 계산하는 시간을 약 1억번이라고 가정하면
a. 3개 기초 정렬의 시간 복잡도의 상한은 O(n2 )라고 할 수 있다.
b. 병합정렬과 퀵정렬의 시간 복잡도 상한은 O(nlogn)
c. 퀵정렬의 최악의 경우에는 O(n2 )이라고 할수 있다.
d. 출처 https://www.lgsl.kr/sto/stories/60/ALMA2020020003
2. 병합 정렬의 경우 퀵정렬 과 같이 항상 시간복잡도 O(nlogn)이 걸리지만 퀵정렬에 비하면 많이 느린 수준이다. 하지만 4
번째 사진의 결과처럼 퀵정렬과 병합정렬을 정렬된 상태로 정렬을 하면 병합정렬은 평균적인 입력과 차이가 없지만 퀵정렬
은 O(n2 )의 시간복잡도를 가지는 것을 볼 수 있다.
3. 번외로 c++ STL 내장되있는 sort(begin, end)함수는 quickSort와 mergeSort를 압도적으로 제치고 가장 빨랐다. 정확한
이유는 모르지만 추측하건대
a. 메모리 관리의 차이
b. introSort라는 정렬방식의 특징상 heapSort를 사용하기 때문에
1.
i. https://justicehui.github.io/medium-algorithm/2019/03/24/IntroSort/
내장함수이기때문에
정확한 이유는 좀 더 공부해보는게 좋겠다.
c.
코드
/* wlsdn2749@jj.ac.kr
* 2021. 10. 16 Algorithm Report3
* Prof. hongjun jang
* Comparison Sorting algorithm code
* 1. mergeSort
* 2. quickSort
*
* input data NUMBER "500", "5000", "50000"
* All input data is random without duplication
*
* output comes with existing sort to compare with
*
*/
#include <iostream>
과제3
3
#include <vector>
#include <algorithm>
#include <random>
#define SWAP(a,b) {int temp=a; a=b; b=temp;} // Macro : SWAP
#define NUMBER1 500
#define NUMBER2 5000
#define NUMBER3 50000
using namespace std;
void merge(vector<int>&, int, int, int);
void caltime(clock_t start, clock_t finish)
{
clock_t runtime;
runtime=finish-start;
cout << "
: " << (float)runtime/CLOCKS_PER_SEC << "sec\n";
}
vector<int> shufflingRandomCreator(vector<int> array, int n){
random_device rRand; //Using hardware resource not Seed
array.clear();
for(int i=0; i<n; i++){
array.push_back(i+1); // Insert array 1~n;
}
실행시간
for(int i=0; i<n; i++){
int dest = rRand() % n;
SWAP(array[i], array[dest]);
}
return array;
}
void selectionSort(vector<int>array, int n){ // n = input data NUMBER "1000 or 10000"
clock_t start = clock(); // start
for(int rightMost = n-1, maxValue=0; rightMost>0; rightMost--){ //0 < rightMost < n-1, initial Value = 0
for(int i = 0; i<=rightMost; i++){ // find maxValue
if(array[i] > array[maxValue]){
maxValue = i;
}
}
SWAP(array[maxValue], array[rightMost]);
maxValue = 0; // maxValue reset
}
clock_t finish = clock(); // end
caltime(start, finish);
}
void bubbleSort(vector<int>array, int n){
clock_t start = clock(); // start
for(int rightMost = n-1; rightMost>0; rightMost--){ // n = input data NUMBER "1000 or 10000"
for(int i = 0; i<rightMost; i++){
if(array[i] > array[i+1]){ // if element is bigger than next ... last i+1 = rightMost not error B
SWAP(array[i], array[i+1]) // SWAP between adjacent elements
}
}
}
clock_t finish = clock(); // end
caltime(start, finish);
}
void insertionSort(vector<int> array, int n){
clock_t start = clock(); // start
for(int i=1; i<n; i++) {
int loc = i - 1;
int newItem = array[i];
//is completed upto A[i-1]
while (loc >= 0 && newItem < array[loc]) { // if newitem > array[loc] : ends
array[loc + 1] = array[loc];
loc--;
}
array[loc + 1] = newItem; // insert
}
clock_t finish = clock(); // end
caltime(start, finish);
}
void printArray(vector<int>array){
vector<int>::iterator it;
for(it = array.begin(); it!=array.end(); it++){
cout << " " << *it;
}
}
/*
* mergeSort
*
과제3
4
* mergeSort is originated by divide and conquer algorithm,
* Split continuously array in half and Sort array one by one and Finally array will be Sorted
* Array is sorted by ascending order
* Divide
* 1. get parameter p = left, r = right
* 2. q = (p+r)/2 q = mid
* 3. recursively repeat ( p , q ) (q+1, r)
* 4. conquer
*
* Conquer
* 1. get parameter p = left, q = mid, r = right
* 2. makes temporary array
* 3. compare p~q's element with q+1~r's element
* 4. put smaller element into temporary array
* --------------------------------------------- sorted
* 5. copy temporary array to array
*/
void mergeSort(vector<int>&array, int p, int r){
if(p < r) {
int q = (p + r) / 2;
mergeSort(array, p, q);
mergeSort(array, q + 1, r);
merge(array, p, q, r);
}
}
void merge(vector<int>&array, int p, int q, int r){
int i = p;
int j = q+1;
int t = 0;
vector<int>tmp(r-p+1);
while(i<=q && j<=r) { // left array and right array is not max
if(array[i] <= array[j]){
tmp[t++] = array[i++]; // compare each array and put smaller into tmp
}
else tmp[t++] = array[j++]; // Sort
}
while(i<=q) tmp[t++] = array[i++]; // left array index ++ to q
while(j<=r) tmp[t++] = array[j++]; // right array index ++ to r
i=p;
vector<int>::iterator it;
for(it=tmp.begin(); it!=tmp.end(); it++){
array[i++] = *it; // copy tmp to array
}
}
/*
* quickSort
*
* quickSort is originated by divide and conquer algorithm,
* Array is sorted by ascending order
* pivot is first element = p
* Divide
* 1. get parameter p = left, r = right
* 2. exit condition : p>r
* 3. while(p<r) find(greater than pivot, lesser than pivot)
* 4.
if(p>r) SWAP(right value, pivot value)
* 5.
else SWAP(left value, pivot value)
* 6. based on pivot left side is lesser than pivot , right side is greater than pivot
* 4. recursively repeat quickSort(p , changed pivot - 1 ) (changed pivot + 1 , r)
* 5. conquer
*
* Conquer
* If the Divide is repeated recursively until the number of elements is left, it is executed until there is one remaining.
* Since the pivot position is fixed each time it is divided, Finally array will be sorted.
*/
void quickSort(vector<int>&array, int p, int r){
if(p >= r){
return;
// exit condition
}
int pivot = p; // pivot is the most left
int i = p+1;
int j = r;
while(i<=j){ // if i and j cross, stop while
while(array[pivot] >= array[i] && r >= i){ // find greater than pivot
i++;
}
while(array[pivot] <= array[j] && p < j){ // find lesser than pivot
과제3
5
j--;
}
if(i>j){
SWAP(array[j], array[pivot]); // if crossed, change right value with pivot value
}else{
SWAP(array[i], array[j]); // if not cross, change left value with right value
} // left value is smaller than right value
}
quickSort(array, p, j-1); // based on pivot, left side
quickSort(array, j+1, r); // based on pivot, right side
}
int main() {
int N; // N = 500 or 5000 or 50000
while(1) {
cout << "
: " ;
cin >> N;
if (N == NUMBER1 || N == NUMBER2 || N == NUMBER3) {
vector<int> array;
array = shufflingRandomCreator(array, N);
cout << "<<<
>>> \n";
selectionSort(array, N);
cout << "\n<<<
>>> \n";
bubbleSort(array, N);
cout << "\n<<<
>>> \n";
insertionSort(array, N);
데이터의 개수
선택 정렬
버블 정렬
삽입 정렬
array = shufflingRandomCreator(array, N);
clock_t start = clock(); // start
cout << "\n<<<
>>> \n";
mergeSort(array, 0, N);
clock_t finish = clock(); // end
caltime(start, finish);
병합 정렬
array = shufflingRandomCreator(array, N);
start = clock(); // start
cout << "\n<<<
>>> \n";
quickSort(array, 0, N);
finish = clock(); // end
caltime(start, finish);
퀵 정렬
array = shufflingRandomCreator(array, N);
start = clock();
cout << "\n<<<STL
>>> \n";
sort(array.begin(), array.end());
finish = clock();
caltime(start, finish);
break;
정렬
}
else {
cout << "
}
입력 실패, 입력값은 500 or 5000 or 50000 이여야 합니다.\n";
}
return 0;
}
Notion Link
https://juniper-sale-45c.notion.site/3-8cbb0f7963c14781a83fbe76c5e038f8
과제3
6
Download