00. 배열 | 큐 | 스택
📌 배열 (Array)
정의
데이터를 나열하고, 각 데이터를 인덱스에 대응하도록 구상한 데이터 구조
배열이 왜 필요할까 ?
- 같은 종류의 데이터를 효율적으로 관리하기 위해 사용
- 같은 종류의 데이터를 순차적으로 저장 (인덱스가 존재)
- 문자열과 같은 경우 순차적으로 저장되어 있어야 효율적으로 관리 될 수 있다

- 인덱스를 통해서 연결된 데이터의 일부분을 바로 접근할 수 있다
장점
빠른 접근 가능
: 배열의 첫번째 위치만 알면 인덱스를 통해 몇번째 만큼 떨어진 곳으로 바로 접근 가능

단점
추가 / 삭제가 쉽지 않다
삭제하는 경우 필요없는 공간을 가지고 있어야 한다
미리 최대의 길이를 지정해야 한다
고정된 길이 <-> 가변적
`JAVA` 라는 문자열을 저장하기 위해 미리 4정도의 크기를 갖는 배열을 생성해놓아야 한다

배열은 추가가 되지 않기 때문에 새로운 배열을 만든 후 기존 배열값을 넣어준 뒤 값을 새로 넣어주어야 한다

// 배열을 잘라내는 Arrays 클래스가 존재한다 (기존 배열의 필요한 부분을 잘라 새로운 배열을 만드는 원리) Arrays.copyOfRange(배열, 시작 인덱스, 종료 인덱스)
📌 큐 (Queue)
정의
- 가장 먼저 넣은 데이터를 가장 먼저 꺼낼 수 있는 구조
- 예시) 음식점에서 가장 먼저 줄을 선 사람이 제일 먼저 음식점에 입장하는 것과 동일
- FIFO (First In First Out) 구조
- 스택과 반대되는 구조이다 ( 스택은 FILO 구조 )
사용되는 용어
- Enqueue : 큐에 데이터를 넣는 기능
- Dequeue : 큐에 데이터를 꺼내는 기능
종류
- Queue : 가장 일반적인 큐 자료구조
- Lifo Queue : 나중에 입력된 데이터가 먼저 출력되는 구조 (스택구조와 같음 FILO)
- Priority Queue : 데이터 마다 우선순위를 넣어서 우선순위가 높은 순으로 데이터 출력
어디에 많이 쓰일까 ?
- 멀티 태스킹을 위한 프로세스 스케줄링 방식을 구현하기 위해 많이 사용됨 (운영체제 참고)
> 큐의 경우에는 장단점보다는 특별히 언급되는 장단점이 없음
- 큐의 활용 예로 프로세스 스케줄링 방식을 함께 이해해두는 것이 좋다

📌 스택 (Stack)
정의
- 데이터를 제한적으로 접근할 수 있는 구조
- 한 쪽 끝에서만 자료를 넣거나 빼낼 수 있는 구조
- 가장 나중에 쌓은 데이터를 가장 먼저 빼낼 수 있는 구조
- LIFO 구조
- 대표적인 스택의 활용으로 컴퓨터 내부의 프로세스 구조의 함수 동작 방식이다

주요 기능
- push : 데이터를 스택에 넣기
- pop : 데이터를 스택에서 꺼내기
스택구조와 프로세스 스택
- 스택구조는 프로세스 실행 구조의 가장 기본적으로 사용된다
- 함수 호출 시 실행 구조를 스택과 비교해서 이해필요
- 참고) 프로그램이 실행되는 상태를 프로세스 라고 한다

