반응형

개념

다익스트라(dijkstra)알고리즘은 다이나믹 프로그래밍(dp)를 활용한 대표적인 최단 경로 탐색 알고리즘이다. 다익스트라 알고리즘은 하나의 정점에서 다른 모든 정점으로 가는 최단 경로를 알려준다.

참고: https://blog.naver.com/PostView.naver?blogId=ndb796&logNo=221234424646&redirect=Dlog&widgetTypeCall=true&directAccess=false

 

23. 다익스트라(Dijkstra) 알고리즘

  다익스트라(Dijkstra) 알고리즘은 다이나믹 프로그래밍을 활용한 대표적인 최단 경로(Shortest P...

blog.naver.com

2차원 배열로 간선의 정보를 저장한다. 서로 연결되어 있지 않은 경우는 무한의 수로 설정한다.

  1. 음의 간선 정보는 포함 할 수 없다.
  2. 방문하지 않은 노드중 가장 비용이 적은 노드를 선택

구현 방법

  1. 간선 정보 2차원 배열로 생성, 최단 거리 배열 생성
#define INF 1e9 //엄청 큰 값인 10억

vector<pair<int,int>> v[10001]; // 비용, 연결점
int d[10001];
fill(d, d+10001, INF);

최단 거리 배열은 가장 작은 값을 나타내야 하기 때문에 우선은 가장 큰 값으로 초기화해 놓는다.

  1. priority_queue를 이용하여 최소비용 순서로 다익스트라 알고리즘 적용
void dijkstra(int start) {
	priority_queue<pair<int,int>> pq;
	pq.push({0,start});
	d[start] = 0;
	
	while(!pq.empty()) {
		int dist = -pq.top().fist; // 현재 노드까지의 비용, 작은것부터 뽑기위해 -로 저장해놨음
		int now = pq.top().second; // 현재 노드
		pq.pop();
	
		if(d[now] < dist) continue; // 현재 노드까지의 비용이 더 크면 볼 것도 없음
	
		for(int i = 0; i < v[now].size(); i++) {
			int cost = dist + v[now][i].first; //현재노드까지의 비용 + 다음 노드로 가는 비용
			if(cost < d[v[now][i].second]) {
				d[v[now][i].second] = cost
				pq.push(make_pair(-cost, v[now][i].second));
			}
		}
	}
}

현재까지의 비용이 가장 적은 노드 선택 후 그 노드와 연결된 노드들의 비용 값을 구한 후 만약 구한 값이 원래의 값보다 더 작다면 값을 업데이트 해 준 후 우선순위 큐에 해당 노드를 넣는다.

전체 코드

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정

// 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start)
// 노드의 개수는 최대 100,000개라고 가정
int n, m, start;

vector<pair<int, int> > graph[100001]; // 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열
int d[100001]; // 최단 거리 테이블 만들기

void dijkstra(int start)
{
    priority_queue<pair<int,int>>pq; // 거리, 노드 인덱스
    
    pq.push({0,start}); //시작 노드로 가기위한 최단 경로는 0으로 설정하여, 큐에 삽입.
    d[start]=0;
    
    while(!pq.empty())
    {
        int dist = -pq.top().first; //현재 노드까지의 비용
        int now = pq.top().second; // 현재 노드
        pq.pop();
        
        if(d[now]<dist) // 이미 최단경로를 체크한 노드인 경우 패스
            continue;
        
        for(int i=0; i<graph[now].size(); i++)
        {
            int cost = dist+graph[now][i].second; // 거쳐서 가는 노드의 비용을 계산
                                                  // 현재노드까지 비용 + 다음 노드 비용
            if(cost<d[graph[now][i].first]) // 비용이 더 작다면 최단경로 테이블 값을 갱신.
            {
                d[graph[now][i].first]=cost;
                pq.push(make_pair(-cost,graph[now][i].first));
            }
        }
    }
}

int main(void)
{
    cin >> n >> m >> start;
    
    // 모든 간선 정보를 입력받기
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        // a번 노드에서 b번 노드로 가는 비용이 c라는 의미
        graph[a].push_back({b, c});
    }
    
    // 최단 거리 테이블을 모두 무한으로 초기화
    fill(d, d + 100001, INF);
    
    // 다익스트라 알고리즘을 수행
    dijkstra(start);
    
    // 모든 노드로 가기 위한 최단 거리를 출력
    for (int i = 1; i <= n; i++)
    {
        // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
        if (d[i] == INF) {
            cout << "INFINITY" << '\\n';
        }
        // 도달할 수 있는 경우 거리를 출력
        else {
            cout << d[i] << '\\n';
        }
    }
}

