란?

- FIFO (First in First Out) 방식으로 데이터를 입출력

- 현실 세계의 큐 예 )

    티켓 판매기에서 대기하고 있는 사람들,

    일방통행 도로의 차동자들, 인쇄기의 인쇄 순서, CPU의 테스크 스케줄링

- 큐의 한계 :

  1) front부터 삭제되며, 삭제된 공간을 다시는 사용하지 못한다. 

  2) (배열을 사용할 경우) 큐의 크기가 정해지기 때문에 rear가 더 움직이지 못한다.

     (-> 이 부분은 자바에서는 동적관리 객체인 LinkedList로 해결했다)

- 큐의 한계를 보완 : 원형 큐, 우선순위 큐

 

큐의 내부 구조

- 유투브의 영상에 나와있는 튜토리얼에 따라 큐를 구현해보았다. 

https://www.youtube.com/watch?v=W3jNbNGyjMs&list=PLjSkJdbr_gFZL2BNnGLvTgMYXptKGIyum&index=2 

☞ 확인 사항

- 큐는 데이터를 넣을 때 마지막에 넣고, 꺼낼 때는 앞에서부터 꺼낸다

  (1) offer을 할 때는 : REAR가 가리키는 것이 있을 때 ) REAR의 NEXT에 연결

                            FRONT가 가리키는 것이 없을 때(= 저장된 데이터의 사이즈가 0) )

                                FRONT와 REAR가 모두 null임을 명시한다.

  (2) poll을 할 때는 : FRONT가 가리키는 것이 없을 때 ) 꺼낼 수 없으므로 예외 (NoSuchElementException)를 발생

                           FRONT를 꺼낸 뒤 FRONT->NEXT를 FRONT로 변경

                           만약에 새로운 FRONT가 가리키는게 없을때(= 저장된 데이터의 사이즈가 0)

                               FRONT와 REAR가 모두 null임을 명시한다.

※ 자바의 경우 큐는 인터페이스며, LinkedList가 이를 구현하고 있다.

   아래의 실제 자바 Queue메소드는 LinkedList에서 사용 가능하다.
실제 자바 Queue 메소드 구현객체의 메소드 내용
offer(data) add(data) 데이터 추가
poll() remove() 가장 앞 데이터 꺼내기
peek() peek() 가장 앞 데이터 읽기
isEmpty() isEmpty() 비어있는지 확인

☞ 구현 하기

import java.util.NoSuchElementException;

class Queue<T>{
	
	class Node<T>{
		private T data;
		private Node<T> next;
		
		public Node(T data) {
			this.data = data;
		}
	}
	
	private Node<T> first;
	private Node<T> last;
	
	public void add(T item) {
		Node<T> t = new Node<T>(item);
		
		if (last != null) {
			last.next = t;
		}
		last = t;
		
		if (first == null) {
			first = last;
		}
	} 
	
	public T remove() {
		if (first == null) {
			throw new NoSuchElementException();
		}
		
		T data = first.data;
		first = first.next;
		
		if (first == null) {
			last = null;
		}
		return data;
	}
	
	public T peek() {
		if (first == null) {
			throw new NoSuchElementException();
		}
		return first.data;
	}
	
	public boolean isEmpty() {
		return first == null;
	}

}//end class Queue

 

■ 큐 알고리즘 예제

https://www.acmicpc.net/problem/2164

☞ 계획 수립

  [1] LinkedList를 사용하여 데이터를 하나씩 넣어준다.
  [2] 반복문을 통해 [1] poll [2] poll & offer을 반복한다.

☞ 계획 수행

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;

public class Ex01_2164_카드2 {

	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		int N = Integer.parseInt(reader.readLine());
		
		LinkedList<Integer> list = new LinkedList<Integer>();
		
	    //순서대로 1~N값 입력
		for (int i = 1; i <= N; i++) {
			list.offer(i);
		}
		
		//버리고, 밑으로 내리는 것 반복
		while (list.size() != 1) {			
			list.poll(); //첫번째로 꺼낸 것은 버린다.
			list.offer(list.poll()); //두번째로 꺼낸 것은 가장 마지막에 넣는다.
		}
		System.out.println(list.peek());
		
	}

}

