CPU_Scheduler

CPU 스케줄링

CPU란?

프로그램의 기계어 명령을 실제로 수행하는 컴퓨터 내의 중앙처리장치.

일반적으로 시스템 내에 하나밖에 없으므로 여러 프로그램이 동시에 수행되는 시분할 환경에서의 CPU는 매우 효율적으로 관리되어야 하는 자원이다.

  • 처리순서

    1. 프로그램이 시작되어 메모리에 올라간다.
    2. 프로그램 카운터라는 이름의 레지스터가 현재 CPU에서 수행할 코드의 메모리 주소값을 가지고 있다.
    3. CPU는 프로그램 카운터가 가르키는 주소의 기계어 명령을 수행한다.

 

CPU 스케줄러

CPU를 사용하는 패턴이 상이한 여러 프로그램이 동일한 시스템 내부에서 함께 실행되기 때문에 필요하다.

준비 상태에 있는 프로세스들 중에 어떠한 프로세스에게 CPU를 할당할지 결정하는 운영체제의 코드.

 

CPU스케줄링이 발생하는 상황

  1. 실행 상태에 있던 프로세스가 I/O 요청 등에 의해 봉쇄상태로 바뀌는 경우
  2. 실행 상태에 있던 프로세스가 타이머 인터럽트 발생에 의해 준비 상태로 바뀌는 경우
  3. I/O 요청으로 봉쇄 상태에 있던 프로세스의 I/O 작업이 완료되어 인터럽트가 발생하고 그 결과 이 프로세스의 상태가 준비 상태로 바뀌는 경우
  4. CPU에서 실행 상태에 있는 프로세스가 종료되는 경우

 

CPU 스케줄링 방식

  • 비선점형 방식

    CPU를 획득한 프로세스가 스스로 CPU를 반납하기 전까지는 CPU를 빼앗기지 않는 방법

    일반적으로 선점형보다 스케줄러의 호출 빈도가 낮고 Context Switching 오버헤드가 작다.

    (1), (4)가 대표적인 예.

     

  • 선점형 방식

    프로세스가 CPU를 계속 사용하기 원하더라도 강제로 빼앗을 수 있는 방법

    "선점"이라는 말은 OS가 프로세스 자원을 선점하고 있다가 각 프로세스의 요청이 있을 때 특정 요건들을 기준으로 자원을 배분하는 방식 => 한 프로세스가 자원을 독점 할 수 없다.

    (2), (3)이 대표적인 예

 

디스패처 dispatcher

CPU스케줄러가 어떤 프로세스에게 할당할지 결정하고 나면, 새롭게 선택된 프로세스가 CPU를 할당받고 작업을 수행할 수 있도록 환경설정하는 커널 모듈.

PCB에 저장, 복원 등등.. 소요 시간은 Context Switching 오버헤드에 해당.

 

 

스케줄링 알고리즘

FCFS

FCFS(First-Come First-Served)는 프로세스가 준비 큐에 도착한 시간 순서대로 CPU 할당

프로세스가 자발적으로 CPU를 반납할 때까지 CPU를 선점하지 않는다. => 비선점형 방식

단점 : Convoy(콘보이) 현상

CPU버스트가 짧은 프로세스가 CPU버스트가 긴 프로세스보다 나중에 도착해 오랜 시간을 기다려야 하는 상황.

(CPU를 짧게 사용해야 하는 프로세스가 길게 사용해야하는 프로세스보다 나중에 도착해서 무한 대기)

 

SJF

SJF(Shortest-Job First)는 CPU 버스트가 가장 짧은 프로세스에게 먼저 CPU를 할당하는 방식.

프로세스들이 준비큐에서 대기하는 전체적인 시간이 줄어든다.

  • 비선점형

    일단 CPU를 획득하면 자진 반납할때까지 선점 당하지 않는 방식.

  • 선점형

    준비 큐에서 CPU버스트가 가장 짧은 프로세스에게 CPU를 할당했다 하더라도 더 짧은 프로세스가 도착할 경우 CPU를 빼앗아 부여한다. ==> SRTF(Shortest Remaining Time First)

    일반적 시분할 환경에서는 평균 대기 시간을 가장 많이 줄일 수 있는 방식.

단점 : CPU 버스트 시간을 미리 알수 없다.

그렇기 때문에 예측치가 가장 짧은 프로세스에게 할당한다.

기아 현상(Starvation)

계속 CPU버스트가 짧은 프로세스에게만 할당할 경우 CPU 버스트가 긴 프로세스는 준비 큐에서

무한 대기

 

우선순위 스케줄링