시간 복잡도

O(N * logN)

 

반응형

'코딩 낙서' 카테고리의 다른 글

카카오기출 - 순위 검색  (0) 2023.06.23
알고리즘 - 인덱스 트리(Index Tree)  (0) 2023.06.21
알고리즘 - 크루스칼(Kruskal)  (0) 2023.06.21
알고리즘 - 누적합(Prefix Sum)  (0) 2023.06.21
알고리즘 - Union & Find  (0) 2023.06.21
반응형

개념

가장 적은 비용으로 모든 노드를 연결하기 위해 사용하는 알고리즘이다. 최소 비용 신장 트리를 만들기 위한 대표적인 알고리즘으로 흔히 여러개의 도시가 있을 때 각 도시를 도로를 이용해 연결하고자 할 때 비용을 최소로 하기 위해 실제로 적용되는 알고리즘이다.

노드 = 정점 = 도시

간선 = 거리 = 비용

일단 모든 노드를 최대한 적은 비용으로 연결 시켜야하기 때문에 간선 정보를 오름차순으로 정렬 한 후 비용이 적은 간선부터 차근차근 그래프에 포함시킨다. 단 이때 사이클을 형성하게 될 경우 간선을 포함하지 않는다.

 

조건

  1. 간선 정보를 오름차순으로 정렬
  2. 사이클이 형성되지 않게 연결

사용하기 좋은 경우

  1. 모든 노드를 최소 비용으로 연결할 경우
  2. 연결되어있는 그룹의 수를 구하는 경우 → 크루스칼 알고리즘으로 다 연결 한 후 최상단 부모의 개수가 그룹의 수이다.

구현 방법

  1. 비용, 출발, 도착의 정보를 갖는 노드들을 비용을 기준으로 오름차순 정렬하기
typedef pair<int, int> pii;
for(int i = 0; i < m; i++) { //a: 출발지점, b: 도착지점, c: 비용
        scanf("%d%d%d", &a, &b, &c);
        v.push_back(pair<int, pii>(c, pii(a,b)));
    }
    int p = 0;
    sort(v.begin(), v.end()); //비용 기준으로 정렬
  1. 최상단 부모 찾기
int parent[10001];

int findParent(int child) {
    if(parent[child] == 0) {
        return child;
    }
    return parent[child] = findParent(parent[child]);
}

parent 배열의 인덱스는 자기 자신을 나타내고 값은 자신의 부모를 나타낸다. 값이 0일경우 부모가 존재하지 않는 것으로 최상단 노드를 의미하기 때문에 값이 0일때를 찾아서 return 한다.

  1. 부모 자식 관계 설정하기, 최소 비용 구하기
int unionSet(pair<int, pii> xy) {
    int xp = findParent(xy.second.first); //출발 지점의 부모 찾기
    int yp = findParent(xy.second.second); //도착 지점의 부모 찾기
    
    if(xp == yp) return xp; //부모가 같으면 이미 연결되어 있는 것이므로 종료
    else { //부모가 다르면 서로 다른 선에 연결되어 있기 때문에 한 쪽의 부모를 다른 쪽 부모에 연결
        cost[xp] += cost[yp] + xy.first; //연결 후 최상단 노드의 비용을 더해줌
        parent[yp] = xp; //한 쪽의 최상단 부모를 다른 쪽 최상단 부모로 설정
    }
    return xp; //새로운 연결선의 최상단 노드
}