- 여기까지는 문제가 어렵지 않았다.. 그런데 아래의 문제들을 만난 뒤 당황..

 

■ 원형 큐 (Circular Queue)의 원리를 사용한 알고리즘 문제

- 원형 큐의 개념 : 큐를 원형의 구조처럼 한 바퀴를 돌리며 사용하는 방식

☞ 계획 수립

  [1] LinkedList를 사용한다.
  [2] 이중 루프를 돌려,
      - 바깥에서는 큐가 빌 때까지 반복,
      - 안쪽에서는 K번째 전까지는 poll & offer을 반복하고, K번째에는 poll을 한다.
  [3] 출력은 StringBuffer를 사용한다.

 

☞ 계획 수행

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Ex02_11866_요세푸스문제1_원형큐사용 {

	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringBuffer buffer = new StringBuffer();
		StringTokenizer token = new StringTokenizer(reader.readLine());
		
		int N = Integer.parseInt(token.nextToken());
		int K = Integer.parseInt(token.nextToken());
		
		//1~N까지의 데이터를 담을 연결리스트
		Queue<Integer> queue = new LinkedList<Integer>();
		
		//1~N까지 데이터 채우기
		for (int i = 1; i <= N; i++) {
			queue.offer(i);
		}
		
		buffer.append("<");
		
		int count = 0;
		
		//큐가 더 이상 아무것도 없을 때까지 반복
		while (!queue.isEmpty()) {
			//K보다 작을 때까지 poll&offer을 반복
			for (int i = 1; i < K; i++) {
				queue.offer(queue.poll());
			}
			
			//K번째에 poll해서 buffer에 저장
			if (count == 0) {
				buffer.append(queue.poll());
				count++;
				continue;
			}
			
			buffer.append(", ").append(queue.poll()); 
			
		}//end while
		
		buffer.append(">");

		System.out.println(buffer);
		
	}
	
}

 

>> 결과

7 3
<3, 6, 2, 7, 5, 1, 4>

▼ 처음에 일반큐 + 배열 + 커서변수를 사용해서 예제를 풀었었다. 

    그렇게 하니 코드도 길고 내가 적고도 다른 사람에게 설명할 수 없는 코드가 만들어졌다.

    스터디 때 다른 팀원분이 원형큐에 대해 설명해주셔서 알아보고 다시 작성을 해보았는데

    원형큐를 사용하니 메모리 사용량은 더 많았어도 시간은 더 준 걸 볼 수 있었다.

 

 

[참조]

https://st-lab.tistory.com/184

https://velog.io/@delicate1290/%EB%B0%B1%EC%A4%80-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C-1158%EB%B2%88

'Computer Science > Algorithm' 카테고리의 다른 글

[정렬] 병합정렬(Merge Sort)  (0) 2022.05.11
[정렬] 퀵 정렬(Quick Sort)  (1) 2022.05.10
[자료구조] 스택  (0) 2022.04.18
[검색] 선형탐색과 이진탐색  (0) 2022.04.12
[자바의 정석] 스택과 큐  (0) 2022.03.30

■ 스터디 방향성

- 5월-6월간 매주 일요일 오전 11시에 각 조원들이 아래 강의를 보고 네트워크/운영체제를 공부

 

1. 네트워크

- 개념 정리 포커스 : https://dev-coco.tistory.com/161?category=1056309 

 

신입 개발자 기술면접 질문 정리 - 네트워크

💡 HTTP 프로토콜에 대해 설명해주세요. HTTP(Hyper Text Transfer Protocol)이란 데이터를 주고 받기 위한 프로토콜이며, 서버/클라이언트 모델을 따릅니다. HTTP는 상태 정보를 저장하지 않는 Stateless의

dev-coco.tistory.com

- 강의 링크 : https://www.youtube.com/playlist?list=PL0d8NnikouEWcF1jJueLdjRIC4HsUlULi 

 

네트워크 기초(개정판)

OSI 7계층에서 각 계층의 다양한 프로토콜들을 통해서 배우는 네트워크 기초에 대한 강의입니다.

www.youtube.com

 

2. 운영체제