준비큐에서 기다리는 프로세스들 중에 우선순위가 가장 높은 프로세스에게 CPU할당

숫자가 낮을수록 우선순위가 높다.

  • 비선점형

    비록 우선순위가 더 높은 프로세스가 도착하더라도 CPU를 자진 반납하기 전까지 선점 불가.

  • 선점형

    현재 CPU에서 수행중인 프로세스보다 우선순위가 높은 프로세스가 도착할 경우 CPU를 새롭게 도착한 프로세스에 할당.

단점: 기아 현상(Starvation) 우선순위가 낮은 프로세스는 무한대기.

=> 에이징 기법

에이징 기법이란 기다리는 시간이 길어지면 우선순위를 조금씩 높여 언젠가 가장 높은 우선순이가 되어 CPU를 할당받을 수 있게 해주는 방법.

 

HRN 스케줄링

HRN(Highest Response-ratio next)는 SJF의 단점을 보안하기 위해 등장.

우선순위 계산식을 이용하여 자원 할당. 숫자가 높을수록 우선순위가 높다. ==> 비선점형

우선순위 = (대기시간+실행시간)/실행시간

 

라운드 로빈 스케줄링

시분할 시스템의 성질을 가장 잘 활용한 새로운 의미의 스케줄링 방식.

CPU 사용 시간이 특정 시간으로 제한되며, 이 시간이 경과되면 CPU를 회수해 다음 프로세스에게 할당하고, 이 프로세스는 준비 큐의 맨 뒤로 가서 차례를 기다린다. ==> 선점형

라운드 로빈 스케줄링은 SJF방식보다 평균대기시간은 길지만 응답시간은 더 짧다.

할당시간 : 각 프로세스가 CPU를 연속적으로 사용할 수 있는 최대 시간.

할당시간이 너무 길면 FCFS와 같은 결과를 초래할 수 있으며, 너무 작으면 빈번하게 교체로 인한 context switching 오버헤드가 커지게 된다.

CPU를 회수하는 방법으로는 타이머 인터럽트 사용. 만약, CPU 버스트 시간이 할당시간보다 짧으면 자신의 버스트 시간만큼 스스로 사용후 반납.

 

 

 

 

scheduler

스케줄러

프로세스를 스케줄링하기 위한 Queue에는 세 가지 종류가 존재한다.

  • Job Queue : 현재 시스템 내에 있는 모든 프로세스의 집합
  • Ready Queue : 현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
  • Device Queue : Device I/O 작업을 대기하고 있는 프로세스의 집합

각각의 Queue에 프로세스들을 넣고 빼주는 스케줄러에도 크게 세 가지 종류가 존재한다.

 

장기스케줄러 Long-term scheduler / job scheduler

메모리는 한정되어 있는데 많은 프로세스들이 한꺼번에 메모리에 올라올 경우, 대용량 메모리(일반적으로 디스크)에 임시로 저장된다. 이 pool에 저장되어 있는 프로세스 중 어떤 프로세스에 메모리를 할당하여 ready queue로 보낼지 결정하는 역할을 한다.

  • 메모리와 디스크 사이의 스케줄링을 담당.

  • 프로세스에 memory(및 각종 리소스)를 할당(admit)

  • degree of Multiprogramming 제어

    메모리에 여러 프로그램이 올라가는 것 -> 몇 개의 프로그램이 올라갈 것인지를 제어

  • 프로세스의 상태 new - > ready (in memory_)

 

cf) 메모리에 프로그램이 너무 많이 올라가도, 너무 적게 올라가도 성능이 좋지 않은 것이다. 참고로 time sharing system에서는 장기 스케줄러가 없다. 곧바로 메모리에 올라가 ready 상태가 된다.

 

단기스케줄러 Short-term scheduler / CPU scheduler

  • CPU와 메모리 사이의 스케줄링을 담당.
  • Ready Queue에 존재하는 프로세스 중 어떤 프로세스를 running 시킬지 결정.
  • 프로세스에 CPU를 할당(scheduler dispatch)
  • 프로세스의 상태 ready -> running -> waiting -> ready

 

중기 스케줄러 Medium-term scheduler / Swapper

  • 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄 (swapping)
  • 프로세스에게서 memory를 deallocate
  • degree of Multiprogramming 제어
  • 현 시스템에서 메모리에 너무 많은 프로그램이 동시에 올라가는 것을 조절하는 스케줄러.
  • 프로세스의 상태 ready -> suspended

Process state - suspended(stopped)