부모가 같으면 이미 연결되어있는 상태이고 다르면 서로의 최상단 부모를 연결해준다.

전체 코드

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
typedef pair<int, int> pii;
int n, m, a, b, c, answer;

vector<pair<int, pii>> v;

int parent[10001];
int cost[10001];

int findParent(int child) {
    if(parent[child] == 0) {
        return child;
    }
    return parent[child] = findParent(parent[child]);
}

int unionSet(pair<int, pii> xy) {
    int xp = findParent(xy.second.first);
    int yp = findParent(xy.second.second);
    
    if(xp == yp) return xp;
    else {
        cost[xp] += cost[yp] + xy.first;
        parent[yp] = xp;
    }
    return xp;
}

int main(int argc, const char * argv[]) {
    scanf("%d", &n);scanf("%d", &m);
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &a, &b, &c);
        v.push_back(pair<int, pii>(c, pii(a,b)));
    }
    int p = 0;
    sort(v.begin(), v.end());
    for(int i = 0; i < v.size(); i++) {
        p = unionSet(v[i]);
    }
    answer = cost[p];
    printf("%d", answer);
    
    return 0;
}

시간복잡도

O(logN)

반응형
반응형

개념

말 그대로 구간의 누적의 합을 구하는 알고리즘이다. 배열에 값을 저장하고 하나씩 더해가는 방식은 O(n^2)의 시간 복잡도를 갖는다. 하지만 누적합 알고리즘을 사용한다면 O(n)으로 시간복잡도를 줄일 수 있다. 보통 누적합은 부분 합을 구하기 위해서 사용하는데 만약 a부터 b까지의 합을 구한다고 하면 먼저 누적합을 만들고, b번째 요소에서 a-1번째 요소를 빼주면 구할 수 있다.

사용 하면 좋은 경우

  1. 리스트에 일정 구간의 값의 합을 구할 때
  2. 리스트에 일정 구간에 값을 넣어야 할 경우(시작과 끝 부분에 값 넣어놓고 누적합)

사용 방법

  1. 구간의 합 구하기
import itertools

a = [3,2,1,6,8,4]
result = list(itertools.accumulate(a))

print(result)

🖨️ [3, 5, 6, 12, 20, 24]

  1. 부분 합 구하기
import itertools

a = [3,2,1,6,8,4]
start = 3
end = 5
acc = list(itertools.accumulate(a))

result = acc[end] - acc[start-1]

🖨️ 18

누적합을 우선 구한 후 마지막 부분의 누적합 값에서 시작부분 전의 누적합을 빼서 부분 합을 구할 수 있다,

시간 복잡도

  • O(N)
반응형
반응형

개념

그룹을 지을 때 사용할 수 있는 알고리즘이다. 처음에 자기 자신을 부모로 설정하고 조건에 따라 부모를 설정한다. Find는 자신의 최상위 부모를 찾는 역할을 한다. Union은 두 변수의 부모가 다르다면 하나의 최상위 부모를 다른 하나의 최상위 부모의 자식으로 만들어 두개의 그룹이 합쳐지는 기능을 수행한다.

  • Union by Rank : 트리가 균형이 맞도록 한다. 각 집합에 대해 이 집합을 나타내는 트리의 높이를 rank 변수에 저장한다. 그리고 두 집합을 합칠 때 rank가 작은 집합을 rank가 큰 집합 아래에 붙힌다.
  • Path Compression : 경로 압축(path compression)은 find 과정 가운데 경로 상의 모든 점들을 곧바로 루트 정점에 연결하는 방법이다. 이렇게 하면 위 그림과 같은 구조로 시간 복잡도가 훨씬 줄어들게 된다.

조건

  • Cycle 구조가 생기면 안된다. 따라서 Union은 서로의 부모가 다를때만 해야한다.

사용하기 좋은 경우

  1. 서로 중복되지 않는 부분 집합들로 나눌 때
  2. 그룹의 수를 구할 때

구현 방법

  1. Find
parent = [x for x in range(10)] # 자기 자신이 부모로 초기화