- 개념 정리 포커스 : https://dev-coco.tistory.com/162?category=1056309 

 

신입 개발자 기술면접 질문 정리 - 운영체제

💡 프로세스와 쓰레드의 차이에 대해 설명해주세요. 프로세스는 실행 중인 프로그램을 말하며, 완벽히 독립적이기 때문에 메모리 영역(Code, Data, Heap, Stack)을 다른 프로세스와 공유하지 않습니

dev-coco.tistory.com

- 강의 링크 : https://www.youtube.com/playlist?list=PLBrGAFAIyf5rby7QylRc6JxU5lzQ9c4tN 

 

[Course] Operating System (CPA310) - 운영체제 강의

o Operating System (운영체제), CPA310, KOREATECH o Instructor: Duksu Kim (김덕수) o Course homepage: https://sites.google.com/view/hpclab/courses/operating-system 운...

www.youtube.com

 

 

■ 자료 공유

- 각자 블로그 및 파일 등에 정리한 내용을 공유

- 궁금한 점이 있다면 채팅을 통해 나누는 방식

[자료구조 알고리즘] Stack 구현하기 in Java - YouTube

 

[ 스택의 활용 예 : 출처 자바의 정석 ]

수식 계산, 수식괄호검사, 워드프로세서의 undo/redo, 웹브라우저의 뒤로/앞으로

 

★ 문제 : 10828번: 스택 (acmicpc.net)

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

★ 스택 단계 (acmicpc.net)

 

스택 단계

주어진 문자열이 올바른 괄호열인지 판단하는 문제

www.acmicpc.net

 

■ 스택을 생성해보는 예제 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class _00_스택 {
	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer token;
		
		//스택 인스턴스 생성
		Stack stack = new Stack();
		
		//첫번째줄 입력값(명령의 수) 
		int N = Integer.parseInt(reader.readLine()); 
		
		//명령 문자열 한 줄
		String input;
		//명령어
		String order;
		
		while (N > 0) {
			input = reader.readLine();
			token = new StringTokenizer(input);
			order = token.nextToken();
			
			//명령어에 따라 스택 메소드 실행
			if (order.equals("push")) {
				int item = Integer.parseInt(token.nextToken());
				stack.push(item);
			} else if (order.equals("pop")) {
				stack.pop();
			} else if (order.equals("size")) {
				stack.size();
			} else if (order.equals("empty")) {
				stack.empty();
			} else if (order.equals("top")) {
				stack.top();
			}
			
			N--;
		}
	}
}

class Stack {
	//노드 내부 클래스 정의
	class Node {
		private int data;
		private Node next;
	}
	
	//가장 위에 있는 노드
	private Node top;
	
	//push메소드 : 노드 삽입
	public void push(int item) {
		Node t = new Node();
		t.data = item;
		t.next = top;
		top = t;
	
	//pop메소드 : 노드 빼기 (뺄 때, 데이터값 읽기)
	public void pop() {
	    if (top == null) {
	    	System.out.println("-1");
	    }else {
	    	Node tmp = top;
	    	top = top.next;
	    	System.out.println(tmp.data);
	    }
	}//pop()
	
	//size메소드 : 노드의 갯수 반환
	public void size() {
		int count = 1;
		Node tmp = top;
		
		if (top == null) {
			System.out.println(0);
		} else {
			while(tmp.next != null) {
				tmp = tmp.next;
				count++;
			}
			System.out.println(count);
		}
	}//size()
	
	//empty메소드(isEmpty) : 노드가 있는지 여부 확인
	public void empty() {
		if (top == null) {
			System.out.println(1);
		} else {
			System.out.println(0);
		}
	}//empty()
	
	//top메소드(peek) : top노드 데이터 읽기
	public void top() {
		if (top == null) {
			System.out.println("-1");
		} else {
			System.out.println(top.data);
		}
	}//top()
	
}

 

 

'Computer Science > Algorithm' 카테고리의 다른 글

[정렬] 퀵 정렬(Quick Sort)  (1) 2022.05.10
[자료구조] 큐(Queue)  (0) 2022.04.28
[검색] 선형탐색과 이진탐색  (0) 2022.04.12
[자바의 정석] 스택과 큐  (0) 2022.03.30
[자바의 정석] ArrayList/LinkedList  (0) 2022.03.29

■ 선형검색 : 정렬되지 않은 데이터를 0부터 끝까지 확인할 때 유리

- 의사코드

for i from 0 to n-1
  if i'th element is the target value
     return true
  return false

- 자바코드

package linearSearch;

import java.util.Arrays;

public class LinearSearch1 {