function recursive(num) { if (num < 0) console.log('ended') else { console.log(num) recursive(num-1) console.log('returned num') } } recursive(4)
장점
구조가 단순해서 구현이 쉽다
(구조가 단순하기 때문에 일반적으로) 데이터 저장/읽기 속도가 빠르다
- 일반적으로 그렇지 구현 로직을 다르게 하면 빠르지 않을 수 도 있다
단점
데이터 최대 갯수를 미리 정해야 한다
- 재귀함수 사용할 수 있는 크기는 다 정해져있어서 특정 크기를 넘어가면 에러가 발생한다
- 구현을 다르게 하면 최대 갯수를 지정할 필요는 없기도 함
(최대 갯수를 미리 정해야 하기 때문에) 저장 공간의 낭비가 발생할 수 있다
- 최대 갯수만큼 함수를 모두 작성하지 않기 때문
- 1000번의 크기 함수를 만들어놨지만, 해당 재귀함수는 2번만 끝나는 경우 998개의 저장공간 낭비가 발생
- 스택은 단순하고 빠른 성능을 위해 사용되므로, 보통 배열구조를 활용해서 구현하는 것이 일반적임
이 경우 위에서 배열의 특징때문에 위에서 열거한 단점을 갖고 있는 것
(배열은 크기를 지정해야하고 가변적으로 크기를 늘리기 어렵기 때문)
'25. 자료 구조와 알고리즘 > 나의 알고리즘' 카테고리의 다른 글
08. 동적 계획법 (Dynamic Programing) 과 분할정복 (Divide and Conquer) (0) | 2021.09.21 |
---|---|
11. 이진 탐색 (Binary Search) (0) | 2021.09.21 |
10. 병합정렬 (Merge Sort) (0) | 2021.09.17 |
09. 퀵 정렬 (Quick Sort) (0) | 2021.09.16 |
07. 재귀함수 (Recursive Call) - 경우의 수 구하기 (0) | 2021.09.16 |
댓글
이 글 공유하기
다른 글
-
08. 동적 계획법 (Dynamic Programing) 과 분할정복 (Divide and Conquer)
08. 동적 계획법 (Dynamic Programing) 과 분할정복 (Divide and Conquer)
2021.09.21동적 계획법 (Dynamic Programing, DP) - 입력 크기가 작은 부분 문제들을 해결한 후, 해당 부분문제의 해를 재활용해서 보다 큰 크기의 부분문제를 해결 최종적으로 전체 문제를 해결하는 알고리즘 - 상향식 접근법으로 가장 최하위의 해답을 구한 후 이를 저장하고, 해당 결과값을 이용해서 상위문제를 풀어나가는 방식 - Memorization (메모제이션) 이란 프로그램 실행 시 이전에 계산한 값을 저장하여 다시 계산하지 않도록 하여 전체 실행속도를 빠르게 하는 기술 - 문제를 잘게 쪼갤 때, 부분문제는 중복되는 경우 재활용 된다 - 예) 피보나치 수열 * 요약 1. 작은 문제 부터 먼저 해결하여 값을 저장한다. 2. 점차 큰 크기의 문제 부분을 해결하는 데 중복된 작은 문제는 계산하지 않고 … -
11. 이진 탐색 (Binary Search)
11. 이진 탐색 (Binary Search)
2021.09.21이 글은 보호되어 있습니다. -
10. 병합정렬 (Merge Sort)
10. 병합정렬 (Merge Sort)
2021.09.17병합정렬 (Merge Sort) public class MergeSort { public static void main(String[] args) { int[] numArr = {4, 1, 7, 3, 2, 8, 6}; int[] results = mergeSplit(numArr); System.out.println(Arrays.toString(results)); } private static int[] mergeSplit(int[] arr) { // 길이가 1개 이하 인 경우 return arr if (arr.length lp && right.length > rp) { // 왼쪽 배열의 크기 보다 lp 가 작은 경우 and 오른쪽 배열 크기 보다 rp 가 작은 경우 if (left[lp] > right[… -
09. 퀵 정렬 (Quick Sort)
09. 퀵 정렬 (Quick Sort)
2021.09.16정의 - 정렬 알고리즘의 꽃 - 기준점(Pivot) 을 정해서, 기준점보다 작은 데이터는 왼쪽(left) 큰 데이터는 오른쪽(right)으로 모으는 함수 - 각 왼쪽 (left), 오른쪽 (right) 는 재귀용법을 사용해서 다시 동일함수를 호출하여 위 작업을 반복한다 - 함수는 왼쪽 (left) + 기준점 (pivot) + 오른쪽 (right) 을 리턴한다 - 왼쪽 퀵 정렬 일 때 0번째가 가장 작은 수 일 경우 최악의 성능이 나옴 (빠르긴 하나, 상황에 따라 성능이 차이가 날 수 있기 때문에 안정적이지 않은 편이다. 그 에 비해 같은 분할정복의 정렬 중 병합 정렬은 항상 동일한 성능을 가지고 있어 안정적이고 퀵 정렬보다는 아니지만 그에 준수 한 속도를 가지고 있다) 분석 - 병합정렬 (Merge So…
댓글을 사용할 수 없습니다.