def find_parent(x, parent):
	if parent[x] == x: # x가 최상위 부모
			return x
	#x의 부모중 최상위 부모 찾기
	parent[x] = find_parent(parent[x], parent)
	return parent[x]

  1. Union
def union_parent(a, b, parent):
	pa = find_parent(a)
	pb = find_parent(b)
	if pa == pb :
		pass
	elif pa < pb : # 더 큰애가 부모가 되게 설정
		parent[pa] = pb
	else:
		parent[pb] = pa

시간 복잡도

  • O(M)+O(Mlog⋆N)+O(Nlog⋆N)=O((M+N)log⋆N)
  • (M : find 연산 수, N : 트리가 바뀌는 횟수)
반응형

'코딩 낙서' 카테고리의 다른 글

알고리즘 - 크루스칼(Kruskal)  (0) 2023.06.21
알고리즘 - 누적합(Prefix Sum)  (0) 2023.06.21
알고리즘 - 이진 탐색(이분 탐색)  (0) 2023.06.21
[LINUX] 기본 명령어 정리  (0) 2023.06.20
Linux  (0) 2023.06.14
반응형

개념

이진 탐색이란 데이터가 정렬돼 있는 배열에서 특정한 값을 찾아내는 알고리즘이다. 배열의 중간에 있는 임의의 값을 선택하여 찾고자 하는 값 X와 비교한다. X가 중간 값보다 작으면 중간 값을 기준으로 좌측의 데이터들을 대상으로, X가 중간값보다 크면 배열의 우측을 대상으로 다시 탐색한다. 동일한 방법으로 다시 중간의 값을 임의로 선택하고 비교한다. 해당 값을 찾을 때까지 이 과정을 반복한다.

https://blog.hexabrain.net/246 참고

 

알고리즘 2-2강. 탐색 알고리즘 - 이진 탐색(Binary Search)

[탐색 알고리즘 강좌] 데이터를 찾아보자! 이진 탐색(Binary Search) 이번에는 순차 탐색에 이어 이진 탐색(Binary Search)에 대해 알아보도록 할텐데, 이 '이진 탐색(Binary Search)'이 왜 이진인지 짐작이 가

blog.hexabrain.net

조건

  • 수들이 오름차순 또는 내림차순으로 정렬 되어 있어야 한다.
  • 원하는 값을 찾으면 종료한다. (종료 조건1) → 값을 찾음
  • 왼쪽값이 오른쪽 값보다 커지면 종료한다. (종료조건2) → 값이 없음

사용 하면 좋은 경우

  1. 리스트에서 값을 찾을 때 시간을 단축해야 하는 경우
    • list에서 find() 함수를 사용하거나 반목문으로 값을 찾을 시 O(N)의 시간이 필요하기 때문에 이진 탐색을 사용하면 시간 효율성을 증가 시킨다.
  2. 조건에 맞는 최소 또는 최대값을 찾아야 하는 경우
    • 이러한 경우에는 index를 left, right로 두지 않고 left = 가장 작은 값, right = 가장 큰 값 으로 설정하여 배열에서의 위치가 아닌 조건에 맞는 값을 구 할 수 있도록 한다.

구현 방법

기본 이진 탐색

  1. 반복문
#include <iostream>
#include <vector>

using namespace std;

int BinarySearch(vector<int> num, int target) {
    int left = 0, right =(int) num.size(), mid = 0;
    sort(num.begin(), num.end()); //숫자 오름차순 정렬
    //num : {1, 2, 4, 5, 15, 56, 123, 125, 199, 3215}
    while(left <= right) { //종료 조건
        mid = (left + right) / 2;
        if(num[mid] == target) {// target을 찾았을 때
            return mid;
        }
        else if(num[mid] > target) { //target보다 클 때 -> 왼쪽 수들을 확인
            right = mid - 1;
        }
        else { //target보다 작을 때 -> 오른쪽 수들을 확인
            left = mid + 1;
        }
    }
    return -1;
}

  1. 재귀 함수
#include <iostream>
#include <vector>