	public static void main(String[] args) {
		int[] arr = new int[10];
		init(arr);
		System.out.println(Arrays.toString(arr));
		
		//linear search
		//전제 : 정렬되지 않은 데이터
		//찾으려는 수 : 5
		for (int i = 0; i < arr.length; i++) {
			if (arr[i]==5) {
				System.out.println("index : "+i);
				break;
			}
		}
	}
	
	public static void init(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int)(Math.random()*arr.length)+1;
			for (int j = 0; j < i; j++) {
				if (arr[i]==arr[j]) {
					i--;
					break;
				}
			}
		}
	}
}

>> 결과

[9, 3, 6, 8, 1, 5, 7, 4, 2, 10]
index : 5

 

■ 이진검색 : 정렬된 데이터들 안에서 특정 데이터를 찾을 때 유리

- 의사코드

*찾고자 하는 값이 50일 때,

if middle item is 50
	return true
else if 50 < middle item
	search left half
else if 50 > middle item 
	search right half

- 수학적 논리 : 중앙값을 지정한 후, left~right의 범위를 줄여가면서 logN의 속도로 탐색을 하는 방법

- 자바 코드

package BasicSearch;

public class _01_BinarySearch {

	public static void main(String[] args) {
		int[] arr = new int[] {1,2,3,4,5,6,7,8,9,10};
		int key = 3;
		
		int mid;
		int left = 0;
		int right = arr.length-1;
		while(left<=right) {
			mid = (left+right)/2;
			
			if(key==arr[mid]) {
				System.out.println("index : "+mid);
				break;
			}
			
			if(key < arr[mid]) {
				right = mid-1;
			}else if(key > arr[mid]) {
				left = mid+1;
			}
		}//end while
	}//end main

}

>> 결과

index : 2

 

 

※ 참조 : 자료구조에 대한 정리

https://why-dev.tistory.com/6?category=917883 

 

[컴퓨터 공학_복습] 알고리즘 정의, 검색과 정렬 알고리즘

심플한 개발 [컴퓨터 공학_복습] 알고리즘 정의, 검색과 정렬 알고리즘 본문 컴퓨터공학 [컴퓨터 공학_복습] 알고리즘 정의, 검색과 정렬 알고리즘 심플한 개발 2022. 1. 26. 17:27 Prev 1 ··· 3 4 5 6 7 Ne

why-dev.tistory.com

 

1. 스택과 큐

https://www.youtube.com/watch?v=ktvhRSRohR4 

▶ 스택(Stack) : 밑이 막힌 상자

   - LIFO구조. Last in First Out / push(저장) & pop(추출) 방식

   - 배열이 적합   *순차적인 추가/삭제

▶ 큐(Queue)  : 양끝이 뚫린 상자(포장마차의 종이컵 빼는 것과 같다)

   - FIFO구조. First in First Out / otter(저장, 제공한다) & poll(추출) 

   - 링크드리스트가 적합   *비순차적인 추가/삭제

 

■ 스택의 메소드 **JAVA에서 스택은 클래스 (객체생성 가능)

push(Object) : Object  --- Stack객체에 item을 저장

pop( ) : Object      ---  맨 위의 것 꺼내기

empty( ) : boolean ---  비어있는지

peek(  )  : Object   ---  맨 위의 것 읽기 (꺼내지X)

search(Object) : int ---  맨 위에서 1부터시작해서 순서 반환 *못찾으면 -1 반환

 

■ 큐의 메소드  **JAVA에서 큐는 인터페이스 (객체생성 불가능)

offer(Object) : boolean  --- Queue 객체에 item을 저장(예외 발생X)

poll( ) : Object      ---  객체를 꺼내서 반환(예외 발생X)