외부적인 이유로 프로세스의 수행이 정지된 상태에로 메모리에서 내련 상태를 의미한다. 프로세스 전부 디스크로 swap out 된다. Blocked 상태는 다른 I/O 작업을 기다리는 상태이기 때문에 스스로 ready state로 돌아갈 수 있지만 이 상태는 외부적인 이유로 suspending 되었기 때문에 스스로 돌아갈 수 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package Z_Project;
 
import java.util.Arrays;
 
/**
 * Dijkstra: 하나의 선택한 정점에서 각 정점까지 갈 수 있는 최단거리를 구하는 알고리즘
 *  Greedy 방식, 음이 아닌 가중치 일 경우만 사용가능
 *                음의 가중치가 있는 경우는 => 벨만포드 알고리즘을 통해서 구해야한다
 *    시간복잡도 O(n^2)
 */
public class Z38_Dijkstra {
    public static void main(String[] args) {
        final int M = Integer.MAX_VALUE;
        int[][] G = {
                {0,3,5,M,M,M},
                {M,0,2,6,M,M},
                {M,1,0,4,6,M},
                {M,M,M,0,2,3},
                {3,M,M,M,0,6},
                {M,M,M,M,M,0}
        };
        
        int s = 0//시작정점
        int[] D = G[s].clone(); // 가중치 배열, 시작정점의 진출차수로 가중치배열을 초기화
        boolean[] used = new boolean[G.length]; //사용한 정점들을 저장할 배열
        
        for (int n = 0; n < used.length; n++) { //정점 하나씩 선택하기
            //사용하지 않은 정점중에서, 가중치가 최소인 정점을 찾아서 used배열에 정점 추가
            int minIndex = -1//최소 가중치가 저장된 D배열의 인덱스
            int minVal = M; //최소가중치
            for(int i=0;i<D.length;i++) {
                if(!used[i] && minVal>D[i]) {
                    minIndex=i;
                    minVal=D[i];
                }
            } //가중치 최소인 장점을 찾음. 
            used[minIndex] = true;
            
            //선택한 정점을 통해서 갈수 있는(인접한) 정점의 가중치를 갱신
            for(int i=0;i<D.length;i++) {
                //사용하지 않은 정점, 인접한 정점, 가중치가 지금보다 더 작으면 =>갱신
                if(!used[i] && G[minIndex][i] != M && D[i]>D[minIndex]+G[minIndex][i] ) {
                    D[i] = D[minIndex]+G[minIndex][i];
                }
            }
        }
        
        System.out.println(Arrays.toString(D));
    } //end of main
}//end of class
 
 
cs


1. 재귀함수.


stirng 넘겨줄때 함수 호출 파라미터로 바로 넘어줘야한다.

s+="a"

dfs(s);


이런식으로 넘겨주면 함수가 종료된후 돌아왔을때 s는 여전히 "a"된 값이 저장되있다



2. substring

substring(0,len)

이면.. 0~4까지 cut

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

[javascript] Hoisting 호이스팅이란  (1) 2019.07.11
[java 예외처리]Try-with-resources  (2) 2019.07.11
[java] 쓰레드(Thread)  (0) 2019.01.24
[java] 예외처리  (2) 2019.01.24
[java] Collection 활용  (0) 2019.01.17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package Z_Project;
 
import java.util.Arrays;
import java.util.Scanner;
 
/**
 * MST 알고리즘 중 KRUSKAL이 더 직관적이고 간단(많이 사용됨) DisjointSets
 */
 
/*
 * 
input
6 11
5 3 18
1 2 21
2 6 25
0 2 31
0 1 32
3 4 34
5 4 40
2 4 46
0 6 51
4 6 51
0 5 60
output
5-3 18
1-2 21
2-6 25
0-2 31
3-4 34
2-4 46
 * 
 * */
public class Z37_KRUSKAL {
    public static int[] p; //부모를 저장할 배열
    public static int[] rank;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int V = sc.nextInt();
        int E = sc.nextInt();
        p = new int[V+1];
        rank = new int[V+1];
        
        Edge[] ed = new Edge[E];
        
        for(int i=0;i<E;i++) {
            ed[i] = new Edge(sc.nextInt(),sc.nextInt(),sc.nextInt());
        }
        Arrays.sort(ed); //정렬하기 위해서 compareTo()를 작성해야한다.
        
        for(int i=0;i<p.length;i++) {
            makeSet(i);
        }
        