using namespace std;
//재귀 함수는 num을 정렬 해서 함수 호출
int RecurBinarySearch(vector<int> num, int target, int left, int right) {
    if(left > right) return -1; //종료 조건
    int mid = (left + right) / 2;
    if(num[mid] == target) { //target을 찾았을 때
        return mid;
    }
    else if(num[mid] > target) { // target보다 클 때
        return RecurBinarySearch(num, target, left, mid-1);
    }
    else { //target보다 작을 때
        return RecurBinarySearch(num, target, mid+1, right);
    }
}

int main(int argc, const char * argv[]) {
    vector<int> num {1,5,2,199,56,3215,125,123,15,4};
    sort(num.begin(), num.end());
    int left = 0, right = (int)num.size();
    cout << RecurBinarySearch(num, 199, left, right) << endl;
    return 0;
}

UpperBound

목표값보다 큰 값이 처음 발견되는 곳 찾기

int UpperBound(vector<int> num, int target) {
    int left = 0, right = (int) num.size(), mid = 0;
    sort(num.begin(), num.end());
    int ans = 0;
    while(left <= right) {
        mid = (left + right) / 2;
        if(num[mid] <= target) { // 목표보다 작거나 같으면 오른쪽 보기
            left = mid + 1;
        }
        else { // 목표보다 크면 답의 후보로 두고 왼쪽 보기
            ans = mid;
            right = mid - 1;
        }
    }
    return ans;
}

LowerBound

목표값보다 작은 값이 처음 발견되는 곳 찾기

int LowerBound(vector<int> num, int target) {
    int left = 0, right = (int) num.size(), mid = 0;
    sort(num.begin(), num.end());
    int ans = 0;
    while(left <= right) {
        mid = (left + right) / 2;
        if(num[mid] >= target) { //목표보다 크거나 같으면 왼쪽 보기
            right = mid - 1;
        }
        else { // 목표보다 작으면 답의 후보로 두고 오른 쪽 보기
            ans = mid;
            left = mid + 1;
        }
    }
    return ans;
}

결과

int main(int argc, const char * argv[]) {
    vector<int> num {1,5,2,199,56,3215,125,123,15,4};
    sort(num.begin(), num.end());
    int left = 0, right = (int)num.size();
    for(int i = 0; i < num.size(); i++) {
        cout << num[i] << " ";
    }
    cout << endl;
    cout << "재귀 : " << RecurBinarySearch(num, 199, left, right) << endl;
    cout << "반복문 : " << BinarySearch(num, 199) << endl;
    cout << "UpperBound : " << UpperBound(num, 199) << endl;
    cout << "LowerBound : " << LowerBound(num, 199) << endl;
    return 0;
}
1 2 4 5 15 56 123 125 199 3215
재귀 : 8
반복문 : 8
UpperBound : 9
LowerBound : 9

시간 복잡도

  • O(logN)
반응형

'코딩 낙서' 카테고리의 다른 글

알고리즘 - 크루스칼(Kruskal)  (0) 2023.06.21
알고리즘 - 누적합(Prefix Sum)  (0) 2023.06.21
알고리즘 - Union & Find  (0) 2023.06.21
[LINUX] 기본 명령어 정리  (0) 2023.06.20
Linux  (0) 2023.06.14
반응형

Linux에서 자주 쓰는 기본 명령어에 대해 간단히 정리해보겠습니다.
우선 ls, cd, mkdir, rm, cp, mv 등의 명령어를 사용하여 파일 시스템을 탐색하고 파일 및 디렉토리를 관리하는 방법에 대해 알아보았습니다.

다음은 일반적으로 사용되는 몇 가지 기본 명령어입니다.

ls: 현재 디렉토리의 파일 및 디렉토리 목록을 표시합니다.
cd: 디렉토리를 변경합니다.
mkdir: 새로운 디렉토리를 생성합니다.
rm: 파일이나 디렉토리를 삭제합니다.
cp: 파일이나 디렉토리를 복사합니다.
mv: 파일이나 디렉토리를 이동하거나 이름을 변경합니다.
pwd: 현재 작업 중인 디렉토리의 경로를 표시합니다.
cat: 파일의 내용을 터미널에 표시합니다.
grep: 텍스트에서 패턴을 찾습니다.
chmod: 파일이나 디렉토리의 권한을 변경합니다.