peek(  )  : Object   ---  삭제 없이 요소 읽음(꺼내지X)

add(Object) : boolean  --- Queue 객체에 item을 저장(예외 발생O)

remove() : Object  ---  객체를 꺼내서 반환(예외 발생O)

   [ 큐 사용법]
   1. 큐를 직접 구현
   2. 큐를 구현한 클래스를 사용 >> Java API 중 Queue를 구현한 목록 확인 (LinkedList도 큐 구현)
      Queue q = new LinkedList();

 

1. ArrayList : 배열 기반 리스트

https://www.youtube.com/watch?v=_2e-cgwMOyc 

▶ Vector를 개선. *차이점) Vector는 동기화 가능/ ArrayList는 동기화X

▶ 생성자

ArrayList()  
ArrayList(Collection c) 컬렉션을 넣으면 배열리스트로 변경됨
ArrayList(int initalCapacity) 저장하려는 갯수만큼 길이 지정

* 저장갯수를 지정해주지 않으면 배열이 늘어나고 줄어들 때마다 배열이 새로 생성되기에 성능 떨어진다.

▶ 메소드

추가 삭제 검색 기타
add(Object o) : boolean
add(int index, Object element) 
addAll(컬렉션)
addAll(index, 컬렉션)
remove(Object o) : boolean
remove(int index)
removeAll(Collection c)
clear()
indexOf() : int  <- index
lastIndexOf() : int
contains()
get(int index) : Object
set(index, Object) : Object
subList()
toArray() : Object[]
isEmpty()
trimToSize() - 빈공간제거
size() - 갯수 반환

▶ ArrayList에서 객체를 추가하거나 삭제할 때 배열의 복사가 이루어질 수 있다.

    ★ 삭제할 때, Last in First Out 방식을 취할 경우, 배열 복사가 발생하지 않는다. (성능 ↑)

 