        for(int i=0;i<ed.length;i++) { //가중치가 낮은 간선부터 선택하기
            Edge e = ed[i];
            if(findSet(e.a) != findSet(e.b)) { //서로 다른 집합일 경우만 합치기
                union(e.a,e.b);
                System.out.println(e.a+"-"+e.b+" "+e.val);
            }
        }
    }//end of main
    
    public static void printSet() {
        System.out.print("index : ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", i);
        }
        System.out.print("\nparent: ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", p[i]);
        }        
        
        System.out.println("\n");
    }
    
    
    /*멤버 x를 포함하는 새로운 집합을 생성*/
    public static void makeSet(int x) {
        p[x]=x; //부모 : 자신의 index로 표시 or -1
        //rank[x] = 0;//초기값 0임, 생략가능
    }
    
    /*멤버 x를 포함하는 집합의 대표자를 리턴*/
    public static int findSet(int x) {
        if(x==p[x]) return x;
        else {
            p[x]=findSet(p[x]); // Path Compression
            //rank[x]=1;//할 필요 없다. 대표자의 깊이(rank)만 알면된다.
            return p[x];
        }
    }
    
    public static void union(int x,int y) {
        int px = findSet(x);
        int py= findSet(y);
        
        // 서로 다른 집합일 경우만 합친다.
 
        if(px!=py) {
        //    p[py]=px; //대표자 합치기    
            link(px,py);
        }
    }
    
    /*x의 대표자의 집합과 y의 대표자의 집합을 합침, rank도 맞춤*/
    public static void link(int px, int py) {
        if(rank[px]>rank[py]) {
            p[py]=px; //작은쪽에 큰쪽을 붙인다.
        } else {
            p[px]=py;
            
            if(rank[px]==rank[py]) { //같은 경우는 rank 값이 증가
                rank[py]++;//집합의 대표자 랭크가 증가됨.
            }
        }
    }
    
    public static class Edge implements Comparable<Edge>{
        int a; //정점1
        int b; //정점2
        int val; //가중치
        public Edge(int a, int b, int val) {
            this.a = a;
            this.b = b;
            this.val = val;
        }
        @Override
        public int compareTo(Edge o) { //비교기준
            return this.val-o.val;
        }
        
        
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package Z_Project;
 
import java.util.Arrays;
 
/*
 * 상호배타 집합 => MST(크루스칼 알고리즘에 활용)
 * 
 * makeSet(int x) 멤버 x를 포함하는 새로운 집합을 생성
 * findSet(int x) 멤버 x를 포함하는 집합의 대표자를 리턴
 * union(int x, int y) 멤버 x,y의 대표자를 구해서 두 집합을 통합
 * link(int px, int py) x의 대표자의 집합과 y의 대표자의 집합을 합침
 * 
 */
public class Z36_DisjointSets2 {
    public static int[] p = new int[10]; //부모를 저장할 배열
    public static int[] rank=new int[10];
    public static void main(String[] args) {
        
        for(int i = 0;i<p.length;i++) {
            makeSet(i);
        }
        
        printSet();
        union(0,1);printSet();
        union(2,3);printSet();
        union(0,3);printSet();
        
    }//end of main
    
    public static void printSet() {
        System.out.print("index : ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", i);
        }
        System.out.print("\nparent: ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", p[i]);
        }        
        
        System.out.println("\n");
    }
    
    
    /*멤버 x를 포함하는 새로운 집합을 생성*/
    public static void makeSet(int x) {
        p[x]=x; //부모 : 자신의 index로 표시 or -1
        //rank[x] = 0;//초기값 0임, 생략가능
    }
    
    /*멤버 x를 포함하는 집합의 대표자를 리턴*/
    public static int findSet(int x) {
        if(x==p[x]) return x;
        else {
            p[x]=findSet(p[x]); // Path Compression
            //rank[x]=1;//할 필요 없다. 대표자의 깊이(rank)만 알면된다.
            return p[x];
        }
    }
    
    public static void union(int x,int y) {
        int px = findSet(x);
        int py= findSet(y);
        
        // 서로 다른 집합일 경우만 합친다.
 
        if(px!=py) {
        //    p[py]=px; //대표자 합치기    
            link(px,py);
        }
    }
    
    /*x의 대표자의 집합과 y의 대표자의 집합을 합침, rank도 맞춤*/
    public static void link(int px, int py) {
        if(rank[px]>rank[py]) {
            p[py]=px; //작은쪽에 큰쪽을 붙인다.
        } else {
            p[px]=py;
            
            if(rank[px]==rank[py]) { //같은 경우는 rank 값이 증가
                rank[py]++;//집합의 대표자 랭크가 증가됨.
            }
        }
    }
}
 
cs

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

[java] Dijkstra 다익스트라 알고리즘  (0) 2019.02.19
Kruskal 크루스칼 알고리즘  (0) 2019.02.18
[java] Insertion Sort 삽입정렬  (0) 2019.01.28
Permutation 순열  (0) 2019.01.17
Dijkstra 최단경로 알고리즘  (2) 2019.01.08
01_유승아_스레드

