이 포스트를 통해 같은 RDBMS인 Oracle(오라클)과 MySQL의 대표적인 문법 차이를 알아보자 
기능
Oracle
MySQL
공백 치환 함수
NVL('컬럼명', '')
IFNULL('컬럼명', '')
현재 날짜 및 시간
sysdate
now()
날짜 Format
to_char(sysdate, 'MMDDYYYYHH24MISS')
date_format(now(), '%Y%m%d%H%i%s')
요일 관련 날짜 Format
요일을 1 ~ 7 로 인식
to_char(sysdate -1, 'D')
요일을 0 ~ 6 로 인식
date_format(date_sub(now(), interval 1 day, '%w')
Like 절 '%' 사용
Like '%' || '문자' || '%' 이런 식으로 컬럼명 앞뒤로 '%' 사용
Like concat('문자', '%') 이런식으로 concat 사용
형 변환
to_char, to_number
cast
대소문자 구분
구분 없이 사용.
기본적으로 구분하지만 설정에서 변경 가능.
rownum
where 절에서 rownum > 5 and rownum =< 15
where 절을 허용하지 않고 limit 5, 15
문자열 자르기
substr(문자열, 1, 3)
substring(문자열, 1, 3),
left(문자열, 3)
right(문자열, 3)
시퀀스(사용자 함수를 만들어서 사용)
시퀀스명.nextval
시퀀스명.currval
문자열 병합
문자열 (또는 컬럼) || '병합할 문자'
concat(문자열 (또는 컬럼), '병합할 문자')
예약어가 컬럼명일 경우
컬럼명을 ""로 감싸기
"column"
컬럼명을 Tab 키  위에 있는 `로 감싸기
저장 프로시저의 여부를 파악하여 create
create or replace procedure 프로시저명
drop procedure if exists 프로시저명; 을 한 뒤 create procedure 프로시저명
 
AndroidManifest.xml

안드로이드 시스템이 앱의 코드를 실행하기 전에 확보해야하는 앱에 대한 필수 정보를 시스템에 제공하는 목록(빌드 툴, OS, 구글 플레이에 제공)

 

AndroidManifest.xml안의 내용

?xml version="1.0" encoding="utf-8"? : 이 문장은 이 파일이 XML 문서임을 선언하여 version과 인코딩 방식을 알려준다.

package='com.example'project_name' : 이 정보로 앱을 식별한다.

android:icon = '@mipmap/ic_launcher' : 전체 애플리케이션의 아이콘 및 애플리케이션의 각 구성요소의 기본 아이콘

android:lable '@string/app_name' : 전체 애플리케이션을 나타내는 즉, 사용자가 읽을 수 있는 기본 라벨

activity : 앱에 액티비티 컴포넌트를 등록하기 위한 태그.

intent-filter : 다른 앱에서 본인앱으로 접근하거나, 본인 앱에서 다른 앱으로 접근하기 위한 필터.

action : 인텐트 필터에 작업을 추가하는 태그. 인텐트 필터에 action 태그가 없으면 필터가 intent 객체를 허용하지 않는다.

category : 인텐트 필터에 카테코리 이름을 추가한다.

data : 데이터 사양을 인텐트 필터에 추가한다.

'개념' 카테고리의 다른 글

RESTFUL(restful)(RESTful) API가 무엇일까?  (0) 2022.06.17
Oracle(오라클)과 MySQL 문법 비교  (0) 2022.06.17
Proguard(프로가드)란?  (0) 2022.06.17
Gradle(그래들)이란 무엇일까?  (0) 2022.06.17
CDN이란?  (0) 2022.06.17

Flutter

플러터(Flutter)란 무엇인가?

단일 코드베이스로 모바일(Android, IOS) 개발, 웹 개발, 데스크탑 개발, 임베디드 개발등이 가능한 크로스 플랫폼이다.

Google에서 개발하고 있는 장차 Fuchsia OS 위에서 UI / UX를 담당하게 될  오픈소스 프레임워크이다.

구글에 맞춘 Meterial 디자인과 애플에 맞춘 Cupertino 디자인도 가능하다.

 

왜 크로스 플랫폼을 선택해야하는가?

사용하기에 앞서 각 플랫폼별 native 언어가 있는데 불구하고 크로스 플랫폼을 선택을 왜 하는지에 의문이 있을 것이다.

 

ex) 현재 native 개발자인데 크로스 플랫폼을 사용해도 생산성 차이가 없을 것 같다 등

답 : NAVER 지식IN 개발 후기를 보면 알 수 있듯이 기존 native 개발과 크로스 플랫폼으로 따로 같은 개발을 해봤을 시 생산성이 3~5배로 차이가 날 정도로 좋다. 물론 개인마다 차이가 있겠지만 최소 1.5배 ~ 2배 차이가 나면서 멀티 플랫폼 개발을 한번에 하는게 압도적인 생산성 차이가 난다고 생각한다.

 

ex) 크로스 플랫폼으로 개발을 해도 결국 native로 변경해야하는 것 아닌가? 등

답 : Computing이나 민감한 디바이스의 특정 기능을 요구하는 것이 아니므로 반드시 native가 필수일 필요는 없다. 즉, 처음 모바일 설계를 할 시 구분을 하고 넘어가야한다 대부분의 모바일 앱은 Computing이나 민감한 디바이스의 특정 기능을 요구하지 않으며 사용한다고 하면 크로스 플랫폼을 선택하지 않는게 맞기 때문이다.

 

ex) native에서 되는게 크로스 플랫폼에서 개발 안되는 것 아닌가? 등

답 : 현재 대부분의 기능을 플러그인을 통해 구현이 되어있으며 점차 더 개발될 것이기 때문에 걱정할 필요는 없다고 생각한다.

 

플러터(Fluter) vs 리액티브 네이티브(Reactive Native) 비교

플러터(Flutter)

장점

- 리액티브 네이티브(Reactive Native)처럼 Bridge를 거치지 않고 각 플랫폼에 맞는 native 언어로 컴파일된 후바로 Skia엔진을 통해  canvas에 렌더링하기 때문에 각 플랫폼의 native 언어와 비슷한 수준의 성능을 보여준다.

- 리액티브 네이티브(Reactive Native)의 인기를 쉽게 따라잡았으며 인기의 추세가 더 크다.

 

단점

- 리액티브 네이티브(Reactive Native)보다 구직하기 어렵다. (채용사이트 구인 게시글 수를 비교하였을 때)

 

리액티브 네이티브(Reactive Native)

장점

- 기존 React 개발자이면 빠르게 학습하여 모바일 개발이 가능하다.

- 플러터(Flutter)보다 구직하기가 더 쉽다. (채용사이트 구인 게시글 수를 비교하였을 때)

 

단점

- Bridge를 사용하여 플러터(Flutter)보다 렌더링 성능이 떨어진다.

 

개발 특징

1. Hot Reload(핫 리로드) : 모바일 앱이 실행되고 있는 상태에서, 앱의 상태를 유지한 채로 변경사항을 적용시켜 주어 빠른 개발을 할 수 있다.

 

2. Hot Restrat(핫 리스타트) : 모바일 앱이 실행되고 있는 상태에서, 변경사항을 적용시켜준다. 단, 앱의 상태는 초기화 된다. Hot Reload(핫 리로드)보다는 시간이 조금 더 걸리지만, 앱을 재실행하는 것보다는 훨씬 빠르게 변경사항을 확인할 수 있다.

 

기존 Native의 명령형 스타일 -> 선언형 스타일로 하게 되어 개발하기 더 쉽다.

// 명령형 스타일
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
// 선언형 스타일
return ViewB(
  color: red,
  child: ViewC(...),
)

 

플러터(Flutter)로 만들어진 기업 어플리케이션
  • 네이버 지식IN
  • GS SHOP
  • Google AdSense, Google Assistant, Google Pay
  • BMW
  • Toyota
  • Alibaba
  • Tencent

ios simulator를 이용하여 애플 관련 개발을 진행할 경우 위의 제목과 같이 로그인을 진행 했음에도 불구하고 경고창이 나오면서

 

더 이상 진행이 되지 않는 경우가 있다 이럴 경우 icloud.com에 들어가 개발을 진행할 계정으로 로그인 후 사용자 약관 동의 후 

 

ios simulator에서 setting으로 들어가 로그인 후 다시 개발하고자 하는 어플에 들어가 진행하면 된다.

Proguard

소스 코드 난독화 및 앱의 용량을 줄여주는(필요하지 않는 멀티덱스를 제거) 프로그램이다. 소스 코드가 노출되면 안 되는 앱이나, 용량이 큰 앱에 적용하는데에 사용한다. GPL 라이센스를 갖고 있으며 어떠한 제약 조건 없이 사용할 수 있는게 특징이다.

 

멀티덱스

안드로이드 앱을 구성하는 코드는 컴파일 되어 덱스(dex) 파일로 만들어지는데 하나의 덱스(dex) 파일에는 최대 65536개의 메소드만 참조 가능하다. 만약 프로젝트의 코드가 65536개의 메소드를 초과하게 되면 덱스(dex) 파일이 여러개가 생성된다.

 그러면 멀티 덱스를 사용하여 컴파일 가능하지만, 빌드 과정에서 앱 내의 파일을 여러개의 덱스(dex)파일로 나누어야 하므로 빌드 속도가 느려지고 APK 파일의 용량이 커지게 되므로 프로가드를 통해 최적화 시켜주는게 좋다.

Gradle이란?

Gradle은 그루비(Groovy)를 기반으로 한 빌드 도구이다. Ant와 Maven과 같은 이전 세대 빌드 도구들의 단점을 보완하고 장점을 취합하여 만든 오픈소스 빌드 도구이다.

 

Ant
  • XML 기반으로 빌드 스크립트를 작성한다.
  • 간단하고 사용하기 쉽다.
  • 유연하지만 프로젝트가 커지는 경우 스크립트 관리나 빌드 과정이 복잡해진다.
  • 생명주기를 갖지 않아 각각의 결과물에 대한 의존관계 등을 정의해야 한다.
Maven
  • XML 기반으로 작성한다.
  • 생명주기와 프로젝트 객체 모델이란 개념을 사용한다.
  • pom.xml에 필요한 라이브러리를 작성하면 자동으로 해당 프로젝트로 불러와 편리하다.
  • 학습 장벽이 높다.
  • 라이브러리가 서로 의존하는 경우 복잡해진다.
Gradle
  • 의존성 관리를 위한 다양한 방법을 제공한다.
  • 빌드 스크립트를 XML 언어가 아닌 JVM에 동작하는 스크립트 언어 '그루비(Groovy) 기반의 DSL(Domain Specific Language)를  사용한다.
  • 그루비(Groovy)는 자바 문법과 유사하여 쉽게 배울 수 있으며 Gradle Wrapper를 이용하면 Gradle이 설치되지 않은 시스템에서도 프로젝트를 빌드할 수 있다.
  • Maven의 pom.xml을 Gradle 용으로 변환 가능하며 Maven의 중앙 저장소도 지원하기 때문에 라이브러리를 모두 그대로 가져다 사용 가능하다.
Gradle 기본 구조
디렉토리 / 파일 설명
/.gradle
/gradle
gradle 버전별 엔진 및 설정 파일
/.idea 에디터 관련 파일들
/gradlew Unix용 실행 스크립트
/gradlew.bat Windows용 실행 스크립트
/settings.gradle 빌드할 프로젝트 정보 설정
wrapper/gradle-wrapper.jar Wrapper파일
wrapper/gradle-wrapper.properties Gradle Wrapper 설정 파일
/build.gradle 프로젝트 빌드에 대한 모든 기능 정의

 

Gradle Build Lifecycle
  1. 초기화 (Initialization) : 빌드 대상 프로젝트를 결정하고 각각에 대한 프로젝트 객체를 생성. settings.gradle 파일에서 프로젝트를 구성한다. (멀티프로젝트, 싱글프로젝트 구분)
  2. 구성 (Configuration) : 빌드 대상이 되는 모든 프로젝트의 빌드 스크립트를 실행한다. (프로젝트 객체 구성)
  3. 실행 (Execution) : 구성 단계에서 생성하고 설정된 프로젝트의 태스크 중에 실행 대상 결정. gradle 명령행에서 지정한 태스크 이름 인자와 현재 디렉토리를 기반으로 태스크를 결정하여 선택된 태스크들을 실행.
Build 설정파일
  • build.gradle : 빌드에 대한 모든 기능을 정의
  • settings.gradle : 프로젝트 구성을 설정 (싱글프로젝트의 경우 생략이 가능하다)(Gradle은 멀티프로젝트를 구성하여 프로젝트간의 의존성 및 서브프로젝트를 구성할 수 있다)

'개념' 카테고리의 다른 글

RESTFUL(restful)(RESTful) API가 무엇일까?  (0) 2022.06.17
Oracle(오라클)과 MySQL 문법 비교  (0) 2022.06.17
AndroidManifest.xml(안드로이드매니페스트)이란?  (0) 2022.06.17
Proguard(프로가드)란?  (0) 2022.06.17
CDN이란?  (0) 2022.06.17
CDN이란?

CDN(Content Delivery Network)(콘텐츠 전송 네트워크)는 사용자와 가까운 곳에서 콘텐츠를 전송함으로써 더 빠르고 안정적인 서비스를 제공하는 것이다.

 

지리적으로 분산된 여러 개의 서버로, 콘텐츠를 사용자와 가까운 서버에서 전송함으로써 전송 속도를 높인다.

 

전 세계 데이터센터는 파일 복사본을 임시로 저장하는 캐싱을 사용하는데 따라서 사용자는 가까운 서버에 접속할 수 있다.

 

웹 페이지, 이미지, 비디오 등의 콘텐츠를 가까운 물리적 위치의 서버에 캐싱한다.

 

CDN의 원리를 보면 알 수 있듯이 프로식 서버의 한 종류인 Reverse Proxy로 동작하는 캐시 서버이다.

 

CDN을 사용하는 이유?
  1. 물리적 거리 : 사용자와 가까운 서버에서 통신을 하므로 콘텐츠 제공 속도가 빠르다.
  2. 부하분산 : 일반 서버만 사용할 경우 트래픽이 갑자기 급증하거나 컨텐츠양이 증가하는 경우 부하가 집중되어 장애가 발생할 가능성이 있는데 CDN 도입을 통해 일반 서버의 부하를 줄일 수 있다.

 

CDN의 장점
  1. 비용 절감 : 본 서버로 직접 요청되지 않기 때문에 대역폭 비용이 크게 절감된다. 즉, 호스팅 비용이 절감된다.
  2. 가용성과 안정성 증가 : 본 서버의 부담이 덜어져 과부하로 인한 오류가 줄어들어 안정적인 서비스 제공 가능.
  3. 보안 : 일반 서버만 이용할때 보다 DDos로 인한 서버 다운에 더 강하며 CDN 서버에서 정상적인 요청과 비정상적인 요청을 구분해내어 요청수를 제한하거나 집중된 요청을 분산가능하다.

 

CDN 캐싱 방식
  1. Static Caching(정적 캐싱) : 본 서버에 있는 콘텐츠를 CDN서버에 미리 캐싱 해두어 사용자가 빠르게 접근 가능한 방법.
  2. Dynamic Caching(동적 캐싱) : 미리 CDN 서버에 캐싱하지 않고 사용자가 콘텐츠 요구 시 해당 콘텐츠가 CDN 서버에 없는 경우 본 서버에서 다운로드 받아 전달하고 있는 경우 CDN 서버에서 컨텐츠 전달을 한다. 일정 시간 이후 CDN 서버에서 캐싱 콘텐츠가 삭제될 수 있다. (이 점이 차이점)
연결리스트란?

연결리스트란 여러개의 노드를 연결함으로써 데이터를 보관하는 자료구조로 노드는 데이터를 가진 data 부분과 다음 노드를 연결하는 

link 부분으로 나뉘어져 있다.

 

연결리스트의 장점
  1. 배열과는 다르게 필요한 만큼 메모리를 동적으로 할당 받아서 사용한다. 즉, 데이터 삽입 시에만 메모리 추가 사용하므로 효율적.
  2. 삽입 삭제가 간단하다 : 새로운 노드 삽입 삭제 시 포인터 값(link)만 변경해주면 되기 때문이다.

 

연결리스트의 단점
  1. 노드 접근이 배열보다 오래 걸린다 : 첫 노드부터 순차적으로 접근해야하기 때문이다. 메모리 구조상 차이.
  2. 물리적으로 인접한 메모리에 위치해있지 않다 : 배열과 달리 포인터로 다음 노드의 위치를 알 수 있으므로 메모리 주소 공간이 떨어져있다.
  3. 참조 포인터를 위한 메모리 공간이 낭비된다.

 

연결리스트의 시간복잡도
접근 탐색 삽입 삭제
O(n) O(n) O(1) O(1)

※ 중간 삭제 삽입 시 해당 위치의 전과 후의 데이터에 접근해야하고 작업을 해야하므로 O(n + 1)이 걸린다. 위의 삽입 삭제 상수시간은 접근을 고려하지 않고 삽입 삭제만 봤을 때의 시간이다.

 

연결리스트의 종류
  1. 단일 연결리스트 : 가장 기본적인 연결리스트로 마지막 노드는 가리키는 노드가 없다. 보통 스택 구현에 많이 사용. 마지막 노드가 null을 가르킨다.
  2. 이중 연결리스트 : 노드를 연결하는 link가 앞 뒤로 존재해서 앞 뒤 노드들 간의 관계를 바로 알 수 있다. 보통 큐 구현에 많이 사용. 단일 연결리스트는 헤드노드 유실시 전체 자료를 다 잃어버리지만 이중 연결리스트는 헤드만 아닌 테일 노드도 가지고 있으면 복구가 가능하다 또한 단일 연결리스트는 헤드에서만 탐색이 가능하나 이중 연결리스트는 테일에서도 탐색이 가능하므로 탐색의 방향이 바뀌어야 하는 경우 사용한다. 현실에서 사용하는 연결 리스트는 대부분 이중 연결리스트라고 보면 된다.
  3. 원형 연결리스트 : 마지막 노드가 다시 처음 노드를 가리키는 연결리스트. 헤드와 테일의 구분이 없다. 스트림 버퍼의 구현에 많이 사용.

※ 물론 위의 연결리스트 구현될 수 있다는 스택, 큐 등 자료구조는 배열로도 큐를 단일 연결리스트로도 구현 가능하다 해당 자료구조만큼보다는 조금 비효율적이다라는 것이다.

 

배열과 연결리스트 사용 의문과 결론

동적배열과 연결리스트의 이 2개의 글을 읽어보셨으면 아시겠지만 결국 시간복잡도만 봤을 때 배열과 연결리스트는 데이터 접근과 탐색(탐색은 빅오 표기법은 같으나 메모리를 생각했을 때 조금의 차이)을 제외하면 별 다른 점이 없다. 

 

결국 자료구조의 설계를 기준으로 결정해야하는데 연결리스트는 마지막 노드에 한 해 데이터 추가 삭제 시 상수 시간이 걸리는 점을 생각 동적 배열은 마지막에 데이터를 추가 삭제 시 분할 상환할 경우에 상수 시간이 걸리다는 점과 데이터의 접근과 탐색을 생각하면 될 것 같다.

또한 보통 개발자가 배우기를 연결리스트는 삽입, 삭제에 유리, 배열은 접근 탐색에 유리하다는 것을 알고있다는 점도 반영.

 

결론은 데이터 접근, 탐색이 중요하면 배열을 사용. 데이터의 추가 삭제가 중요하면 연결리스트를 사용.

 

하지만 실무에서는 대부분 동적배열을 애용한다?!

 

 

 

 

'자료구조' 카테고리의 다른 글

Deque란?  (0) 2022.06.27
Queue란?  (0) 2022.06.27
Stack이란?  (0) 2022.06.27
배열이란? (Array와 ArrayList의 차이)  (0) 2022.06.09
배열이란?

배열이란 연관된 데이터를 하나의 변수에 그룹핑해서 관리하기 위한 방법이다. 

 

즉, 배열은 하나의 변수에 여러 정보를 담을 수 있어 많은 정보를 효율적으로 처리할 수 있는 자료구조이다.

 

 

배열의 장점
  1. 검색 성능이 좋다 : 인덱스를 이용한 무작위 접근이 가능하므로 빠르다.
  2. 순차 접근의 경우에도 데이터를 하나의 연속된 메모리 공간에 할당하므로 연결 리스트보다 빠르다.

 

배열의 단점
  1. 자료의 삽입과 삭제에 비효율적이다 : 항목의 모든 요소를 이동시켜야해서 비효율적.
  2. 메모리 공간 낭비 : 배열은 메모리를 할당 받아 사용하기 때문에 데이터의 존재 유무와 상관없이 일정한 크기의 공간을 점유하고 있기 때문에 데이터를 삭제하더라도 배열 자체를 제거하지 않은 이상 낭비를 유발한다.

 

배열의 시간복잡도
접근 검색 입력 삭제
O(1) O(n) O(n) O(n)

※ 배열의 마지막 원소에 삽입, 삭제 삽입은 당연히 간단하게 끝내지만 (상수 시간) 아닌 경우. 즉, 시간 복잡도의 평균과 최악을 가정하여O(n)이라고 생각하면 될 것 같습니다.

 

Array과 ArrayList의 차이점

Array

- 통상적으로 말하는 자료구조 상의 배열.

- 고정 배열.

- 배열의 크기를 지정하며 그 크기 이상 데이터 삽입 시 불가.

- 배열의 사용하지 않는 인덱스가 있더라도 고정 크기이므로 메모리 낭비.

 

ArrayList

- 동적 배열.

- 자동적으로 크기가 지정되며 그 크기 이상 데이터 삽입 시 원래 크기의 1.5 ~ 2배 사이즈로 크기가 확장되며 삽입 가능.

- 배열의 사용하지 않는 인덱스가 있을 시 크기가 줄어들며 만약 인덱스 1의 데이터를 삭제 시 고정 배열은 1에 접근하였을 때 데이터가 
없지만 동적 배열은 1에 접근하였을 때 2에 있던 데이터가 1로 가있어 데이터가 있다.

- Hash Map, Dictionary, Linked List로 구현되어 있다.

 

코드 예시
// 자바스크립트의 배열은 다른 데이터 타입을 배열안에 같이 넣을 수 있다.
// 다트의 배열은 타입 지정이 없을 시 다른 데이터 타입을 배열안에 같이 넣을 수 있다.

javascript

고정 배열
1. let arr = new Array(3);

동적 배열
1. let arr = [];
2. let arr new Array();

 

'자료구조' 카테고리의 다른 글

Deque란?  (0) 2022.06.27
Queue란?  (0) 2022.06.27
Stack이란?  (0) 2022.06.27
연결리스트란? (단일 연결리스트, 이중 연결리스트, 원형 연결리스트)  (0) 2022.06.09

1. 알고리즘별 정의, 장점, 단점 정리

종류 정의 장점 단점 이용
버블 정렬(Bubble Sort) 첫 번째 원소부터 인접한 원소끼리 계속 자리를 교환하면 맨 끝까지 정렬하는 방식 구현이 간단
코드가 직관
정렬 시간이 오래 걸림 이미 정렬된 데이터를 정렬 시에 빠르다(반대로 역순 배열은 가장 느림)
선택 정렬(Selection Sort) 최소 값을 찾고 그 값을 맨 앞에 위치한 값과 교체하는 방식(반복) 구현이 간단
비교하는 횟수에 비해 교환이 적게 일어남 
버블 정렬보다 빠름
정렬 시간이 오래 걸림 많은 교환이 일어나야 하는 자료 상태에서 비교적 효율적(역순 정렬)
이미 정렬된 상태에서 소수의 자료가 추가됨으로 재정렬할 시 최악
삽입 정렬(Insertion Sort) 자료 배열의 모든 요소를 앞에서부터 차례대로 이미 정렬된 배열 부분과 비교하여 자신위 위치를 찾아 삽입하는 방식 최선의 경우 O(N)으로 정렬 가능 최악의 경우 O(N^2)이 걸림 다른 정렬 알고리즘의 일부로 쓰임
이미 정렬된 경우 아주 최고의 정렬 알고리즘(탐색을 제외한 오버헤드가 매우 적음)
합병 정렬(Merge Sort) 작은 단위로 잘게 쪼개어 작은 단위부터 정렬해서 정렬된 단위들을 계속 병합해가면서 정렬하는 방식 항상 O(NlogN)으로 일정한 속도로 정렬 추가적인 메모리 공간 필요(임시 배열에 원본 맵을 계속해서 옮겨주면서 정렬하는 방법) 순차적인 비교로 정렬하기에 LinkedList의 정렬에 사용하면 효율적
크기가 큰 레코드 정렬 시 효율적
퀵 정렬(Quick Sort) Pivot을 정하여 이 축의 값보다 작은 값은 왼쪽에 큰 값은 오른쪽으로 위치시킨뒤 왼쪽과 오른쪽의 수들을 다시 각각의 축으로 나누어져 축 값이 가장 작은 값이 될 때까지 정렬 평균 실행시간 O(NlogN)으로 빠른 편 Pivot에 따라 성능 차이가 심함
최악의 경우 O(N^2)이 걸림
순차 접근이 아닌 임의 접근이기에 LinkedList를 퀵 정렬에 사용하면 성능이 좋지 않다
힙 정렬(Heap Sort) 최대 힙을 만들고 루트 노드를 던지고 마지막 노드를 루트 노드 위치에 넣고 다시 최대 힙 만들기를 반복 항상 O(NlogN)으로 빠른 편 다른 O(NlogN)의 정렬법보다 오래 걸림

가장 크거나 가장 작은 값을 구할 때
최대 K만큼 떨어진 요소들을 구할 때 : 삽입 정렬을 개선
쉘 정렬(Shell Sort) 삽입정렬의 개념을 확대하여 일반화한 정렬방법 O(NlogN)의 정렬법보다 빠름 설정 간격에 따라 성능 차이가 심함 삽입 정렬을 보안한 알고리즘으로 삽입 정렬 시 삽입되어야할 위치가 현재 위치에서 상당히 멀리 떨이진 곳에 정렬을 해야만 하는 경우 쉘 정렬 사용
기수 정렬(Radix Sort) 데이터의 비교를 통한 정렬이 아닌 분산 정렬을 이용한 정렬 방법으로 자릿수가 있는 데이터(정수, 문자열 등)에만 사용 가능 O(N) 속도로 굉장히 빨리 정렬 가능 '버킷'이라는 추가적인 메모리가 할당되어야 한다. 즉, 메모리가 생각보다 많이 소비
데이터 타입이 항상 일정해야함
구현을 위한 조건이 많이 붙음
자릿수가 있는 데이터를 정렬할 경우
계수 정렬(Counting Sort) 비교하지 않는 정렬로 정렬하기 위한 요소들이 몇 개씩 있는지 세어서 적절한 위치에 선형 시간에 정렬하는 방법 적은 개수의 숫자를 정렬할 때 빠름 추가적인 메모리(숫자 개수를 저장할 공간, 결과를 저장할 공간)가 필요
가장 큰 숫자에 영향을 받는다는 점
특정 범위내에서 반복되는 정수인 많은 데이터의 경우에 효율적 (만약 데이터의 특성을 파악하기 어렵다면 퀵 정렬을 이용하는 것이 유리)

 

2. 알고리즘별 시간복잡도 및 공간 복잡도

종류 평균  최선 최악  공간 복잡도
버블 정렬(Bubble Sort) O(N^2) O(N^2) O(N^2) O(N^2)
선택 정렬(Selection Sort) O(N^2) O(N^2) O(N^2) O(N)
삽입 정렬(Insertion Sort) O(N^2) O(N) O(N^2) O(N^2)
합병 정렬(Merge Sort) O(NlogN) O(NlogN) O(NlogN) O(NlogN)
퀵 정렬(Quick Sort) O(NlogN) O(NlogN) O(N^2) O(NlogN)
힙 정렬(Heap Sort) O(NlogN) O(NlogN) O(NlogN) O(NlogN)
쉘 정렬(Shell Sort) O(N^1.25) O(N^1.25) O(N^1.25) O(N)
기수 정렬(Radix Sort) O(dN) / d는 최대값의 자릿수 O(dN) O(dN) O(N)
계수 정렬(Counting Sort) O(N+k) O(N+k) O(N+k) O(K) / K는 K 크기만큼의 배열을 만들어야 한다는 뜻

 

ETC

  • 추가적인 메모리 할당이 불가능한 경우 병합 vs 큌 : 데이터가 최악인 것만 본다면 퀵 보다 병합 정렬이 훨씬 빠르지만 추가 메모리 할당이 없다면 병합 정렬은 사용 불가이기에 퀵을 써야한다
  • 안정 정렬 : 중복된 값을 입력 순서와 동일하게 정렬하는 특성 ex) 삽입 정렬, 버블 정렬, 합병 정렬, 계수 정렬
  • 불안정 정렬 : 중복된 값이 입력 순서와 동일하지 않게 정렬되는 특성 ex) 선택 정렬, 퀵 정렬, 힙 정렬
  • 기본으로 탑재 되어있는 언어의 라이브러리 중 정렬은 시간 복잡도가 보통 NlogN으로 잘 판단하여 사용할 것.

+ Recent posts