[예제 연습1]

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListEx2 {

	public static void main(String[] args) {
		final int LIMIT = 10;
		String source = "0123456789abcdefghijABCDEFGHIJ!@#$%^&*()ZZZ"; 
		int length = source.length(); 
		
		List list = new ArrayList(length/LIMIT+10);
		
		for(int i = 0; i < length; i+=LIMIT) {
			if(i+LIMIT < length)
				list.add(source.substring(i,i+LIMIT));
			else
				list.add(source.substring(i));
		}
		
		for(int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		
	}//end main
}//end class

>> 결과

0123456789
abcdefghij
ABCDEFGHIJ
!@#$%^&*()
ZZZ

 

2. LinkedList 

https://www.youtube.com/watch?v=1ey5QpqbapU 

[배열의 장단점]

- 장점 : 배열의 구조가 간단하고, 데이터를 읽는데 걸리는 시간이 짧다. 

- 단점1 : (실행중) 크기를 변경할 수 없다. (크기를 변경할 경우 : 크기를 늘려 복사해서 참조변경)

         * 크기 변경을 피하기 위해 충분히 큰 배열을 생성하면, 메모리가 낭비됨

- 단점2 : 비순차적인(=중간에) 데이터의 추가, 삭제에 시간이 많이 걸린다. 

         * 데이터를 추가/삭제하려면 다른 데이터를 옮겨야함

         * 순차적인 데이터 추가(끝에 추가)와 삭제(끝부터 삭제)는 빠르다.

[LinkedList <- 배열의 단점을 보완]

- 배열과 달리, 링크드 리스트는 불연속적으로 존재하는 데이터를 연결

▶ 데이터의 삭제 : 단 한 번의 참조 변경으로 가능

▶ 데이터의 추가 : 한 번의 객체 생성과 두 번의 참조변경만으로 가능

- 단점 : 데이터 접근성이 나쁘다 (why? 노드들이 next로 하나씩 연결되어 있음)

- 개선한 것

▶ 더블리 링크드 리스트 : 이중 연결리스트 *하나의 노드에 next + previous

▶ 더블리 써큘러 링크드 리스트 : 이중원형 연결리스트 *첫번째->맨끝 / 맨끝->첫번째 연결

- 자바는 더블리 링크드 리스트를 사용한다.

 

ArrayList vs LinkedList 비교

그림으로 보는 ArrayList와 LinkedList의 비교

  특징 읽기(접근시간) 추가/삭제 비고
ArrayList 연속적 빠르다 느리다 순차적인 추가삭제는 더 빠르다.
비효율적인 메모리사용
LinedList 불연속 느리다 빠르다 데이터가 많을수록 접근성이 떨어진다.

 

▶ 들어가기 전에..

   컬렉션의 대부분의 내용은 자바의 정석 강의을 보고 공부하고 있습니다.
   영상 내용 중 중요한 것을 작성했으나 제가 쓴 부분이 오류가 있을 수 있으니 오류가 있으면 댓글 부탁드립니다.

 

1. 컬렉션 프레임웍(Collection Framework)의 이해

https://www.youtube.com/watch?v=z9GpUGoYCw4

■ 용어 

▶ 컬렉션 (모아놨다)

▶ 프레임웍(정형화된 틀) : 라이브러리 + 프로그래밍 방식

    *라이브러리 : 다른 사람이 이미 만들어 놓은 걸 모아논 곳(라이브러리=도서관). 기능만 제공한다(ex. JavaAPI)

▶ 컬렉션 프레임웍 : 다수의 객체를 다루기 위한 표준화된 프로그래밍 방식 

    *객체 = 데이터 

    - java.util 패키지에 포함. (JDK2.0부터)

▶ 컬렉션 클래스

 

■ 컬렉션 프레임웍의 핵심 인터페이스

공통 인터페이스 순서 중복
Collection List O O 대기자 명단(1.홍길동/2.김길동...)
Set(집합) X X 네 발 동물 집합, 양의 정수 집합 
- Map X 키X, 값O 우편변호, 지역변호(전화번호), 아이디/패스워드

 

2. Collection인터페이스의 메소드

https://www.youtube.com/watch?v=RscGmop2Bzo 

■ Collection 인터페이스 _ 검색/추가/삭제/기타

  메소드 설명
검색 boolean contains(Object o)
boolean containsAll(Collection c)
지정된 객체가 있는지 확인
지정된 컬렉션의 객체들이 있는지 확인
추가 boolean add(Object o)
boolean addAll(Collection c)
지정된 객체 추가
지정된 컬렉션의 객체들을 추가
삭제 boolean remove(Object o)
boolean removeAll(Collection c)
boolean retainAll(Collection c)
void clear()
지정된 객체 삭제
지정된 컬렉션에 포함된 객체들을 삭제
지정된 컬렉션 외의 객체를 삭제
컬렉션의 모든 객체 삭제
기타 int size()
boolean isEmpty()
Iterator iterator()
Object[] toArray()
Object[] toArray(Object[] a)
컬렉션에 저장된 객체의 갯수를 반환
컬렉션이 비어있는지 확인
컬렉션의 iterator를 얻어서 반환
컬렉션에 저장된 객체를 Object타입 객체배열로 반환
컬렉션에 저장된 객체를 저장해서 반환

 

■ List 인터페이스(순서O/중복O) _ 검색/추가/삭제/읽기/변경/추출/정렬

  메소드 설명
검색 int indexOf(Object o)
int lastIndexOf(Object o)
지정된 객체의 위치를 첫번째부터 찾아 반환
지정된 객체의 위치를 마지막부터 찾아 반환
추가 void add(int index, Object element)
boolean addAll(int index, Collection c)
지정된 위치에 객체를 추가
지정된 위치에 컬렉션에 있는 객체를 추가
삭제 Object remove(int index) 지정된 위치의 객체 삭제
읽기 Object get(int index) 지정된 위치에 있는 객체를 반환
변경 Object set(int index, Object element) 지정된 위치에 객체를 저장
추출 List subList(int fromIndex, int toIndex) 지정된 범위부터의 객체를 List로 반환
정렬 void sort(Comparator c) 지정된 비교자로 List를 정렬

 

■ Set 인터페이스(순서X/중복X)_메소드는 컬렉션과 동일+집합 관련 메소드

- addAll(Collection c) : boolean [합집합]

- containsAll(Collection c) : boolean [부분집합]

- removeAll() [차집합]

- retainAll() [교집합]

 

■ Map 인터페이스(순서X/중복-키X,값O)

  메소드 설명
검색 boolean containsKey(Object key)
boolean containsValue(Object value)
Object get(Object key)
key가 있는지 확인
value가 있는지 확인
key를 가진 객체 반환
추가 Object put(Object key, Object value)
void putAll(Map t)
Map에 value객체를 key객체에 맵핑해서 저장
Map에 모든 key-value쌍 추가
삭제 Object remove(Object key) key를 가진 key-value삭제
읽기 Set keySet()
Set entrySet()
Collection values()
모든 key객체 반환
모든 key-value쌍을 Map.Entry형식으로 하여 Set로 반환
모든 value객체 반환

 

1. 알고리즘이란?

https://why-dev.tistory.com/6?category=917883 

 

[컴퓨터 공학_복습] 알고리즘 정의, 검색과 정렬 알고리즘

▼ 부스트 코스의 컴퓨터 공학 내용을 복습 & 요약한 내용입니다. https://www.boostcourse.org/cs112 부스트코스의 컴퓨터 공학을 수강 중인데, 알고리즘 부분 내용이 잘 이해가 가지 않아서ㅠㅠ 스스로

why-dev.tistory.com

 

2. 정렬

- 정의 : 이름,학번,키 등 핵심항목(key)의 대소관계에 따라 순서대로 값을 나열하는 것

- 안정성 : 키값이 같은 요소의 순서가 정렬 후에도 유지되는 것

   (ex. 같은 점수를 지닌 두 학생에 대해 학번으로 순번을 지정)

- 내부 정렬과 외부 정렬 : 정렬할 모든 데이터를 하나의 배열에 저장할 수 있을 때에 내부 정렬을 사용한다. 

- 정렬의 속도 비교 : 

https://youtu.be/ZZuD6iUe3Pc

 

3. 버블정렬, 선택정렬, 삽입정렬

  - Big O는 셋 다 n^2이지만, 속도는 다르다.
  - (정렬이 안 된 자료들을 정렬할때) 버블정렬 보다는 선택정렬이 교환횟수가 적어서 상대적으로 더 빠르다. 
  - (이미 정렬이 어느 정도 된 경우) 삽입정렬을 쓰는 것이 좋다

 

1) 버블정렬 