리눅스 명령어는 다양한 옵션을 제공하여 보다 구체적인 작업을 수행할 수 있다고합니다. 같이 한번 알아보도록 하겠습니다!

각 명령어마다 다양한 옵션이 있으며, 옵션은 주로 하이픈(-)과 함께 사용됩니다. 명령어의 옵션을 사용하면 명령어의 동작을 변경하거나 추가 기능을 활용할 수 있습니다.

여기에 몇 가지 일반적으로 사용되는 명령어와 해당 명령어의 일부 옵션을 예시로 나열하겠습니다:

ls (목록 보기):
-l: 자세한 파일 정보 표시
-a: 숨겨진 파일 및 디렉토리 포함하여 모두 표시
-h: 파일 크기 등을 보기 좋게 사람이 읽을 수 있는 형식으로 표시

cd (디렉토리 변경):
..: 상위 디렉토리로 이동
-: 이전 작업 디렉토리로 이동

mkdir (디렉토리 생성):
-p: 중간 디렉토리가 없으면 자동으로 생성

rm (파일 및 디렉토리 삭제):
-r: 디렉토리와 그 내용을 재귀적으로 삭제 (주의: 신중히 사용)

cp (파일 복사):
-r: 디렉토리와 그 내용을 재귀적으로 복사 (디렉토리 복사 시)

mv (파일 이동 및 이름 변경):
-i: 대상 파일이 이미 존재할 경우 덮어쓰기 전 확인

cat (파일 내용 표시):
-n: 줄 번호 표시

grep (패턴 검색):
-i: 대소문자 구분 없이 검색
-r: 디렉토리 내의 파일에서 재귀적으로 검색

chmod (파일 권한 변경):
u: 소유자(user)에 대한 권한 변경
g: 그룹(group)에 대한 권한 변경
o: 기타 사용자(other)에 대한 권한 변경
+: 권한 추가
-: 권한 제거
=: 권한 설정

반응형

'코딩 낙서' 카테고리의 다른 글

알고리즘 - 크루스칼(Kruskal)  (0) 2023.06.21
알고리즘 - 누적합(Prefix Sum)  (0) 2023.06.21
알고리즘 - Union & Find  (0) 2023.06.21
알고리즘 - 이진 탐색(이분 탐색)  (0) 2023.06.21
Linux  (0) 2023.06.14
반응형

개발자를 꿈꾼다면 Linux란 말은 한번씩 들어 봤을 것입니다. 본 게시글에서는 Linux가 무엇인지 왜 쓰는지 등에 대해 공부해보겠습니다. 최근에는 도커와 같은 컨테이너 툴을 사용하며 리눅스의 인기가 사그러드는 추세지만 아직도 기업에서는 리눅스를 활용하는 경우가 많아, 최소한의 정보는 익혀두는 것이 좋습니다. 

리눅스란 무엇인가? 


리눅스는 리누스 토발즈(Linus Torvalds)가 1991년에 개발한 오픈 소스 운영 체제의 커널입니다. 이 운영 체제는 컴퓨터 시스템에서 동작하는 소프트웨어로, 다양한 하드웨어 플랫폼에서 실행될 수 있습니다.

 

리눅스는 **유닉스(Unix)** 운영 체제에서 영감을 받아 개발되었습니다. 유닉스는 고성능과 안정성을 가진 운영 체제로서 기업과 대학 등에서 주로 사용되었으나, 상용 소프트웨어로서의 비용과 제한된 소스 코드 접근성 등의 이유로 개인이나 소규모 조직에서는 사용하기 어려웠습니다.

리눅스의 등장은 이러한 상황을 바꿔놓았습니다. 리눅스는 오픈 소스로 개발되어 소스 코드에 대한 자유로운 액세스를 제공합니다. 이는 많은 개발자들이 소프트웨어의 수정과 개선에 참여할 수 있게 하였고, 커뮤니티의 지속적인 기여와 협업을 가능하게 했습니다. 따라서 리눅스는 빠른 업데이트와 보안 패치, 성능 향상을 이끌어냈습니다.

 