1주차(thread) 0218


 

프로세스와 스레드

프로세스

  • 사전적 의미

    • "컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램"

    • 메모리에 올라와 실행되고 있는 프로그램의 인스턴스

    • 운영체제로부터 시스템 자원을 할당받는 작업의 단위

      • CPU시간
      • 운영되기 위해 필요한 주소 공간
      • 메모리 영역(Code, Data, Stack, Heap)
  • 특징

    • 기본적으로 프로세스당 최소 1개의 스레드(메인스레드)를 가지고 있다.
    • 각 프로세스는 별도의 주소공간에서 실행되며, 한 프로세스는 다른 프로세스의 벼수나 자료구조에 겁근할 수 없다.
    • 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스간의 통신(IPC, inter-process communication)을 사용해야 한다.(Ex. 파이프, 파일, 소켓 통신)

 

스레드

  • 사전적 의미

    • "프로세스 내에서 실행되는 여러 흐름의 단위"
    • 프로세스의 특정한 수행 경로
    • 프로세스가 할당받은 자원을 이용하는 실행의 단위
  • 특징

    • 스레드는 프로세스 내에서 각각 Stack만 따로 할당 받고 Code, Data, Heap 영역은 공유한다.
    • 스레드는 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들을 같은 프로세스 내에 스레드끼리 공유하며 실행된다.
    • 각각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.
    • 한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드(sibling thread)도 그 변경된 결과를 즉시 볼 수 있다.

멀티 프로세스

  • 멀티프로세싱이란?

    • 하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것.
  • 장점

    • 여러 개의 자식 프로세스 중 하나에 문제가 발생하면 그 자식 프로세스만 죽는 것 이상으로 다른 영향이 확산되지 않는다.
  • 단점

    • Context Switching 오버헤드

      • Context Switching과정에서 캐쉬 메모리 초기화 등 무거운 작업이 진행되고 많은 시간이 소모되는 등의 오 버헤드가 발생하기 된다.
      • 프로세스는 각각의 독립된 메모리 영역을 할당받았기 때문에 프로세스 사이에서 공유하는 메모리가 없어, Context Switching이 발생하면 캐쉬에 있는 모든 데이터를 전부 리셋하고 다시 캐쉬정보를 불러와야 한다.
    • 하나의 프로그램에 속하는 프로세스들 사이의 변수를 공유할 수 없다.

 

멀티스레드

  • 멀티스레드란?

    • 하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 것.
    • 웹 서버는 대표적인 멀티 스레드 응용프로그램이다.
    • 윈도우, 리눅스 등 많은 운영체제들이 멀티 스레딩을 기본으로 멀티프로세싱을 지원한다.
  • 장점

    • 시스템 자원 소모 감소(자원의 효율성 증대)

      • 시스템콜(프로세스를 생성하여 자원을 할당하는 과정)이 줄어들어 자원을 효율적으로 관리할 수 있다.
    • 시스템 처리량 증가(처리 비용 감소)

      • 스레드 간 데이터를 주고받는 것이 간단해지고 시스템 자원 소모가 줄어든다.
      • 스레드 사이의 작업량이 작아 Context Switching이 빠르다.
    • 스레드는 프로세스 내의 Stack영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다.

  • 단점

    • 설계 / 디버깅이 까다롭다.
    • 단일프로세스 시스템의 경우 효과를 기대하기 어렵다.
    • 자원을 공유하므로 동기화 문제가 발생한다.
    • 하나의 스레드에 문제가 발생하면 전체 프로세스가 영향을 받는다.

멀티스레드 vs 멀티프로세스

  • 멀티프로세스 대신 멀티 스레드를 사용하는 이유?

    • 프로그램을 여러 개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것이다.
  • 멀티프로세스로 할 수 있는 작업을 멀티 쓰레딩으로 하는 이유?

    • 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
    • 프로세스 간의 Context Switching시 오버헤드가 크기 때문.
    • 스레드는 프로세스 내의 메모리를 공유하기 때문에 스레드간 데이터를 주고 받는 것이 간단해지고 시스템 자원소모가 줄어든다.
MergeSort

MergeSort

merge sort에 대한 이미지 검색결과

 

  • 시간 복잡도 O(n lon n)

 

  • list를 이용해 구현하기

 

  • 배열을 이용해 구현하기

 

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

해시테이블 Hashtable  (2) 2019.05.06
[Java] 배열과 List / Set / Map  (0) 2019.01.22

+ Recent posts