원리 ) 안쪽에서 두개의 값을 비교한다 
       --> 한 줄 비교가 다 끝나면 마지막 값이 가장 큰 값(또는 가장 작은 값)
       --> 안 쪽은 n-1-i 만큼 두개씩 비교 & swap하면 된다.
       바깥쪽에서 이 과정을 n-1만큼 반복한다.

[코드]

package _02_정렬;

import java.util.Arrays;

public class _04_BubbleSort {

	public static void main(String[] args) {
		
		int[] arr = new int[10];
		
		random(arr);
		
		System.out.println(Arrays.toString(arr));
		
		//오름차순 버블 정렬을 구현하라
		int tmp;
		for (int i = 0; i < arr.length-1; i++) {
			for (int j = 0; j < arr.length-1-i; j++) {
				if (arr[j] > arr[j+1]) {
					tmp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = tmp;
				}
			}
		}
		System.out.println(Arrays.toString(arr));
		
		//내림차순 버블 정렬을 구현하라
		for (int i = 0; i < arr.length-1; i++) {
			for (int j = 0; j < arr.length-1-i; j++) {
				if (arr[j] < arr[j+1]) {
					tmp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = tmp;
				}
			}
		}
		System.out.println(Arrays.toString(arr));

	}
	
	public static int[] random(int[] arr) {
		
		OUTER :
		for (int i = 0; i < arr.length; i++) {
			
			arr[i] = (int)(Math.random()*10)+1;
			
			for (int j = 0; j < i; j++) {
				
				if (arr[j] == arr[i]) {
					i--;
					continue OUTER;
				}
			}
		}
		
		return arr;
		
	}

}

>> 결과

[10, 3, 8, 9, 4, 1, 7, 5, 2, 6]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

 

2) 선택정렬 