개발자는 리눅스를 왜 쓸까?

 

윈도우, 맥OS, 안드로이드, iOS 등의 운영 체제들은 일반 사용자를 대상으로 GUI를 중심으로 개발되어 사용이 편리하도록 설계되었습니다. 이러한 운영 체제들은 이미 다양한 기능과 소프트웨어가 개발되어 제공되기 때문에 일반 사용자들이 필요한 기능을 간단하게 사용할 수 있도록 최적화되어 있습니다.

 

리눅스 배포판과 종류



리눅스 배포판은 리눅스 커널을 기반으로 한 운영 체제의 완전한 패키지로, 사용자들이 특정 목적과 요구에 맞게 선택할 수 있도록 다양한 변형이 이루어진 형태입니다. 각 배포판은 기본적으로 리눅스 커널과 함께 필요한 시스템 도구, 라이브러리, 응용 프로그램 등을 포함하고 있으며, 개발 및 사용자 경험에 영향을 미칩니다. 

그럼 배포판 중에서 인기있는 배포판에 대해 몇 가지 말씀드리겠습니다.

1. Ubuntu

Ubuntu는 사용자 친화적인 인터페이스와 다양한 소프트웨어 지원으로 인기 있는 배포판입니다. 사용하기 쉬우며, 개인용 컴퓨터, 노트북, 서버 등 다양한 플랫폼에서 사용됩니다. 기본적으로 **GNOME 데스크톱 환경**을 제공하며, LTS(Long-Term Support) 버전은 장기 지원을 받습니다.

2. CentOS

CentOS는 R**ed Hat Enterprise Linux(RHEL)**을 기반으로 한 무료 및 오픈 소스 배포판입니다. 서버 환경에서의 안정성과 보안을 중요시하는 사용자들에게 인기가 있습니다. RHEL과 호환되며, 엔터프라이즈 환경에서 신뢰성과 지원을 제공합니다.

3. Fedora

Fedora는 **최신 기술과 소프트웨어를 선도적**으로 채용하는 배포판입니다. 개발자와 엔터프라이즈 사용자를 대상으로 하며, 기본적으로 **GNOME 데스크톱 환경**을 제공합니다. 최신 기술의 실험적인 측면을 갖고 있으므로, 최신 기능을 빠르게 경험하고자 하는 사용자에게 적합합니다.

4. Debian

Debian은 **안정성과 보안성을 강조**하는 배포판으로, 다양한 아키텍처와 사용 가능한 패키지의 풍부함으로 알려져 있습니다. 다양한 데스크톱 환경을 지원하며, 개인용 컴퓨터부터 서버까지 다양한 용도로 사용할 수 있습니다.

5. Arch Linux

Arch Linux는 **사용자 중심의 배포판**으로, 최소한의 기본 설치를 제공하고 나머지 시스템을 사용자가 직접 구성하는 방식을 채택하고 있습니다. 최신 소프트웨어와 커뮤니티 주도의 개발에 초점을 두고 있으며, **직접적인 제어와 맞춤 설정**을 원하는 사용자에게 인기가 있습니다.

**GNOME 데스크톱 환경이란?
GNOME은 GNU Network Object Model Environment의 약자로 리눅스 배포판과 함께 제공되는 기본적인 그래픽 사용자 인터페이스를 제공하는 소프트웨어 패키지 모음입니다.

반응형

'코딩 낙서' 카테고리의 다른 글

알고리즘 - 크루스칼(Kruskal)  (0) 2023.06.21
알고리즘 - 누적합(Prefix Sum)  (0) 2023.06.21
알고리즘 - Union & Find  (0) 2023.06.21
알고리즘 - 이진 탐색(이분 탐색)  (0) 2023.06.21
[LINUX] 기본 명령어 정리  (0) 2023.06.20

+ Recent posts