원리 ) i index를 min(or max)으로 지정하고, 나머지 값들을 하나씩 비교한 뒤, 교환한다.

[코드]

package _02_정렬;

import java.util.Arrays;

public class _05_SelectionSort {

	public static void main(String[] args) {

		int[] arr = new int[10];
		
		random(arr);
		
		System.out.println(Arrays.toString(arr));
		
		//오름차순 선택정렬을 구현하라
		int min, tmp;
		for (int i = 0; i < arr.length-1; i++) {
			min = i; // 하나의 요소를 min으로 선택(이 값보다 작은 값을 찾는다)
			for (int j = i+1; j < arr.length; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			//i위치값과 min값을 swap
			tmp = arr[i];
			arr[i] = arr[min];
			arr[min] = tmp;
		}
		System.out.println(Arrays.toString(arr));
		
		//내림차순 선택정렬을 구현하라
		int max;
		for (int i = 0; i < arr.length-1; i++) {
			max = i;
			for (int j = i+1; j < arr.length; j++) {
				if (arr[j] > arr[max]) {
					max = j;
				}
			}
			//i위치값과 max값을 swap
			tmp = arr[i];
			arr[i] = arr[max];
			arr[max] = tmp;
		}
		System.out.println(Arrays.toString(arr));

	}
	
	public static int[] random(int[] arr) {
		
		OUTER :
		for (int i = 0; i < arr.length; i++) {
			
			arr[i] = (int)(Math.random()*10)+1;
			
			for (int j = 0; j < i; j++) {
				
				if (arr[j] == arr[i]) {
					i--;
					continue OUTER;
				}
			}
		}
		
		return arr;
		
	}

}

>> 결과

[2, 9, 8, 5, 10, 1, 6, 4, 3, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

 

3) 삽입 정렬 (Insertion Sort)

- 거의 다 정렬된 상태의 데이터를 다시 정렬할 때, 가장 효과적인 알고리즘 (위 정렬 속도 비교 확인)

- 원리 : 아직 정렬되지 않은 부분의 첫번째 요소를 정렬한 부분의 알맞은 위치에 삽입한다.

- 장점 : 정렬이 되었거나 또는 그 상태에 가까우면 정렬 속도가 아주 빠름

- 단점 : 삽입할 곳이 멀리 떨어지면 이동(대입)하는 횟수가 많다

   (ex. 0~10까지 중 0제외 나머지는 정렬된 상태이나, 0값이 인덱스의 끝에 위치)

[코드]

package _02_정렬;

import java.util.Arrays;

public class _02_InsertionSort {

	public static void main(String[] args) {
		int[] arr = new int[10];
		
		random(arr);
		
		System.out.println(Arrays.toString(arr));
		
		//오름차순 삽입정렬을 구현하라
		int tmp;
		for (int i = 1; i < arr.length; i++) {
			tmp = arr[i];
			int j;
			
			for (j = i; j > 0 && arr[j-1] > tmp; j--) {
				arr[j] = arr[j-1];
			}
			arr[j] = tmp;	
		}
		System.out.println(Arrays.toString(arr));
		
		//내림차순 삽입정렬을 구현하라
		for (int i = 1; i < arr.length; i++) {
			tmp = arr[i];
			int j;
			for (j = i; j > 0 && arr[j-1] < tmp; j--) {
				arr[j] = arr[j-1];
			}
			arr[j] = tmp;
		}
		System.out.println(Arrays.toString(arr));
	}
	
	public static int[] random(int[] arr) {
		
		OUTER :
		for (int i = 0; i < arr.length; i++) {
			
			arr[i] = (int)(Math.random()*10)+1;
			
			for (int j = 0; j < i; j++) {
				
				if (arr[j] == arr[i]) {
					i--;
					continue OUTER;
				}
			}
		}
		
		return arr;
		
	}

}

>> 결과

[3, 1, 6, 4, 10, 2, 5, 7, 9, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

 

4. 셸 정렬 (Shell Sort)

 

 

[ 출처 ]

- 자바의 정석, 남궁성

- Do it! 자료구조와 함께 배우는 알고리즘 입문 [자바편], bogyoh shibata지음

- 기타 : 유투브

+ Recent posts