<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jungeun-dev.log</title>
        <link>https://velog.io/</link>
        <description>성장하는 개발자_💻</description>
        <lastBuildDate>Tue, 21 Feb 2023 17:06:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jungeun-dev.log</title>
            <url>https://images.velog.io/images/jungeun-dev/profile/1b01d1db-1a17-4ba0-bcc4-3ca687e2fb57/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jungeun-dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jungeun-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[BOJ/백준] 2447 - Python]]></title>
            <link>https://velog.io/@jungeun-dev/BOJ%EB%B0%B1%EC%A4%80-2447-Python</link>
            <guid>https://velog.io/@jungeun-dev/BOJ%EB%B0%B1%EC%A4%80-2447-Python</guid>
            <pubDate>Tue, 21 Feb 2023 17:06:29 GMT</pubDate>
            <description><![CDATA[<h2 id="problem-💻">Problem 💻</h2>
<p><img src="https://velog.velcdn.com/images/jungeun-dev/post/2eb97aa7-a637-468c-8355-8a1dcd8242c3/image.png" alt=""></p>
<h3 id="example">Example</h3>
<p><img src="https://velog.velcdn.com/images/jungeun-dev/post/cba70ceb-6795-4fd1-96c6-5af6e1966690/image.png" alt=""></p>
<h2 id="solution-🔥">Solution 🔥</h2>
<ul>
<li>문제 초반에 &quot;재귀적인 패턴으로 별을 찍어 보자&quot;라고 적혀있다
  이에 재귀함수로 이 문제를 풀려고 하니 도저히 풀리지 않아 다른 코드를 보고 이를 이해하는데에 목적을 두었다.
  <img src="https://velog.velcdn.com/images/jungeun-dev/post/82611e23-1183-4adf-97d1-f5b10d38d536/image.png" alt="">
다음 그림은 오랜만에 재귀를 풀어 봤길래 정리하는겸 어떤식으로 재귀함수가 돌아가는지 순서를 적어봤다.
n = 27 의 경우이다.
star(27)의 함수를 처음 호출하고 함수 내에서 star(9) 호출, star(3)호출, star(1) 호출이 되고 star(1) 함수가 가장 먼저 반환되고 그다음 차례대로 star(3), star(9), star(27)이 반환된다.</li>
</ul>
<blockquote>
<p><span style="color: rgba(188,218,243)"><strong>그렇다면 재귀에서 가장 중요하게 생각해야하는 건 무엇일까?</strong> </span></p>
</blockquote>
<ol>
<li>어디가 끝인가? =&gt; 여기서는 n = 1이 되는 경우이다 이때 반환 되는 것이 최소 단위가 된다는 것 또한 중요하다<blockquote>
</blockquote>
</li>
<li>어떻게 반복되는가?
여기서는 밑의 코드에서와 같이 for문을 참고하면 어떠한 반복이 이루어지는지 알수 있을 것이다. 대충 퉁쳐서 말하자면 이 문제는 &quot;*3&quot; 이라고 할수있겠다.(정확한 반복은 for문과 이미지 참고)
<img src="https://velog.velcdn.com/images/jungeun-dev/post/29df74c3-48ba-4446-8d68-2dd5355f4718/image.png" alt=""></li>
</ol>
<h2 id="code">Code</h2>
<pre><code class="language-python">def star(n):
    if n == 1:
        return [&#39;*&#39;]
    stars = star(n//3)
    li = []

    for s in stars:
        li.append(s*3)
    for s in stars:
        li.append(s+&#39; &#39;*(n//3)+s)
    for s in stars:
        li.append(s*3)
    return li

n = int(input())
print(&#39;\n&#39;.join(star(n)))</code></pre>
<h3 id="출처">출처</h3>
<p><a href="https://lucian-blog.tistory.com/57">https://lucian-blog.tistory.com/57</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Entity Framework(EF)]]></title>
            <link>https://velog.io/@jungeun-dev/Entity-Framework</link>
            <guid>https://velog.io/@jungeun-dev/Entity-Framework</guid>
            <pubDate>Mon, 14 Nov 2022 23:05:40 GMT</pubDate>
            <description><![CDATA[<p>ASP.NET를 공부하던 중 EF가 무엇인가에 막혀서 찾아본 EF</p>
<h2 id="entity-frameworkef">Entity Framework(EF)</h2>
<p>C#과 같은 객체 지향형 프로그래밍(OOP)에서 데이터베이스를 쉽게 사용하기 위한 ORM(Object-Relational Mapping)도구
 =&gt; 객체(Object)와 관계형(Relational) 데이터베이스의 테이블을 Mappin하여 쉽게 데이터에 접근 할 수 있다</p>
<p> Microsoft가 직접 구현한 ORM으로는 EF와 LINQ TO SQL이 있다</p>
<ul>
<li>Code First
먼저 C# 클래스로 테이블의 구조를 정의한다. 클래스의 속성을 테이블의 column에 Mapping한다.
미리 DB를 설계하지 않고 C# 클래스들로 Domain object를 정의하고 프로그램 실행시 DB가 없으면 자동으로 생성하는 방식</li>
</ul>
<ul>
<li><p>Model First
기존 DB가 없을 때 직접 Visual Model Designer에 Entity들을 하나씩 추가해 나가면서 Data Model을 구성하는 방식</p>
</li>
<li><p>Database First
기존 DB로부터 테이블 구조들을 읽어 Visual Model을 구성하는 방식</p>
</li>
</ul>
<h3 id="reference-list">Reference List</h3>
<p><a href="https://www.csharpstudy.com/web/article/8-Entity-Framework">https://www.csharpstudy.com/web/article/8-Entity-Framework</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[API 그리고 Endpoint]]></title>
            <link>https://velog.io/@jungeun-dev/APIvsEndpoint</link>
            <guid>https://velog.io/@jungeun-dev/APIvsEndpoint</guid>
            <pubDate>Mon, 14 Nov 2022 22:36:29 GMT</pubDate>
            <description><![CDATA[<p>Microsoft 문서를 읽는데 endpoint라는데 그게 뭔지 몰라 찾아보았다.
근데 api랑 매번 같이 설명을 해주길래 같이 정리 !</p>
<h2 id="api-application-programming-interface">API (Application Programming Interface)</h2>
<h3 id="api가-무엇인가">API가 무엇인가?</h3>
<p>api라는 맥락에서 Application은 고유한 기능을 가진 모든 소프트웨어를 나타낸다.
Interface는 두 application 간의 서비스 계약이라고 할 수 있는데, 이 계약은 요청과 응답을 사용하여 두 Application이 통신하는 방법을 말한다.</p>
<h3 id="api는-어떻게-작동하는가">API는 어떻게 작동하는가?</h3>
<p>보통 clien와 server 측면으로 설명하는데 요청을 보내는 application을 client, 응답을 보내는 application을 server라고 한다.</p>
<p>API가 생성된 시기와 이유에 따라 네가지 방식이 있다.</p>
<ul>
<li><p>SOAP API
과거에 많이 사용했던 API로 단순 객체 프로토콜을 사용하며, 클라이언트와 서버는 XML을 사용하여 메세지를 교환한다</p>
</li>
<li><p>RPC API
원격 프로시저 호출이라고 하는데, 클라이언트가 서버에서 함수나 프로시저를 완료하면 서버가 출력을 클라이언트로 다시 전송한다</p>
</li>
</ul>
<p>사실 위 두개는 별로 들어본 적이 없다. 밑에 두개는 많이 들어봤을 것이다</p>
<ul>
<li><p>Websocket API
JSON 객체를 사용하여 데이터를 전달하는 최신 웹 API로 클라이언트앱과 서버 간의 양방향 통신을 지원한다. 서버가 연결된 클라이언트에 콜백 메세지를 전송할 수 있어 REST API보다 효율적이다.</p>
</li>
<li><p>REST API
가장 많이 사용되고 있는 API로 클라이언트가 서버에 요청을 데이터로 전송한다. 서버가 이 클라이언트 입력을 사용하여 내부 함수를 시작하고 출력 데이터를 다시 클라이언트에 반환한다.</p>
</li>
</ul>
<h2 id="endpoint">Endpoint</h2>
<h3 id="그래서-endpoint가-뭔데">그래서 endpoint가 뭔데?</h3>
<p>api는 한마디로 클라이언트으로부터 요청을 받고 서버로부터 요청에 대한 응답을 전송하는 것이라고 할 수 있다.
여기서 endpoint는 요청을 받아 응답을 제공하는 서비스를 사용할 수 있는 지점을 의미한다</p>
<p>예를 들어 영화 평가를 제공하는 웹서비스가 있다고 할 때, 사용자는 원하는 영화를 검색해 볼 것이다.
이 때 해당 영화에 대한 평가를 이용하기 위한 요청이 향하는 URL이 endpoint 이다.</p>
<h4 id="reference-list">Reference list</h4>
<p><a href="https://aws.amazon.com/ko/what-is/api/">https://aws.amazon.com/ko/what-is/api/</a>
<a href="https://blog.hubspot.com/website/api-endpoint">https://blog.hubspot.com/website/api-endpoint</a>
<a href="https://blog.naver.com/ghdalswl77/222401162545">https://blog.naver.com/ghdalswl77/222401162545</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Local Database vs Remote Database]]></title>
            <link>https://velog.io/@jungeun-dev/Local-Database-vs-Remote-Database</link>
            <guid>https://velog.io/@jungeun-dev/Local-Database-vs-Remote-Database</guid>
            <pubDate>Thu, 10 Nov 2022 22:37:38 GMT</pubDate>
            <description><![CDATA[<p>다들 로컬 데이터베이스 이러는데 뭔지 대충 알 것 같으면서도 제대로 된 설명을 본적이 없어서
내가 생각하는게 맞겠지...?라는 생각을 했었다</p>
<p>그래서 정리하는 Local Database 와 Remote Database</p>
<p><img src="https://velog.velcdn.com/images/jungeun-dev/post/44f70163-8aa9-4b9f-b409-43b4cb38ee21/image.png" alt=""></p>
<h2 id="local-database">Local Database</h2>
<p>local = 지역 remote = 원격
이름만 봐도 상대적으로 작은 범위이다.</p>
<p>local database는 어플리케이션과 동일한 시스템에 상주한다.
즉 우리의 핸드폰이나 태블릿 안에 있는 지역 저장소이다.</p>
<p>장점 : database에 접근하기 위해 네트워크 통신을 거쳐 server에 접근 할 필요가 없어 원격 데이터베이스 서버 보다 빠르다.</p>
<p>단점 : 동기화가 어렵다.
상호작용이 불가능하다.</p>
<p>주로 소규모의 데이터를 저장하고 관리할 때 사용하는 데이터베이스이다</p>
<p>SQLite, Room, Realm 등이 있다</p>
<h2 id="remote-database">Remote Database</h2>
<p>외부에서 접근이 가능하도록 네트워크 통신을 거쳐 서버에 도착한 뒤 데이터베이스에 접근하여 데이터를 불러오는 방식이다.</p>
<p>Remote Database의 경우 네트워크 통신에 영향을 많이 받고 대규모의 데이터를 저장하고 관리할 때 사용하는 데이터베이스이다.
Local Database의 경우 동기화와 상호작용이 불가능했지만 Remote Database는 상호작용이 가능하고 이 또한 실시간 접근이 가능하다.</p>
<p>Orcale, MySQL, MSSQL 등이 있다.</p>
<h3 id="reference">Reference</h3>
<p><a href="https://blog.naver.com/winner23456/222641014262">https://blog.naver.com/winner23456/222641014262</a>
다음 블로그를 읽으며 다시 정리하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 최소신장트리(MST)]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%B5%9C%EC%86%8C%EC%8B%A0%EC%9E%A5%ED%8A%B8%EB%A6%ACMST</link>
            <guid>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%B5%9C%EC%86%8C%EC%8B%A0%EC%9E%A5%ED%8A%B8%EB%A6%ACMST</guid>
            <pubDate>Sat, 05 Nov 2022 10:38:23 GMT</pubDate>
            <description><![CDATA[<h3 id="-❔-최소-신장-트리mst란-❔-">** ❔ 최소 신장 트리(MST)란? ❔ **</h3>
<p>** &lt; MST : Minimum Spanning Tree&gt; **</p>
<ul>
<li>신장 트리 중 가중치의 합이 최소가 되는 신장트리</li>
<li>여러개가 존재할 수도 있다.</li>
<li>경로 연결간에 가장 저렴한 경로를 찾는데 사용</li>
<li>순환되면 안된다</li>
<li>MST의 간선의 개수 = n - 1</li>
<li>탐욕법(Greedy) 알고리즘 중 하나</li>
</ul>
<h3 id="탐욕법-greedy">탐욕법 (Greedy)</h3>
<ul>
<li><p>구성 : 다양한 선택, 모음, 또는 찾아야 할 값들</p>
</li>
<li><p>목표 : 구성에 할당된 점수가 존재하며 , 이를 최대화 또는 최소화 해야하는 상황</p>
</li>
<li><p>탐욕적 선택 속성 
=&gt; 출발 구성으로부터 시작하여 지속적인 지역적 향상을 통해 전체 최적해를 찾을 수있는 경우 사용</p>
<p>ex) 잔돈 거스르기 문제 =&gt; 가능한 항상 제일 큰 동전으로 거슬러 준다</p>
<ul>
<li>동전 종류 (32,8,1) =&gt; O</li>
<li>동전 종류 (30,20,5) =&gt; X 
=&gt; 탐욕적 선택 속성 없음 =&gt; 40원은 2개의 20원으로 가능하지만 30원 1개, 5원 2개를 하게 될것</li>
</ul>
</li>
</ul>
<h4 id="prim-jarnik-알고리즘">Prim-Jarnik 알고리즘</h4>
<ul>
<li>대상 : 단순 연결 무방향 가중 그래프</li>
<li>임의의 정점 s를 택하여 s로부터 시작하여, 현 단계에서 갈 수 있는 모든 곳을 검색해 가장 저렴한 곳 연결 (순환이 되면 X)</li>
<li>n개의 노드를 채울때까지 반복</li>
<li>우선 순위 큐 (이진 힙)이용</li>
</ul>
<p>&lt;핵심&gt;</p>
<blockquote>
<p>트리에 속하지 않은 정점들 중
트리에 인접한 간선에서 
최소의 가중치를 갖는 간선을 선택한다는 것이다.</p>
</blockquote>
<blockquote>
<p>visited 리스트를 이용하여 처리
정점이 트리에 속해질 때마다 정점의 인접 간선 정보 업데이트 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mac Terminal Command]]></title>
            <link>https://velog.io/@jungeun-dev/Mac-Terminal-Command</link>
            <guid>https://velog.io/@jungeun-dev/Mac-Terminal-Command</guid>
            <pubDate>Tue, 01 Nov 2022 14:14:04 GMT</pubDate>
            <description><![CDATA[<p>** CLI**
Command Line Interface 로 터미널에서 텍스트를 통해 컴퓨터를 조작하는 명령어 기반의 인터페이스</p>
<p>** GUI **
Graphic User Inter face 로 CLI와 다르게 화면에서 마우스를 통해 컴퓨터를 조작하는 그래픽 기반의 유저 페이스</p>
<h2 id="terminal-command">Terminal Command</h2>
<ul>
<li><p>pwd : 현재 디렉토리</p>
</li>
<li><p>ls : 현재 디렉토리 파일 리스트 보기</p>
</li>
<li><p>cd : 디렉토리 이동</p>
</li>
<li><p>mkdir &quot;폴더명&quot; : 디렉토리 생성</p>
</li>
<li><p>rmdir : 디렉토리 삭제 (내부에 파일이 없을 때만)
rm -r test =&gt; 내부까지 삭제</p>
</li>
<li><p>clear : 현재 화면 클리어</p>
</li>
<li><p>touch : 파일 생성
(touch test.txt)</p>
</li>
<li><p>rm : 파일 삭제</p>
</li>
<li><p>mv : 파일 이동
mv test.txt test (test 폴더로 이동시키기)</p>
</li>
<li><p>mv : 파일/디렉토리 이름 바꾸기
mv test.txt test2.txt (test2로 이름변경)</p>
</li>
<li><p>open : Explorer / Finder 에서 열기</p>
</li>
<li><p>cat : 파일 내용 확인
(concatenate 약자, cat test.txt)</p>
</li>
<li><p>history : 이전에 사용한 명령어 확인</p>
</li>
<li><p>man : 명령어 메뉴얼 확인</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[명품 JAVA Programming] CH2]]></title>
            <link>https://velog.io/@jungeun-dev/%EB%AA%85%ED%92%88-JAVA-Programming-CH2</link>
            <guid>https://velog.io/@jungeun-dev/%EB%AA%85%ED%92%88-JAVA-Programming-CH2</guid>
            <pubDate>Sat, 19 Feb 2022 08:44:34 GMT</pubDate>
            <description><![CDATA[<p>java 프로그래밍 수업을 들어놓고
그 뒤로 안 쓰다가 지금 쓰려니 기억이 안나서 
하루 날 잡아서 빠르게 훝어보려고 한다.
이미 모두 아는 내용을 빠르게 훝어보는 거기에 프로그래밍의 아주 기초적인 책 내용까지는 적지 않을 것이다</p>
<h3 id="21-기본-구조">2.1 기본 구조</h3>
<p>Hello.java</p>
<pre><code class="language-java">
public class Hello{
    public static int sum(int n, int m){
        return n+m;
    }

    public static void main(String[] args){
        int i = 20;
        int s;
        char a;

        s = sum(i,10);
        System.out.println(a);
    }
}</code></pre>
<p>main 메소드에서 실행 시작 </p>
<h3 id="22-식별자">2.2 식별자</h3>
<ul>
<li>클래스 이름 : 첫번째 문자는 대문자로 시작</li>
<li>변수, 메소드 이름 : 첫단어는 소문자로 시작, 각 단어의 첫번째는 대문자로 표기
  ex) myAge, myName</li>
<li>상수 이름: 전체 대문자로 표기</li>
</ul>
<h3 id="23-데이터-타입">2.3 데이터 타입</h3>
<ul>
<li>기본 타입 :<ul>
<li>boolean</li>
<li>char</li>
<li>byte</li>
<li>short</li>
<li>int </li>
<li>long</li>
<li>float</li>
<li>double
(문자열은 기본 타입 X , 자바 라이브러리에서 제공하는 String class 이용)</li>
</ul>
</li>
</ul>
<ul>
<li>레퍼런스 타입
=&gt; c/c++의 포인터와 비슷한 개념이지만 실제 주소 값을 가지지는 않는다.</li>
</ul>
<pre><code class="language-java">int n = null ; //불가능 =&gt; null은 객체 레퍼런스에만 사용 가능
String str = null; // 정상

// var keyword
// var의 사용은 지역 변수에만 한정된다.

var price = 200 ;
var name = &quot;kitae&quot;;
var pi = 3.14;
var point = new Point();

// 상수 선언
final double PI = 3.141592

// 강제 타입 변환 ( casting )
int n = 300;
byte b = n ; //compile error

// b에는 44 로 저장됨 300 % 256 = 44 byte(1byte) , int(4byte)
byte b = (byte)n ; // n을 byte 타입으로 강제 변환
</code></pre>
<h3 id="24-키-입력">2.4 키 입력</h3>
<ul>
<li><p>System.in
키보드 장치를 직접 제어하고 키 입력을 받는 표준 입력 스트림 객체
=&gt; 단순한 바이트 정보로 응용프로그램에 전달 =&gt; 잘 사용 안함</p>
</li>
<li><p>Scanner class 이용</p>
</li>
</ul>
<pre><code class="language-java">import java.util.Scanner;

Scanner scanner = new Scanner(System.in);
String name = scanner.next();
int age = scanner.nextInt();
double weight = scanner.nextDouble();
String line = scanner.nextLine(); // &#39;\n&#39;까지 읽고  &#39;\n&#39;을 제외한 너머지 문자열 저장

//scanner 객체 close
scanner.close();
</code></pre>
<p> =&gt; Scanner 객체를 이용하여 키보드로부터 바이트 정보를 받고, 이를 원하는 타입으로 변환하여 제공
 =&gt; 공백문자를 기준으로 분리하여 토큰 단위로 읽는다.</p>
<h3 id="25-연산">2.5 연산</h3>
<ul>
<li><p>연산자는 모든 프로그래밍 기본과 동일 하기에 작성하지 않겠다.
우선순위만 한번 확인하자
<img src="https://images.velog.io/images/jungeun-dev/post/11423793-9908-481b-a9d6-eb4d93955e16/image.png" alt=""></p>
<h3 id="26-조건문">2.6 조건문</h3>
<h4 id="--if-문">- if 문</h4>
<pre><code class="language-java">if (n % 2 == 0) {
  System.out.println(n + &quot;is Even.&quot;);
}
else if(조건문){
}
else(조건문){
}</code></pre>
</li>
</ul>
<h4 id="--switch-문">- switch 문</h4>
<pre><code class="language-java">//switch 문

switch (score/10){
    case 10: 
    case 9:
        grade = &#39;A&#39;;
        break;
    case 8: 
        grade = &#39;B&#39;;
        break;
       default:
        grade = &#39;F&#39;;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] (Graph) 가장 먼 노드 [C++]]]></title>
            <link>https://velog.io/@jungeun-dev/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Graph-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C-C</link>
            <guid>https://velog.io/@jungeun-dev/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Graph-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C-C</guid>
            <pubDate>Mon, 13 Dec 2021 06:51:44 GMT</pubDate>
            <description><![CDATA[<p>👉 <a href="https://programmers.co.kr/learn/courses/30/lessons/49189">문제 확인 (프로그래머스 - 가장 먼 노드 )</a> 👈</p>
<p><img src="https://images.velog.io/images/jungeun-dev/post/0cea6cdb-d025-4577-b4ab-4521b62b3cb2/image.png" alt=""><img src="https://images.velog.io/images/jungeun-dev/post/cb3ab24f-ff9b-4174-94d9-4015e60db249/image.png" alt=""></p>
<h3 id="🤍-접근">🤍 접근</h3>
<p>처음에는 dfs로 접근하였는데 위의 예시에서 1, 3, 2 와 같은 경우에서 
1과 2 사이의 거리는 1인데 1-&gt;3-&gt;2와 같이 측정되어 거리가 2로 인식되는 오류가 생겼다. 그래서 bfs로 다시 접근하여보았다.</p>
<h3 id="완성-코드">완성 코드</h3>
<pre><code class="language-c++">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;queue&gt;

using namespace std;

//bfs =&gt; 최단경로 ,미로찾기 같은거 &lt;= queue 이용

int solution(int n, vector&lt;vector&lt;int&gt;&gt; edge) {
    int answer = 0;
    vector&lt;vector&lt;int&gt;&gt; graph(n+1);
    vector&lt;bool&gt; visited(n+1,false);
    queue&lt;int&gt; q;
    vector&lt;int&gt; distance(n +1 , 0);

    for(vector&lt;int&gt; e : edge){
        graph[e[0]].push_back(e[1]);
        graph[e[1]].push_back(e[0]);
    }
    q.push(1);
    visited[1] = true;

    while(!q.empty()){
        int start = q.front();
        q.pop();

        for(int i = 0; i &lt; graph[start].size() ; i++){
            int end = graph[start][i];
            if(!visited[end]){
                visited[end] = true;
                distance[end] = distance[start] + 1;
                q.push(end);
            }
        }
    }

    sort(distance.rbegin(), distance.rend()); // 내림차순
    for(int d : distance){
        if(d == distance[0]) answer++;
        else break;
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[이산 수학] Bayes Theorem]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%9D%B4%EC%82%B0-%EC%88%98%ED%95%99-Bayes-Theorem</link>
            <guid>https://velog.io/@jungeun-dev/%EC%9D%B4%EC%82%B0-%EC%88%98%ED%95%99-Bayes-Theorem</guid>
            <pubDate>Wed, 08 Dec 2021 15:36:19 GMT</pubDate>
            <description><![CDATA[<p>여태까지 베이즈 정리를 그냥 조건부 확률이라고만 알고있었다. 단단히 잘못 알고있었다.
그래서 매번 시험에서 틀리는데 틀리는 이유조차 모르고 학기를 끝냈었다. 
이번에 확실하게 알아보자! </p>
<h2 id="✅-bayes-theorem">✅ Bayes&#39; Theorem</h2>
<h3 id="--베이즈-정리의-의미와-의의">- 베이즈 정리의 의미와 의의</h3>
<p>베이즈 정리는 단순히 조건부 확률을 풀어낸것이 아니다. 
새로운 정보를 토대로 어떤 사건이 발생했다는 ** 주장에 대한 신뢰도를 갱신 ** 해 나가는 방법이다.</p>
<h3 id="--베이지안-주의bayesianism">- 베이지안 주의?(Bayesianism)</h3>
<p>또한 베이지안 주의 관점으로 확률을 보면 전통적인 확률관(빈도주의)와는 다르다. 
베이지안 주의 관점으로 보면 확률은 &quot;주장에 대한 신뢰도&quot;라고 할수있다.
예를 들어 주사위를 던져 1이 나올 확률을 1/6하는 것을 빈도주의에서는 600번 던졌을때 100번은 1이 나올 것이다 해석하는 것이고, 베이지안 주의에서는 주사위가 1이 나왔다는 주장의 신뢰도가 1/6라고 보는 것이다.</p>
<h3 id="--용어">- 용어</h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/49797136-0841-42af-80fe-d665c85aa910/image.png" alt="">
H : Hypothesis (가설) =&gt; 어떤 사건이 발생했다는 주장
E : Evidence (증거) =&gt; 새로운 정보
<img src="https://images.velog.io/images/jungeun-dev/post/74f0fbb1-22bf-40d2-876f-f064f2ab9cc8/image.png" alt="">
Posterior probability : 사후 확률
Likelihood : 우도 (가능성)
Prior probability : 사전 확률
Evidence : 증거</p>
<p>베이즈 정리는 두 확률 변수의 <strong>사전 확률</strong>과 <strong>사후 확률</strong> 사이의 관계를 나타내는 정리다. 
베이즈 확률론 해석에 따르면 베이즈 정리는 <strong>사전확률</strong>로부터 <strong>사후확률</strong>을 구할 수 있다.
먼저 단어부터 들이대 보았다. 근데 또 일단 문제부터 한번 풀어보자.
가장 흔한 예시 질병이다.</p>
<h4 id="예제">예제</h4>
<p>질병 A의 발병률은 0.1%로 알려져있다. 이 질병이 실제로 있을 때 질병이 있다고 검진할 확률(민감도)은 99%, 질병이 없을 때 없다고 실제로 질병이 없다고 검진할 확률(특이도)는 98%라고 하자.</p>
<p>만약 어떤 사람이 질병에 걸렸다고 검진받았을 때, 이 사람이 정말로 질병에 걸렸을 확률은?</p>
<h4 id="📜-solution">📜 solution</h4>
<p> -&gt; 먼저 hypothesis와 Evidence를 정의해보자</p>
<blockquote>
<p>evidence : 새로운 정보 =&gt; 질병에 걸렸다고 검진을 받았을때 (positive)
hypothesis : 주장 =&gt; 정말로 질병에 걸렸다
=&gt; 구하고자 하는 것 : P(H|E)</p>
</blockquote>
<p>그러므로 </p>
<blockquote>
<p>질병 A의 발병률은 0.1%이므로 
임의의 사람이 이 질병에 걸렸을 확률은 P(H)로 쓸 수 있으며,  ** P(H)=0.001 ** 이다.</p>
</blockquote>
<p>민감도:
$$
P(E|H)=0.99
$$
특이도 :
$$
P(E^c|H^c)=0.98 
$$</p>
<p>위의 식 
<img src="https://images.velog.io/images/jungeun-dev/post/5c6906cd-68cc-4332-a171-bc9d99123fe8/image.png" alt="">
와 같이 조건부 확률만 알아도 풀 수 가있다.
하지만 베이즈 정리의 진정한 의의는 알기 어렵다. 
베이즈 정리의 진정한 의의는 </p>
<blockquote>
<p>** 사전확률을 모르는 상황에서 사전확률을 가정하고, 
발생한 사건(새로운 정보)를 토대로 사전확률을 &quot;갱신&quot; 해나가는데 있다. ** </p>
</blockquote>
<p>다음 예시를 보자.</p>
<h4 id="예제-1">예제</h4>
<p>상대가 나를 좋아하는지 궁금한 상황이다. 그런데 상대방이 먼저 나에게 디엠이 왔다고 하자. 
여기서 사전확률은 그가 나를 좋아할 확률이다. 그가 나를 좋아할 확률? 잘모르겠다. 
좋아하지도 싫어하지도 않는것 같다. 그러면 좋아할 확률을 0.5라고 사전확률을 놓자. 
$$
P(L) = 0.5
$$
이제 상대방의 행동을 기반으로 사전확률을 갱신해나갈 것이다. 
상대방의 행동 =&gt; 나에게 디엠을 보낸 것이다
이제 알아야 할 것은</p>
<blockquote>
<p>상대방이 나를 좋아하는데 먼저 디엠을 보낼 확률 : P(D|L)
상대방이 나를 좋아하지않는데 먼저 디엠을 보낼 확률 : P(D|L&#39;)</p>
</blockquote>
<p>이 확률을 안다는 것이 비현실적이긴 하지만 여러명을 조사해본결과
P(D|L) = 0.6
P(D|L&#39;) = 0.4 이라고 하자
<img src="https://images.velog.io/images/jungeun-dev/post/e895f161-8d0c-46e1-af15-75aba2d03c90/image.png" alt=""></p>
<p>그렇다면 다음과 같이 구할수있다. 
그러면 디엠을 받음으로써 상대방이 날 좋아 할 확률이 0.6로 갱신되었다. 
이것을 베이즈 갱신이라 하며 갱신된 확률을 사후 확률이라고 한다.</p>
<p>이 상황에서 상대방이 영화를 보자고 한다면? 다시 새로운 정보가 들어온 것이다
그러면 앞에 구한 사후확률은 다음 갱신에서 사전확률이 된다.
이제 갱신된 상대방이 나를 좋아할 확률은 0.6이다.
$$
P(L) = 0.6
$$
이제 상대방의 행동을 기반으로 사전확률을 갱신해나갈 것이다. 
상대방의 행동 =&gt; 나에게 영화를 보자고 하였다.
이제 알아야 할 것은</p>
<blockquote>
<p>상대방이 나를 좋아하는데 먼저 디엠을 보낼 확률 : P(M|L)
상대방이 나를 좋아하지않는데 먼저 디엠을 보낼 확률 : P(M|L&#39;)</p>
</blockquote>
<p>또 이 확률을 조사해본 결과
P(M|L) = 0.7
P(M|L&#39;) = 0.3 이라고 하자
<img src="https://images.velog.io/images/jungeun-dev/post/d1b66803-804e-4a77-98c3-cfce55b07763/image.png" alt="">
그러면 다음과 같이 또 0.75로 갱신된 것을 볼 수있다.
베이즈 정리는 이와 같이 갱신해 나가는 것에 의의가 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 이론 시험 대비 끄적끄적]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%EB%A1%A0-%EC%8B%9C%ED%97%98-%EB%8C%80%EB%B9%84-%EB%81%84%EC%A0%81%EB%81%84%EC%A0%81</link>
            <guid>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%EB%A1%A0-%EC%8B%9C%ED%97%98-%EB%8C%80%EB%B9%84-%EB%81%84%EC%A0%81%EB%81%84%EC%A0%81</guid>
            <pubDate>Wed, 08 Dec 2021 14:11:06 GMT</pubDate>
            <description><![CDATA[<p>필자의 학교 시험 대비로 정리하고자 한다.
개인적으로 아무렇게나 때려 쓰면서 정리할 예정이라
밑도 끝도 없이 요점만 있을 가능성이 높음,,,
의식의 흐름으로 정리,,,</p>
<h3 id="--알고리즘-시간-복잡도-순서-">** * 알고리즘 시간 복잡도 순서 **</h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/304947a5-a23b-449e-9c48-4373628def3e/image.png" alt=""></p>
<blockquote>
<p>시간 복잡도 크기 순서
O(1) &lt; O(logn) &lt; O(n) &lt; O(nlogn) &lt; O(n^2) &lt; O(n^3) &lt; O(2^n) &lt; O(n!)</p>
</blockquote>
<h3 id="--우선순위-큐와-큐-">** * 우선순위 큐와 큐 **</h3>
<ul>
<li>큐는 FIFO 구조로 먼저 들어간것이 먼저 나오는 구조</li>
<li>우선순위 큐는 들어간 순서와 관계없이 우선순위가 높은 데이터가 먼저 나온다</li>
<li>우선순위 큐로 무슨 자료구조가 가장 구현하기 적합한가? =&gt; 힙
( 배열이나 연결 리스트가 삭제에서는 시간 복잡도의 우위를 점할지라도, 삽입의 시간 복잡도가 힙 기반이 월등하기 때문에, 편차가 심한 배열과 연결리스트보다는 힙으로 구현)</li>
</ul>
<h3 id="--정렬-알고리즘-정리-">** * 정렬 알고리즘 정리 **</h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/fd779c22-c679-464d-add3-c8dc270135b9/image.png" alt="">
( 정렬의 자세한 코드는 제 velog 확인 )</p>
<ul>
<li>합병 정렬, 삽입 정렬, 버블 정렬만 안정 정렬이다. </li>
<li>삽입 정렬 최선의 경우 O(n) -&gt; 처음부터 자료가 정렬되어있는경우 =&gt; 자료가 정렬이 되어있을수록  빠르다</li>
<li>힙 정렬 -&gt; 위의 표는 어디서 가져왔는데 힙정렬은 추가 메모리 없이 제자리 정렬도 가능하다. 
(합병정렬만 추가 메모리 필요)</li>
<li>합병 정렬, 퀵 정렬 알고리즘 설계기법 =&gt; &quot;분할 통치법&quot; (분할-&gt;정복(재귀)-&gt;합병(통치))</li>
<li>합병 정렬 외부 메모리 필요, 순차적 데이터 접근</li>
<li>퀵 정렬 최악의 경우 O(n^2) 
=&gt; pivot(기준원소)가 항상 유일한 최소이거나 최대원소일 경우
=&gt; LT 와 GT 중 하나는 크기가 n-1, 다른쪽은 크기가 0</li>
<li>우선순위 큐 (선택 : 무순리스트 , 삽입 : 순서리스트, 힙 : 힙)</li>
<li>분할 통치 (합병,퀵)</li>
</ul>
<h3 id="-사전-adt-">** 사전 ADT **</h3>
<p> 분할 통치 vs 이진 탐색</p>
<ul>
<li><p>분할 통치 : (정렬시) 이등분된 두개의 범위 모두 고려</p>
</li>
<li><p>이진 탐색 : (탐색시) 이등분된 두개의 범위 중 한쪽을 고려대상에서 배제</p>
</li>
<li><ul>
<li>이진 탐색 트리 **</li>
<li>key(lchild) &lt; key(parent) &lt;= key(rchild) </li>
<li>완전 이진트리로 전제 </li>
<li>탐색 성능 최악(O(n)) 최선 O(log n)</li>
</ul>
</li>
<li><ul>
<li>AVL Tree **</li>
</ul>
</li>
<li><p>높이 균형 속성 ( 트리의 모든 내부 노드에 대해 자식들의 좌우 높이 차이가 1을 넘지 않는다)</p>
</li>
<li><p>탐색,삽입,삭제 O(log n)</p>
</li>
<li><ul>
<li>Splay Tree **</li>
</ul>
</li>
<li><p>트리의 노드가 탐색 또는 갱신을 위해 접근된 후, 스플레이되는 이진 탐색 트리를 말합니다.
(스플레이 된다 = 해당 노드가 루트로 이동된다)</p>
</li>
<li><p>탐색,삽입,삭제 O(log n) (상각실행시간)</p>
</li>
<li><p>AVL보다 구현이 더 간단</p>
<h3 id="-해시-테이블-">** 해시 테이블 **</h3>
</li>
<li><p>버켓 배열 + 해시 함수
해시함수 =&gt; 무작위하게 분산 ,가능한 상수시간
임의의 키 =&gt; &lt; 해시코드 맵 &gt; =&gt; &lt; 압축 맵 &gt;</p>
</li>
<li><p>압축맵 ( 나누기 , 승합제( |ax + b| % M {a % M != 0}) )</p>
<ul>
<li><p>충돌 해결   </p>
<ul>
<li><p>분리 연쇄 법 ( 테이블 외부에 추가적인 공간 요구)  </p>
</li>
<li><p>개방 주소법 ( 공간절약, but 삭제가 어려움 , 군집화 발생 )</p>
<ul>
<li><p>선형 조사법 
=&gt; 바로 다음 테이블 셀에 저장 (1차 군집화 발생)</p>
</li>
<li><p>2차 조사법
=&gt; 1 , 4, 9, 16 ...다음 테이블 셀에 저장(2차 군집화 발생)</p>
</li>
<li><p>이중 해싱!!!
=&gt; 군집화를 최소화
더하는게 함수값임 함수값과 M은 서로소관계 
cf) M은 소수이면 더 좋음 =&gt; 소수가 아니면 충돌 발생 가능성이 더 높음</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="-그래프-">** 그래프 **</h3>
</li>
<li><p>간선 리스트 구조</p>
</li>
<li><p>인접 리스트 구조</p>
</li>
<li><p>인접 행렬 구조</p>
</li>
<li><p>인접 리스트 vs 인접 행렬
희소 그래프 =&gt; 인접 리스트
밀집 그래프 =&gt; 인접 행렬</p>
</li>
<li><p>DFS </p>
<ul>
<li>스택 사용 구현 / 재귀 구현 두가지 방법 존재</li>
<li>O(n+m)</li>
</ul>
</li>
<li><p>BFS </p>
<ul>
<li>큐 사용 구현</li>
<li>O(n+m)<ul>
<li>최단경로에 사용</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="-방향-그래프-">** 방향 그래프 **</h3>
<ul>
<li>진입 간선 , 진출 간선 이용</li>
<li>이행적 폐쇄
 =&gt; DFS 로 찾기 O(n(n+m))
 =&gt; 플로이드와샬 (동적프로그래밍) O(n^3)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] DFS & BFS
]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</link>
            <guid>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</guid>
            <pubDate>Wed, 01 Dec 2021 06:29:14 GMT</pubDate>
            <description><![CDATA[<h2 id="bfs--dfs">BFS &amp; DFS</h2>
<p><img src="https://images.velog.io/images/jungeun-dev/post/18063467-b84e-49f4-89c4-9beb3812f126/image.png" alt=""></p>
<h2 id="💞-깊이-우선-탐색dfs란">💞 깊이 우선 탐색(DFS)란?</h2>
<p>** &lt; DFS : Dept First Search &gt;**</p>
<ul>
<li>그래프 전체를 탐색하는 방법 중 하나로 시작점부터 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하고 넘어가는 방법</li>
<li>구현에는 스택을 통해 구현 / 재귀함수로 구현 2가지 존재 
=&gt; 재귀함수로 구현이 더 간편</li>
</ul>
<h3 id="dfs-코드">DFS 코드</h3>
<pre><code class="language-c">//인접 리스트를 이용한 dfs 구현

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

typedef struct incidenceType{
    int vertex;
    struct incidenceType *next;
}incidence;
typedef struct vertextType{
    incidence *head;
    int vertex;
    int isVisited;
}vertext;
typedef struct graphType{
    vertext *vertext;
}graph;

void makeEdge(graph g,int v1,int v2);
void DFS(graph g,int v);

int main(){
    int n,m,s,i,v1,v2;
    graph g;

    scanf(&quot;%d %d %d&quot;,&amp;n,&amp;m,&amp;s); //정점개수, 간선 개수, 조사 시작할 정점 번호
    //그래프 초기화
    g.vertext = (vertext*)malloc((n+1)*sizeof(vertext));
    for(i=1;i&lt;=n;i++){
        g.vertext[i].vertex=i;
        g.vertext[i].isVisited=0;
        g.vertext[i].head = (incidence*)malloc(sizeof(incidence));
        g.vertext[i].head-&gt;next = NULL;
        g.vertext[i].head-&gt;vertex =0;
    }

    for(i=0;i&lt;m;i++){
        scanf(&quot;%d %d&quot;,&amp;v1,&amp;v2);
        makeEdge(g,v1,v2);
    }

    DFS(g,s);

    return;
}

void makeEdge(graph g,int v1,int v2){
    incidence *node1,*node2,*new1,*new2;
    node1 = g.vertext[v1].head;
    node2 = g.vertext[v2].head;

    new1 = (incidence*)malloc(sizeof(incidence));
    new2 = (incidence*)malloc(sizeof(incidence));

    new1-&gt;next = NULL;
    new1-&gt;vertex = v2;
    new2-&gt;next = NULL;
    new2-&gt;vertex = v1;
    // 정점 번호 순서대로 넣음
    while(node1-&gt;next!=NULL){
        if(node1-&gt;next-&gt;vertex&gt;new1-&gt;vertex)
            break;
        node1 = node1-&gt;next;
    }
    new1-&gt;next = node1-&gt;next;
    node1-&gt;next = new1;

    while(node2-&gt;next!=NULL){
        if(node2-&gt;next-&gt;vertex&gt;new2-&gt;vertex)
            break;
        node2 = node2-&gt;next;
    }
    new2-&gt;next = node2-&gt;next;
    node2-&gt;next = new2;
}

void DFS(graph g,int s){
    incidence *node = g.vertext[s].head;

    if(g.vertext[s].isVisited == 1)
        return;

    g.vertext[s].isVisited = 1;
    printf(&quot;%d\n&quot;,s);

    while(node-&gt;next!=NULL){
        DFS(g,node-&gt;next-&gt;vertex);
        node=node-&gt;next;
    }
}</code></pre>
<h3 id="dfs-시간복잡도">DFS 시간복잡도</h3>
<p>인접 리스트로 구현 : O(n + m)
인접 행렬로 구현 : O(n^2)</p>
<h2 id="💞-너비-우선-탐색bfs란">💞 너비 우선 탐색(BFS)란?</h2>
<p>** &lt; BFS : Breadth First Search &gt;**</p>
<ul>
<li>그래프 전체를 탐색하는 방법 중 하나로 시작점으로부터 인접한 노드를 먼저 탐색하는 방법</li>
<li>구현에는 큐를 통해 구현</li>
</ul>
<h3 id="bfs-코드">BFS 코드</h3>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

typedef struct incidenceType{
    int vertex;
    struct incidenceType *next;
}incidence;

typedef struct vertextType{
    incidence *head;
    int vertex;
    int isVisited;
}vertext;

typedef struct graphType{
    vertext *vertext;
}graph;

typedef struct nodeType{
    int data;
    struct nodeType *next;
}node;

typedef struct queueType{
    node* head;
}queue;

void makeEdge(graph g,int v1,int v2);
void BFS(queue *q,graph g,int v);
void enQueue(queue *q,int data);
int deQueue(queue *q);

int main(){
    int n,m,s,i,v1,v2;
    graph g;

    //큐 초기화
    queue *q = (queue*)malloc(sizeof(queue));
    q-&gt;head = (node*)malloc(sizeof(node));
    q-&gt;head-&gt;next = NULL;
    q-&gt;head-&gt;data = 0;

    scanf(&quot;%d %d %d&quot;,&amp;n,&amp;m,&amp;s); //정점 개수, 간선 개수, 탐색시작할 정점 번호

    //그래프 초기화
    g.vertext = (vertext*)malloc((n+1)*sizeof(vertext));
    for(i=1;i&lt;=n;i++){
        g.vertext[i].vertex=i;
        g.vertext[i].isVisited=0;
        g.vertext[i].head = (incidence*)malloc(sizeof(incidence));
        g.vertext[i].head-&gt;next = NULL;
        g.vertext[i].head-&gt;vertex =0;
    }

    for(i=0;i&lt;m;i++){
        scanf(&quot;%d %d&quot;,&amp;v1,&amp;v2);
        makeEdge(g,v1,v2);
    }

    BFS(q,g,s);

    return;
}

void makeEdge(graph g,int v1,int v2){
    incidence *node1,*node2,*new1,*new2;
    node1 = g.vertext[v1].head;
    node2 = g.vertext[v2].head;

    new1 = (incidence*)malloc(sizeof(incidence));
    new2 = (incidence*)malloc(sizeof(incidence));

    new1-&gt;next = NULL;
    new1-&gt;vertex = v2;
    new2-&gt;next = NULL;
    new2-&gt;vertex = v1;

    // 정점 번호 순대로 삽입
    while(node1-&gt;next!=NULL){
        if(node1-&gt;next-&gt;vertex&gt;new1-&gt;vertex)
            break;
        node1 = node1-&gt;next;
    }
    new1-&gt;next = node1-&gt;next;
    node1-&gt;next = new1;

    while(node2-&gt;next!=NULL){
        if(node2-&gt;next-&gt;vertex&gt;new2-&gt;vertex)
            break;
        node2 = node2-&gt;next;
    }
    new2-&gt;next = node2-&gt;next;
    node2-&gt;next = new2;
}

void BFS(queue *q,graph g,int s){
    int v;
    incidence *node;
    //시작 정점 삽입
    enQueue(q,s);
    g.vertext[s].isVisited = 1;

    while(q-&gt;head-&gt;next!=NULL){
        v = deQueue(q);
        printf(&quot;%d\n&quot;,v);

        node = g.vertext[v].head;
        //인접 정점 큐에 삽입, 방문처리
        while(node-&gt;next!=NULL){
            if(g.vertext[node-&gt;next-&gt;vertex].isVisited==0){
                enQueue(q,node-&gt;next-&gt;vertex);
                g.vertext[node-&gt;next-&gt;vertex].isVisited = 1;
            }
            node = node-&gt;next;
        }
    }
}

void enQueue(queue *q,int data){
    node *newnode;
    node *tmp = q-&gt;head;

    newnode = (node*)malloc(sizeof(node));
    newnode-&gt;data = data;
    newnode-&gt;next = NULL;

    while(tmp-&gt;next!=NULL)
        tmp = tmp-&gt;next;
    tmp-&gt;next = newnode;
}
int deQueue(queue *q){
    int ret;
    node *del;
    node *tmp = q-&gt;head;

    del = tmp-&gt;next;
    tmp-&gt;next = del-&gt;next;
    ret = del-&gt;data;
    free(del);
    return ret;
}</code></pre>
<h3 id="bfs-시간복잡도">BFS 시간복잡도</h3>
<p>인접 리스트로 구현 : O(n + m)
인접 행렬로 구현 : O(n^2)</p>
<h2 id="💞-dfs--bfs-응용">💞 DFS &amp; BFS 응용</h2>
<ul>
<li>최단경로 : BFS</li>
<li>이중 연결 요소 : DFS </li>
<li>신장숲, 연결 요소, 경로, 싸이클 : DFS, BFS</li>
</ul>
<h4 id="신장-트리--신장-숲">신장 트리 , 신장 숲</h4>
<ul>
<li>** 신장 트리 (Spanning Tree) ** : 그래프의 정점들을 가지고 있는 트리(연결되고 , 싸이클이 없음)
=&gt; n개의 정점을 n-1개의 간선으로 연결
=&gt; 구현 : DFS or BFS 도중에 사용된 간선들만 남겨두면 된다.
<img src="https://images.velog.io/images/jungeun-dev/post/c6e9e955-c451-404c-94df-2d42a198951d/image.png" alt=""></li>
<li>** 신장 숲 (Spanning forest) **: 그래프가 연결되어 있지 않을 때 신장트리를 만들수 없다.
=&gt; 각 연결된 요소들이 신장 트리들을 가짐</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 사전 ADT]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%82%AC%EC%A0%84-ADT</link>
            <guid>https://velog.io/@jungeun-dev/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%82%AC%EC%A0%84-ADT</guid>
            <pubDate>Tue, 30 Nov 2021 14:36:25 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jungeun-dev/post/a1329742-b687-42c4-8cd4-527cdbc6edd3/image.png" alt=""></p>
<h3 id="사전-구현에-따른-탐색-기법">사전 구현에 따른 탐색 기법</h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/fd00dec9-f5d9-49f7-a324-c3b496cfccb8/image.png" alt=""></p>
<h4 id="무순-사전">무순 사전</h4>
<ul>
<li><p>사전 항목들을 임의의 순서로 리스트에 저장</p>
</li>
<li><p>insertItem() : 맨 앞 또는 맨 뒤에 삽입 =&gt; O(1) </p>
</li>
<li><p>findElement() or removeElement() : 최악의 경우(항목이 존재 안하는 경우) 리스트 전체 순회 =&gt; O(n)</p>
</li>
<li><p>사용 ) 소규모의 사전 , 삽입은 빈번하지만 탐색이나 삭제는 드문 사전 (ex : 서버의 로그인 기록)</p>
</li>
<li><p>선형 탐색 사용 (단순히 리스트 전체를 순회하며 원소를 찾음) =&gt; O(n)</p>
</li>
</ul>
<h4 id="순서-사전">순서 사전</h4>
<ul>
<li><p>사전 항목들을 정렬된 순서로 저장</p>
</li>
<li><p>findElement() : 이진 탐색 이용 =&gt; O(log n) 시간 소요</p>
</li>
<li><p>insertItem() : 공간 확보를 위해 최악의 경우 n개의 항목 이동이 필요 =&gt;  O(n)</p>
</li>
<li><p>removeElement() : 항목이 삭제된 공간을 기존 항목들로 메꾸기 위해 최악의 경우 =&gt; O(n)</p>
</li>
<li><p>사용 ) 소규모 사전, 탐색은 빈번하지만 삽입이나 삭제는 드문 사전 (ex : 전화번호부, 신용카드 사용승인)</p>
</li>
<li><p>이진 탐색 사용</p>
</li>
</ul>
<h4 id="이진-탐색">이진 탐색</h4>
<ul>
<li>키로 정렬된 배열에 기초한 리스트로 구현된 사전에 대해 findElement 수행</li>
<li>재귀가 발생할 때마다 탐색해야할 원소의 수가 반감 =&gt; 최대 log(n)회 실행 됨<pre><code class="language-c">// 중복된 숫자가 없는 정렬된 배열에서의 탐색
</code></pre>
</li>
</ul>
<p>// x = k 인 숫자 index 찾기
int rFE(int * arr, int k, int l, int r) {
    int mid = (l + r) / 2;</p>
<pre><code>if (l &gt; r) return -1;

if (k == arr[mid]) return mid;
else if (k &lt; arr[mid]) rFE(arr, k, l, mid - 1);
else rFE(arr, k, mid + 1, r);</code></pre><p>}</p>
<p>// x &lt;= k 만족하는 숫자 index찾기
int rFE(int* arr, int k, int l, int r) {
    int mid = (l + r) / 2;</p>
<pre><code>if (l &gt; r) return -1;

if (k == arr[mid]) return mid;
//왼쪽 보ㅓ기
else if (k &lt; arr[mid]) return rFE(arr, k, l, mid - 1);
//오른쪽 보기
else
{
    if (mid == r) return mid;
    if (arr[mid + 1] &gt; k) return mid;
    else return rFE(arr, k, mid + 1, r);
}</code></pre><p>}
int findElement(int* arr, int n, int k) {
    return rFE(arr, k, 0, n - 1);
}</p>
<p>// + 비재귀 x&gt;=k 만족하는 숫자 index 찾기 
int findElement(int* arr, int n, int k) {</p>
<pre><code>int l = 0, r = n - 1;
int mid;

while (l &lt;= r) {
    mid = (l + r) / 2;
    if (arr[mid] == k) return mid;
    else if (k &lt; arr[mid]) {
        if (mid == l) return mid;
        if (arr[mid - 1] &lt; k) return mid;
        r = mid - 1;
    }
    else {
        l = mid + 1;
    }
}
return n;</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 그래프(Graph)]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%9E%98%ED%94%84</link>
            <guid>https://velog.io/@jungeun-dev/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%9E%98%ED%94%84</guid>
            <pubDate>Mon, 22 Nov 2021 11:00:08 GMT</pubDate>
            <description><![CDATA[<h2 id="그래프란">그래프란?</h2>
<ul>
<li>** 노드(Node) 또는 정점(vertex) ** 와 노드와 노드를 연결하는 ** 간선(Edge) ** 으로 구성<h3 id="✔-관련-용어">✔ 관련 용어</h3>
<ul>
<li>정점(vertex) : 위치라는 개념</li>
<li>간선(edge) : 위치 간의 관계 , 노드를 연결하는 선(link, branch)</li>
<li>인접 정접(adjacent vertex) : 간선에 의해 직접 연결된 정점</li>
<li>정점의 차수(degree) : 무방향 그래프에서 하나의 정점에 인접한 정점의 수 
=&gt; 무방향 그래프에서 존재하는 정점의 모든 차수의 합 = 그래프의 간선 수의 2배</li>
<li>진입 차수(in-degree) : 방향 그래프에서 외부에서 오는 간선의 수</li>
<li>진출 차수(out-degree) : 방향 그래프에서 외부로 향하는 간선의 수</li>
<li>경로 길이(path length) : 경로를 구성하는데 사용된 간선의 수</li>
<li>단순 경로(simple path) : 경로 중 반복되는 정점이 없는 경우</li>
<li>사이클(cycle) : 단순 경로의 시작 정점과 종료 정점이 동일한 경우</li>
</ul>
</li>
</ul>
<h3 id="✔-그래프-종류">✔ 그래프 종류</h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/bb31fcc0-b56d-4c39-b89a-d10a000c6922/image.png" alt=""> </p>
<p><span style='background-color: #ddffff'> <code>무방향 그래프</code> VS <code>방향 그래프</code> </span></p>
<p>** 무방향 그래프(Undirected Graph) **</p>
<ul>
<li>무방향 그래프는 방향이 없는 그래프로 간선을 통해 양방향 모두 접근 가능</li>
<li>(A,B) = (B,A) </li>
</ul>
<p>** 방향 그래프(Directed Graph) **</p>
<ul>
<li>간선에 방향성이 존재</li>
<li>(A,B) != (B,A) </li>
</ul>
<p><span style ='background-color : #ddffff'> <code>가중치 그래프</code> </span>
** 가중치 그래프(Weighted Graph) **</p>
<ul>
<li>간선에 비용이나 가중치가 할당된 그래프</li>
</ul>
<p><span style='background-color : #ddffff'><code>연결 그래프</code> VS <code>비연결 그래프</code> </span></p>
<p> ** 연결 그래프(Connected Graph) **</p>
<ul>
<li>무방향 그래프에 있는 모든 정점쌍에 대하여 항상 경로가 존재하는 경우</li>
</ul>
<p> ** 비연결 그래프(Disconnected Graph) **</p>
<ul>
<li>무방향 그래프에서 특정 정점쌍 사이에 경로가 존재하지 않는 경우</li>
</ul>
<p><span style='background-color: #ddffff'><code>완전 그래프</code> </span>
** 완전그래프(Complete Graph) **</p>
<ul>
<li>그래프에 속해 있는 모든 정점이 서로 연결되어 있는 그래프</li>
<li>무방향 완전 그래프 
=&gt; 정점수 : **  n * (n -1) / 2 ** {n = 간선의 수}</li>
</ul>
<h3 id="✔-그래프의-구현">✔ 그래프의 구현</h3>
<h4 id="1-인접-행렬adjacency-matrix">1. 인접 행렬(Adjacency Matrix)</h4>
<p><img src="https://images.velog.io/images/jungeun-dev/post/c5994d47-189f-4832-a849-7083c7ed29b9/image.png" alt="">
&lt; 무방향 그래프 인접 행렬 표현&gt;</p>
<pre><code class="language-c">if(간선 x,y가 그래프에 존재) M[x][y] = 1;
otherwise M[x][y] = 0</code></pre>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define VERTICES 6 //vertex 개수

void printIncidence(int ** g, int v) {
    if (v &lt; 1 || v &gt; 6 ) {
        printf(&quot;-1\n&quot;);
        return;
    }
    for (int i = 1; i &lt;= VERTICES; i++) {
        if (g[v][i] != 0) printf(&quot; %d %d&quot;, i, g[v][i]);
    }
    printf(&quot;\n&quot;);
}

void makeEdge(int** g, int v1, int v2, int w) {

    if (v1 &lt; 1 || v1 &gt; VERTICES || v2 &lt; 1 || v2 &gt; VERTICES) {
        printf(&quot;-1\n&quot;);
        return;
    }
    //무방향그래프
    g[v1][v2] = w;
    g[v2][v1] = w;
}

void makeGraph(int** g) {

    for (int i = 1; i &lt;= VERTICES; i++) {
        for (int j = 1; j &lt;= VERTICES; j++) {
            g[i][j] = 0;
        }
    }
    //간선 삽입 예시
    makeEdge(g, 1, 2, 1); // 1과 2 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 3, 1); // 1과 3 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 4, 1); // 1과 4 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 6, 2); // 1과 6 사이에 가중치 2인 간선 생성
    makeEdge(g, 2, 3, 1);
    makeEdge(g, 3, 5, 4);
    makeEdge(g, 5, 5, 4);
    makeEdge(g, 5, 6, 3);
}
int main() {
    char c;
    int v, v2, w;
    int** g = (int *)malloc(sizeof(int*) * (VERTICES + 1));

    for (int i = 1; i &lt;= VERTICES; i++) {
        g[i] = (int*)malloc(sizeof(int) * (VERTICES +1 ));
    }

    makeGraph(g);

    return;
}</code></pre>
<p>다음과 같이 표현 할 수 있다.</p>
<h4 id="2-인접-리스트adjacency-list">2. 인접 리스트(Adjacency List)</h4>
<ul>
<li>가장 일반적인 방법</li>
</ul>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define VERTICES 6 //vertex 개수

typedef struct incidence {
    int weight;
    int vertex;
    struct incidence* next;
}incidence;

typedef struct vertex {
    incidence * head;
    int vertex;
}vertex;

typedef struct graph {
    vertex vertexs[VERTICES + 1];
}graph;

void printIncidence(graph* g, int v) {
    incidence* temp;
    if (v &lt;= 0 || v &gt; VERTICES) {
        printf(&quot;-1\n&quot;);
        return;
    }
    temp = g-&gt;vertexs[v].head-&gt;next;
    while (temp) {
        printf(&quot; %d %d&quot;, temp-&gt;vertex, temp-&gt;weight);
        temp = temp-&gt;next;
    }
    printf(&quot;\n&quot;);
}

void printGraph(graph* g) {
    incidence* temp;

    for (int i = 1; i &lt;= VERTICES; i++) {
        printf(&quot;graph &lt; %d &gt; : &quot;, i);
        temp = g-&gt;vertexs[i].head-&gt;next;
        while (temp) {
            printf(&quot; %d&quot;, temp-&gt;vertex);
            temp = temp-&gt;next;
        }
        printf(&quot;\n&quot;);
    }
    printf(&quot;\n&quot;);
}

//간선 삭제 수정 삽입 모두 가능 + 정점 크기 순으로 삽입됨
void makeEdge(graph* g, int v1, int v2, int w) {
    incidence* temp1,* temp2;
    incidence* new1, * new2;
    incidence* prev1, * prev2;
    int plus = 0;
    temp1 = g-&gt;vertexs[v1].head;
    temp2 = g-&gt;vertexs[v2].head;

    // 정점 존재하지 않을 시 종료
    if (v1 &lt;= 0 || v1 &gt; VERTICES || v2 &lt;= 0 || v2 &gt; VERTICES) {
        printf(&quot;-1\n&quot;);
        return;
    }
    prev1 = g-&gt;vertexs[v1].head;
    prev2 = g-&gt;vertexs[v2].head;
    //삭제의 경우
    if (w == 0) {
        while (temp1) {
            if (temp1-&gt;vertex == v2) {
                prev1-&gt;next = temp1-&gt;next;
                free(temp1);
                break;
            }
            prev1 = temp1;
            temp1 = temp1-&gt;next;
        }
        while (temp2) {
            if (temp2-&gt;vertex == v1) {
                prev2-&gt;next = temp2-&gt;next;
                free(temp2);
                break;
            }
            prev2 = temp2;
            temp2 = temp2-&gt;next;
        }
        return;
    }
    new1 = (incidence*)malloc(sizeof(incidence));
    new1-&gt;vertex = v2;
    new1-&gt;weight = w;
    new1-&gt;next = NULL;

    new2 = (incidence*)malloc(sizeof(incidence));
    new2-&gt;vertex = v1;
    new2-&gt;weight = w;
    new2-&gt;next = NULL;


    //삽입 or 수정
    while (temp1) {
        //삽입

        if (temp1-&gt;vertex &gt; v2) {
            break;
        }
        //수정 (간선 가중치 수정도 가능)
        if (temp1-&gt;vertex == v2) {
            temp1-&gt;weight = w;
            plus = 1;
            break;
        }
        prev1 = temp1;
        temp1 = temp1-&gt;next;
    }
    if (plus == 0) {
        prev1-&gt;next = new1;    
        if (temp1 != NULL) {
            new1-&gt;next = temp1;

        }
    }

    while (temp2) {
        //삽입
        if (temp2-&gt;vertex &gt; v1) {
            break;
        }
        //수정 (간선 가중치 수정도 가능)
        if (temp2-&gt;vertex == v1) {
            temp2-&gt;weight = w;
            plus = 1;
            break;
        }
        prev2 = temp2;
        temp2 = temp2-&gt;next;
    }
    if (plus == 0) {
        prev2-&gt;next = new2;
        if (temp2 != NULL) {
            new2-&gt;next = temp2;
        }
    }
}

void makeGraph(graph * g) {
    //초기화
    for (int i = 1; i &lt;= VERTICES; i++) {
        g-&gt;vertexs[i].vertex = i;
        g-&gt;vertexs[i].head = (incidence*)malloc(sizeof(incidence));
        g-&gt;vertexs[i].head-&gt;vertex = 0;
        g-&gt;vertexs[i].head-&gt;weight = 0;
        g-&gt;vertexs[i].head-&gt;next = NULL;
    }
    //예시
    makeEdge(g, 1, 2, 1); // 1과 2 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 3, 1); // 1과 3 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 4, 1); // 1과 4 사이에 가중치 1인 간선 생성
    makeEdge(g, 1, 6, 2); // 1과 6 사이에 가중치 2인 간선 생성
    makeEdge(g, 2, 3, 1);
    makeEdge(g, 3, 5, 4);
    makeEdge(g, 5, 5, 4);
    makeEdge(g, 5, 6, 3);
}</code></pre>
<h3 id="✔-인접-행렬-vs-인접-리스트">✔ 인접 행렬 VS 인접 리스트</h3>
<p>뭐가 더 효율적인가?</p>
<ul>
<li>희소 그래프 VS 밀집 그래프 </li>
</ul>
<p><span style = 'background-color : #ddfff'> =&gt; 희소 그래프 </span>
  만약 정점이 1000개가 있는데 간선은 10개 뿐인 그래프가 있다고 하자. 이렇게 간선의 수가 적은 그래프를 희소 그래프(sparse graph)라고 한다. 이를 행렬로 구현하기위해서는 10개의 간선을 나타내기 위해 1000x1000행렬을 사용해야한다. 하지만 인접 리스트로 구현시 1000 + 10개의 노드만 있으면 구현이 가능하다. 따라서 인접 리스트는 희소 그래프를 표현할때 적당하다.</p>
<p><span style = 'background-color : #ddfff'> =&gt; 밀집 그래프 </span>
  만약 정점이 1000개가 있는데 간선이 2000개가 있는 그래프가 있다고 하자.  이렇게 간선 수가 가 많은 그래프를 밀집 그래프(dense graph)라고 한다. 이때는 인접행렬로 그래프를 구현하는 것이 더 효과적이다. 왜냐하면 행렬은 인덱스로 바로 접근이 가능하기 때문이다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 스택(STACK)과 큐(QUEUE)]]></title>
            <link>https://velog.io/@jungeun-dev/STACKQUEUE</link>
            <guid>https://velog.io/@jungeun-dev/STACKQUEUE</guid>
            <pubDate>Sun, 21 Nov 2021 07:22:39 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jungeun-dev/post/7bf2edcd-d660-4d53-9233-dbcbe5422605/image.png" alt=""></p>
<h2 id="➕--stack-">➕ ** STACK **</h2>
<h3 id="span-stylebackground-color-ddffff--lifo--last-input-first-out-span"><span style='background-color: #ddffff'> ** LIFO ** (Last Input First Out) </span></h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/4ed25652-e420-49aa-9300-1a8a66c763b3/image.png" alt=""></p>
<ul>
<li><p>마지막에 넣은 원소가 먼저 나온다는 것이다.</p>
</li>
<li><p>아래가 막혀있고 위가 뚫린 형태로써, 차곡차곡 쌓는 구조이다.</p>
</li>
<li><p>스택에서 삽입은 PUSH, 삭제는 POP 이라는 용어로 사용한다.</p>
</li>
<li><p>DFS 탐색시 사용</p>
<p>ex) 문서 작업에서 컨트롤 + Z 와 같은 이전 상태로 되돌리기 등처럼 캐시와 같은 모습으로 많이 존재한다.</p>
</li>
</ul>
<p>😨 stack overflow?</p>
<ul>
<li>stack이란 것을 배우기도 전부터 많이접해보았을 것이다.</li>
<li>말 그대로, 위와 같이 정해진 크기에 무언가를 계속 넣고 있다가 받아들일 수 있는 크기를 초과해서 흘러넘쳐버린 것을 말한다.</li>
</ul>
<h3 id="코드연결리스트-이용-c로-구현-">*<em>코드(연결리스트 이용, c로 구현) *</em></h3>
<blockquote>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
</code></pre>
</blockquote>
<p>typedef struct Node {
    char* data;
    struct Node* prev;
    struct Node* next;
} Node;</p>
<blockquote>
</blockquote>
<p>typedef struct LinkedListStack {
    Node* top;
    int size;
} LinkedListStack;</p>
<blockquote>
</blockquote>
<p>LinkedListStack* init() {
    LinkedListStack* stack;
    stack = (LinkedListStack*)malloc(sizeof(LinkedListStack));
    stack-&gt;top = NULL;
    stack-&gt;size = 0;
    return stack;
}</p>
<blockquote>
</blockquote>
<p>Node* NodeInit(char* str) {
    Node* newNode = (Node<em>)malloc(sizeof(Node));
    newNode-&gt;data = (char</em>)malloc(strlen(str)+1);
    strcpy(newNode-&gt;data, str);
    newNode-&gt;next = NULL;
    newNode-&gt;prev = NULL;
    return newNode;
}</p>
<blockquote>
</blockquote>
<p>void push(LinkedListStack* list, char* str) {
    Node* newNode = NodeInit(str);
    Node* oldTop;</p>
<blockquote>
</blockquote>
<pre><code>if(list-&gt;top == NULL) {
    list-&gt;top = newNode;
}
else {
    oldTop = list-&gt;top;
    oldTop-&gt;next = newNode;
    newNode-&gt;prev = oldTop;
    list-&gt;top = newNode;
}
list-&gt;size++;</code></pre><p>}</p>
<blockquote>
</blockquote>
<p>void pop(LinkedListStack* list) {
    Node* currentTop = list-&gt;top;
    Node* newTop;</p>
<blockquote>
</blockquote>
<pre><code>if(currentTop == NULL) return;
else {
    newTop = list-&gt;top-&gt;prev;
    newTop-&gt;next = NULL;
    list-&gt;top = newTop;
}
list-&gt;size--;
free(currentTop-&gt;data);
free(currentTop);</code></pre><blockquote>
<p>}</p>
</blockquote>
<p>Node* Top(LinkedListStack* list) {
    return list-&gt;top;
}</p>
<h2 id="➕--queue-">➕ ** Queue **</h2>
<h3 id="span-stylebackground-color-ddffff--fifo--first-input-first-out-span"><span style='background-color: #ddffff'> ** FIFO ** (First Input First Out) </span></h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/97bb5d19-a8f2-4e55-840a-f7edc7cd62e9/image.png" alt=""></p>
<ul>
<li>가장 현생활에서 많이 쓰이는 구조이다. </li>
<li>먼저 줄 선 사람이 먼저 계산을 하는 것이다. </li>
<li>큐에서 삽입은 EnQueue, 삭제는 DeQueue 이라는 용어로 사용한다.</li>
<li>BFS 탐색에서 사용</li>
</ul>
<h3 id="👉-코드-연결리스트-이용--c-로-구현">👉 <strong>코드 (연결리스트 이용 , c 로 구현)</strong></h3>
<blockquote>
<pre><code class="language-c">#include&lt;stdio.h&gt;
#include&lt;stdlib.h&gt;
</code></pre>
</blockquote>
<p>typedef char element;</p>
<blockquote>
</blockquote>
<p>typedef struct QNode {
    element data;
    QNode* link;
}QNode;
typedef struct LinkedQueue {
    QNode* front;
    QNode* rear;
}LinkedQueue;</p>
<blockquote>
</blockquote>
<p>LinkedQueue* createLinkedQueue() {
    LinkedQueue* LQ = (LinkedQueue<em>)malloc(sizeof(LinkedQueue));
    LQ-&gt;front = NULL;
    LQ-&gt;rear = NULL;
    return LQ; 
}
int isEmpty(LinkedQueue</em> LQ) {
    if (LQ-&gt;front == NULL) return 1;
    else return 0;
}
void enQueue(LinkedQueue* LQ, element item) {
    QNode* new = (QNode<em>)malloc(sizeof(QNode));
    new-&gt;data = item;
    new-&gt;link = NULL;
    if (LQ-&gt;front == NULL) {
        LQ-&gt;front = new;
        LQ-&gt;rear = new;
    }
    else {
        LQ-&gt;rear-&gt;link = new;
        LQ-&gt;rear = new;
    }
}
element deQueue(LinkedQueue</em> LQ) {
    if (isEmpty(LQ)) exit(1);
    else {
        QNode* old = LQ-&gt;front;
        element item = LQ-&gt;front-&gt;data;
        LQ-&gt;front = LQ-&gt;front-&gt;link;
        if (isEmpty(LQ)) LQ-&gt;rear = NULL;
        free(old);
        return item;
    }
}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[선형 대수학] 행렬]]></title>
            <link>https://velog.io/@jungeun-dev/%ED%96%89%EB%A0%AC</link>
            <guid>https://velog.io/@jungeun-dev/%ED%96%89%EB%A0%AC</guid>
            <pubDate>Tue, 05 Oct 2021 08:14:18 GMT</pubDate>
            <description><![CDATA[<h1 id="✔-미리보기">✔ 미리보기</h1>
<blockquote>
<p>** 1. 행렬과 행렬의 연산 **
     - 행렬
     - 행렬의 합과 스칼라 곱
     - 행렬의 곱</p>
<p>** 2. 특수한 행렬 **
    - 대각 행렬 
    - 항등 행렬과 영행렬
    - 전치행렬
    - 대칭행렬과 교대행렬
    - 삼각행렬</p>
<p>** 3. 행렬의 기본 연산과 사다리꼴 **
    - 행렬의 기본 연산
    - 행 사다리꼴 (Echelon Form)
    - 계수 (Rank)
    - 행렬의 표현과 응용</p>
</blockquote>
<h2 id="-1-행렬과-행렬의-연산-">** 1. 행렬과 행렬의 연산 **</h2>
<h3 id="✔-span-stylebackground-color-ddffff행렬span">✔ <span style='background-color: #ddffff'>행렬</span></h3>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7sf1w%2FbtqOn0L3IC1%2FXAxkURqF4IvymBAjkvxUv1%2Fimg.png" alt="img"></p>
<ul>
<li>가로줄을 행(Row), 세로줄을 열(Column)이라고 부르며, m X n 행렬은 m개의 행과 n개의 열로 이루어진 행렬이다.</li>
</ul>
<h4 id="--span-stylebackground-color-f5f0ff행벡터-열벡터span">- <span style='background-color: #f5f0ff'>행벡터, 열벡터</span></h4>
<ul>
<li>행벡터 : [X1,...Xn] 1 X n 행렬</li>
<li>열벡터 : m X 1 행렬</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff행렬의-합과-스칼라-곱span">✔ <span style='background-color: #ddffff'>행렬의 합과 스칼라 곱</span></h3>
<h4 id="--span-stylebackground-color-f5f0ff행렬의-합과-차span">- <span style='background-color: #f5f0ff'>행렬의 합과 차</span></h4>
<ul>
<li>두 행렬의 크기가 같아야만 연산 가능!</li>
<li>합 : A + B</li>
<li>차 : A - B (= A + (-B))
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRfJZu%2FbtqGbOrsLUu%2F7Tim0QZCNJzmCGQwzzq5Hk%2Fimg.png" alt="img"></li>
</ul>
<h4 id="--span-stylebackground-color-f5f0ff행렬의-스칼라-곱scalar-multiplicationspan">- <span style='background-color: #f5f0ff'>행렬의 스칼라 곱(Scalar Multiplication)</span></h4>
<ul>
<li>행렬 A에 실수 k를 곱하는 연산 =&gt; 행렬의 각 원소마다 k를 곱해준다.
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrJThR%2FbtqF7LQIhZv%2FtxRkryBQJKxG6KUCgkMHG1%2Fimg.png" alt="img"></li>
</ul>
<h4 id="--span-stylebackground-color-f5f0ff상등equal한-행렬-span">- <span style='background-color: #f5f0ff'>상등(equal)한 행렬 </span></h4>
<ul>
<li>두개의 행렬에서 각각 대응하는 항들이 모두 동일하다면 상등하다고 한다.</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff행렬의-곱multiplication-span">✔ <span style='background-color: #ddffff'>행렬의 곱(Multiplication) </span></h3>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpINjC%2FbtqGbbgpnjM%2FxbaXCFmkvGnqabrsPzpq00%2Fimg.png" alt="img"></p>
<ul>
<li><p>(m X n) 행렬인 A와 (n X p) 행렬인 B 경우 AB = C 라 할때, C 는 (m X p) 행렬이 된다.</p>
</li>
<li><p>A의 열의 숫자(n) B의 행의 숫자(n)가 같을 경우에만 정의 된다.</p>
<ul>
<li>AB 와 BA는 다른 값이다.<span style='background-color: #FAFAA0'>(교환 법칙 성립 X) </span></li>
</ul>
</li>
<li><p>ex)
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkLNul%2FbtqF9lcJGbS%2FJaJVvtlxkkNXLuN0nxVF4k%2Fimg.png" alt="img"></p>
</li>
</ul>
<h4 id="span-stylebackground-color-f5f0ff정리-span"><span style='background-color: #f5f0ff'>정리 </span></h4>
<ul>
<li>곱셈의 결합 법칙 =&gt; A(BC) = (AB)C</li>
<li>배분 법칙 =&gt; A(B+C) = AB + AC</li>
<li>스칼라 곱 =&gt; k(AB) = (kA)B = A(kB)</li>
<li>행렬 곱셈의 항등식 =&gt; In = A = AI (I는 항등 행렬) </li>
</ul>
<h4 id="span-stylebackground-color-f5f0ff행렬의-거듭-제곱span"><span style='background-color: #f5f0ff'>행렬의 거듭 제곱</span></h4>
<ul>
<li><p>A가 nXn 행렬이고 k가 양의 정수라고 할때 A의 k승은 A를 k번 곱한느 것이다.</p>
</li>
<li><p>A의 0승은 I(항등행렬)</p>
<h4 id="span-stylebackground-color-f5f0ff-부행렬-submatrix-span"><span style='background-color: #f5f0ff'> 부행렬 (submatrix) </span></h4>
<p><img src="https://images.velog.io/images/jungeun-dev/post/33505e59-8f6f-4551-a2db-27d8d6e5f499/image.png" alt=""></p>
</li>
</ul>
<h2 id="-2-특수한-행렬-">** 2. 특수한 행렬 **</h2>
<h3 id="✔-span-stylebackground-color-ddffffn차-정방행렬-square-matrix-span">✔ <span style='background-color: #ddffff'>(n차) 정방행렬 (Square matrix) </span></h3>
<ul>
<li>n 개의 행과 n개의 열을 가지는 행렬</li>
<li>주대각선 :
<img src="https://images.velog.io/images/jungeun-dev/post/226cad43-79b5-47f7-8b2e-76e4f9f0fc1c/image.png" alt="">
정방행렬에서의 다음과 같은 대각선을 ** 주 대각선(Main diagonal) ** 이라 부른다.</li>
<li>주 대각선 위의 모든 성분들을 <strong>대각항</strong>이라고 하고, 각 대각항의 합을 <strong>대각합(trace)</strong>라고 하며</li>
<li><em>tr(A) 또는 trace(A)*</em>로 표기한다.</li>
</ul>
<h4 id="span-stylebackground-color-f5f0ff대각합-특성span"><span style='background-color: #f5f0ff'>대각합 특성</span></h4>
<p>=&gt; A와 B가 같은 크기의 정방행렬인 경우</p>
<ul>
<li>$\displaystyle \operatorname {tr} (cA)=c\operatorname {tr} (A)$</li>
<li>$\displaystyle \operatorname {tr} (A)=\operatorname {tr} (A^{\operatorname {T} })$</li>
<li>$\displaystyle \operatorname {tr} (AB)=\operatorname {tr} (BA)$</li>
<li>$\displaystyle \operatorname {tr} (A+B)=\operatorname {tr} (A)+\operatorname {tr} (B)$</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff대각-행렬-diagonal-matrixspan">✔ <span style='background-color: #ddffff'>대각 행렬 (Diagonal matrix)</span></h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/25b950a8-01fa-4bfd-ab29-7afcf3925765/image.png" alt=""></p>
<ul>
<li>주 대각선 성분이 아닌 모든 성분이 0인 정방 행렬이다.</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff항등-행렬-identity-matrixspan">✔ <span style='background-color: #ddffff'>항등 행렬 (Identity matrix)</span></h3>
<ul>
<li>대각행렬이면서 대각선의 항들이 모두 1인 정방행렬을 항등행렬 또는 단위행렬이라 한다.</li>
<li><img src="https://images.velog.io/images/jungeun-dev/post/57302f80-dbd5-4f8a-b414-349b5c76414b/image.png" alt=""></li>
<li><img src="https://images.velog.io/images/jungeun-dev/post/71b13a92-9815-44b8-8cff-95abc9aa036f/image.png" alt=""></li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff영행렬-zero-matrixspan">✔ <span style='background-color: #ddffff'>영행렬 (zero matrix)</span></h3>
<ul>
<li>성분이 모두 0인 행렬</li>
<li>기호로는 O로 적는다.</li>
<li>A+O=O+A=A</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff전치행렬-tranpose-matrixspan">✔ <span style='background-color: #ddffff'>전치행렬 (Tranpose matrix)</span></h3>
<ul>
<li><img src="https://ssl.pstatic.net/images.se2/smedit/2017/4/23/j1urp32w9c5gn8.jpg" alt="img"></li>
<li><img src="https://ssl.pstatic.net/images.se2/smedit/2017/4/23/j1urtgg2dm8vsp.jpg" alt=""></li>
<li>전치 행렬 성질
<img src="https://ssl.pstatic.net/images.se2/smedit/2017/4/23/j1urwok5t98jza.jpg" alt="img"></li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff대칭행렬-symmetric-matrixspan">✔ <span style='background-color: #ddffff'>대칭행렬 (symmetric matrix)</span></h3>
<ul>
<li>정방행렬 n X n행렬이 자신의 전치 행렬과 똑같을때 대칭행렬이라 한다.</li>
<li><img src="https://images.velog.io/images/jungeun-dev/post/c2c09179-eae7-4534-8c8b-7fa241c78c39/image.png" alt=""></li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff교대행렬-symmetric-matrixspan">✔ <span style='background-color: #ddffff'>교대행렬 (symmetric matrix)</span></h3>
<ul>
<li><img src="https://images.velog.io/images/jungeun-dev/post/4d07b779-8412-4cb0-9b24-fc0122ab8fc2/image.png" alt=""></li>
<li>전치행렬에 음수를 곱한것과 같을 경우 교대행렬이라 한다.</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff삼각행렬-triangular-matrixspan">✔ <span style='background-color: #ddffff'>삼각행렬 (Triangular matrix)</span></h3>
<ul>
<li>주대각선 위에 있는 모든 항들이 0인 행렬을 하부 삼각행렬</li>
<li>주대각선 아래에 있는  모든 항들이 0인 행렬을 상부 삼각행렬이라한다.</li>
<li>상부 삼각행렬의 전치는 하부 삼각행렬이고, 하부 삼각행렬의 전치는 상부 삼각행렬이다.</li>
</ul>
<h2 id="-3-행렬의-기본-연산과-사다리꼴-">** 3. 행렬의 기본 연산과 사다리꼴 **</h2>
<h3 id="✔-span-stylebackground-color-ddffff기본-행-연산elementary-row-operation-span">✔ <span style='background-color: #ddffff'>기본 행 연산(Elementary row operation) </span></h3>
<p><img src="https://images.velog.io/images/jungeun-dev/post/3a445730-0103-4066-947e-f9dc3b6dcfc6/image.png" alt=""></p>
<ul>
<li>행 동치 :  기본 행 연산을 필요에 다라 한번 또는 여러 번 거친 것</li>
<li>기본 행렬 : n X n 항등 행렬에서 한번의 기본 행 연산을 거쳐 만들어지는 행렬</li>
<li>피벗 : 행렬의 각 행에서 0이 아닌 가장 처음 나타나는 수를 행렬에서 피벗으로 삼을 수 있다.</li>
</ul>
<h3 id="✔-span-stylebackground-color-ddffff-행-사다리꼴row-echelon-form-ref-span">✔ <span style='background-color: #ddffff'> 행 사다리꼴(row echelon form) <REF> </span></h3>
<p>  m X n 행렬 A가 기본 행 연산들을 거친 후 다음 3가지 조건을 만족시키면 행 사다리꼴이라 한다.</p>
<blockquote>
<ul>
<li>(1) 0으로만 이루어진 행들이 있는 경우, 행렬의 아래쪽에 나타낸다.</li>
</ul>
</blockquote>
<ul>
<li>(2) 모두가 0은 아닌 행의 가장 왼쪽에 가장 처음 나타나는 0이 아닌 수를 피벗으로 삼는다.</li>
<li>(3) 모두가 0은 아닌 연이은 두 행이 있으면 아래쪽 행의 피벗은 위쪽행의 피벗보다 오른쪽에 있다</li>
</ul>
<blockquote>
<ul>
<li>위 세개의 조건을 만족하면서 ** &lt;각 행의 피벗을 포함하는 열에는 피벗 이외의 항들은 모두 0 이다 &gt; ** 를 만족하면 ** &quot;기약 행 사다리꼴&quot;(reduced row echelon form) **라 한다.</li>
</ul>
</blockquote>
<h3 id="✔-span-stylebackground-color-ddffff기약-행-사다리꼴을-구하기-위한-기본-행-연산-span">✔ <span style='background-color: #ddffff'>기약 행 사다리꼴을 구하기 위한 기본 행 연산 </span></h3>
<blockquote>
<ul>
<li>전향단계(forward phase) : 피벗의 아랫부분이 0이 되도록 한다.</li>
</ul>
</blockquote>
<ul>
<li>후향단계(backward phase) : 피벗의 윗부분까지 0이 되도록 한다.</li>
<li>전향 단계까지만 실행시 =&gt; 행 사다리꼴 (=가우스 소거법)</li>
<li>전향 단계 + 후향단계 실행시 (=가우스-조단 소거법)</li>
</ul>
<h4 id="--계수rank">- 계수(rank)</h4>
<ul>
<li>행 사다리꼴로 만들었을 때 &lt;행 전체가 0이 아닌 행의 개수 = 피벗의 개수 = 계수&gt;</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[선형 대수학] 선형대수와 선형 방정식]]></title>
            <link>https://velog.io/@jungeun-dev/%EC%84%A0%ED%98%95%EB%8C%80%EC%88%98%EC%99%80-%EC%84%A0%ED%98%95-%EB%B0%A9%EC%A0%95%EC%8B%9D</link>
            <guid>https://velog.io/@jungeun-dev/%EC%84%A0%ED%98%95%EB%8C%80%EC%88%98%EC%99%80-%EC%84%A0%ED%98%95-%EB%B0%A9%EC%A0%95%EC%8B%9D</guid>
            <pubDate>Tue, 05 Oct 2021 07:54:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jungeun-dev/post/18902bb3-3a78-4082-9358-696209453593/image.png" alt=""></p>
<blockquote>
<p>** 1. 선형 대수와 선형 시스템 **
** 2. 선형방정식의 소거법 **</p>
</blockquote>
<p>고등 수학과 다를 것이 없는 내용이므로 이번 글에서는 
위의 두개에 대하여 간단한 용어정리만 할것이다.</p>
<h3 id="✔span-stylebackground-color-fafaa0선형-대수학에서-다루게-될-내용-미리보기-span">✔<span style='background-color: #FAFAA0'>선형 대수학에서 다루게 될 내용 미리보기 </span></h3>
<blockquote>
<ul>
<li>선형 방정식</li>
</ul>
</blockquote>
<ul>
<li>행렬 , 행렬식</li>
<li>벡터 , 벡터공간 , 내적과 외적, 고유값/고유벡터</li>
<li>선형변환</li>
</ul>
<ul>
<li><p><span style='background-color: #f5f0ff'> *<em>선형 방정식 *</em> </span>
a₁x₁ + a₂x₂+ a₃x₃ +﻿ ... + anxn = bn</p>
</li>
<li><p><span style='background-color: #f5f0ff'> *<em>선형 시스템 *</em></span></p>
<ul>
<li>유한개의 선형 방정식의 집합을 선형 시스템이라고 한다.</li>
<li>입출력 관계가 선형으로 주어지는 시스템</li>
<li>중첩의 원리가 성립</li>
</ul>
</li>
<li><p><span style='background-color: #f5f0ff'> ** 동차 선형 시스템(homogeneous system) **</span></p>
<ul>
<li><p>선형 방정식에서 b1 = b2 ... bm = 0 일 경우를 말한다.</p>
</li>
<li><p>이 경우 x1 = x2 ... xn = 0은 항상 동차 선형시스템의 해가 된다. ( = 자명해(trivial solution))</p>
</li>
<li><p>만일 x1,x2,...xn 중 어느 하나라도 0 이 아닌 경우 비자명해(nontrivial solution)이라고 한다.</p>
</li>
<li><p><span style='background-color: #f5f0ff'> ** 동치(equivalent) **</span>
  선형 방정식들이 똑같은 해를 가질 때 두 식이 동치라고 한다.</p>
</li>
<li><p><span style='background-color: #f5f0ff'> ** 선형 방정식의 소거법 **</p>
<blockquote>
<ol>
<li>한 방정식에 0이 아닌 상수를 곱한다.</li>
<li>방정식들의 위치를 서로 교환한다.</li>
<li>한 방정식에 0이 아닌 상수를 곱하여 다른 방정식에 더한다.</li>
</ol>
</blockquote>
</li>
</ul>
<p>✔ ** 예시 1 ) **</p>
<blockquote>
<p>2 x₁+ x₂+ x₃= 5
4 x₁ - 6x₂= -2
-2x₁+7 x₂ + 2x₃ = 9</p>
</blockquote>
<p>** <span style='background-color: #ddffff'> 1) 전향 소거법 단계 ** </span>
첫번째 식에 -2를 곱한 식 -4x₁-2x₂-2x₃= -10</p>
<blockquote>
<p>-4x₁-2x₂-2x₃= -10
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4x₁ - 6x₂= -2</p>
</blockquote>
<hr>
<blockquote>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-8x₂-2x₃ = -12</p>
</blockquote>
<blockquote>
<p>2 x₁+ x₂+ x₃= 5
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-8x₂-2x₃ = -12 
-2 x₁+7x₂ + 2x₃ = 9 </p>
</blockquote>
<p>1번째 식과 3번째 식을 더한다.</p>
<blockquote>
<p>결과 : -8x₂-2x₃ = -12 , 8x₂+ 3x₃ = 14 
=&gt; x₃= 2 </p>
</blockquote>
<p>** <span style='background-color: #ddffff'> 2) 역대입법 단계 ** </span>
x₃= 2를 1번째,2번째 식에 대입하여 x₂= 1, x₁ = 1 을 구한다</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Machine Learning] 머신러닝이란?]]></title>
            <link>https://velog.io/@jungeun-dev/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@jungeun-dev/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sun, 03 Oct 2021 05:26:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jungeun-dev/post/1a883171-36d4-48f7-a3ee-0f4284883e5c/image.png" alt=""></p>
<h3 id="✔span-stylebackground-color-fafaa0-머신-러닝이란-span">✔<span style='background-color: #FAFAA0'>** 머신 러닝이란? **</span></h3>
<ul>
<li><p>컴퓨터를 인간처럼 학습시킴으로써 인간의 도움 없이 컴퓨터가 스스로 새로운 규칙을 생성할 수 있지 않을까?로 부터 시작 되었습니다.</p>
</li>
<li><p>기계를 어떻게 가르칠 것인가에 따라 크게 세가지로 나눠서 생각할 수 있습니다.</p>
<ul>
<li>Supervised Learning(지도 학습)</li>
<li>Unsupervised Learning(비지도 학습)</li>
<li>Reinforcement Learning(강화 학습)</li>
</ul>
</li>
</ul>
<h3 id="✔-span-stylebackground-color-fafaa0supervised-learning지도-학습span">✔ <span style='background-color: #FAFAA0'>Supervised Learning(지도 학습)</span></h3>
<ul>
<li><p>간단히 말해 여러 문제를 답과 같이 학습함으로써 미지의 문제에 대한 올바른 답을 예측하고자 하는 방법이다. 따라서 학습데이터에는 <span style='background-color: #f5f0ff'><strong>문제와 함께 정답</strong></span>까지 알고있어야 한다.</p>
</li>
<li><p>지도학습을 위한 모델은 크게 Classification(분류)모델과 Prediction(예측)모델로 구분된다.</p>
<ul>
<li><span style='background-color: #f5f0ff'>** Classification(분류) **</span>: 연속적이지 않은 값, 즉 &#39;무엇&#39;을 예측
사용하는 알고리즘에 따라 KNN(K Nearest Neighbor), SVM(Support Vector Machine), Decision trees(의사결정 트리)등으로 구분 된다.<ul>
<li><span style='background-color: #f5f0ff'> ** Prediction(예측) ** </span>: 연속된 값, 즉 &#39;얼마나&#39;을 예측
Regression(회귀)모델이 대표적으로 사용되고 있다.</li>
</ul>
</li>
</ul>
<p>=&gt; 분류모델은 학습데이터의 레이블(답)중 하나가 결과값이 되며, 예측 모델은 학습데이터에서 도출된 함수식에서 계산된 임의의 값이 결과값이 된다.</p>
<h4 id="span-stylebackground-color-f5f0ff--classification-span"><span style='background-color: #f5f0ff'> ** Classification **</span></h4>
<ul>
<li>레이블(정답)이 이산적인 경우로 숫자 인식, 번호판 인식, 스팸메일 구분등 정답이 가질 수 있는 값이 유한한 경우이다.<h4 id="span-stylebackground-color-f5f0ffregression-span"><span style='background-color: #f5f0ff'>Regression </span></h4>
</li>
<li>레이블(정답)이 실수인 경우로 특성들을 바탕으로 구분선을 찾아내는 방법</li>
<li>데이터들을 쭉 뿌려놓고 이를 가장 잘 설명하는 직선 또는 이차함수 곡선을 그리고 싶을때 회귀 기능을 사용한다.</li>
<li>선형회귀 기법이 가장 대표적이며 회귀 분석에서 종속변수란 결과값을 가리키며, 독립변수란 이러한 결과값에 영향을 주는 입력값(특성)들을 가리킨다.<ul>
<li>*<em>Simple Linear Regression Analysis(단순 선형 회귀 분석) *</em>: 하나의 종속 변수, 하나의 독립변수 사이의 관계 분석</li>
<li>*<em>Multiple Linear Regression Analysis(다중 선형 회귀 분석) *</em>: 하나의 종속 변수, 여러개의 독립변수 사이의 관계 분석</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="✔-span-stylebackground-color-fafaa0unsupervised-learning비지도-학습span">✔ <span style='background-color: #FAFAA0'>Unsupervised Learning(비지도 학습)</span></h3>
<ul>
<li>레이블(정답)이 정해져 있지 않은 데이터들을 기반으로 데이터의 고유한 구조나 패턴을 익히는 학습이다. <ul>
<li>Clustering(군집화) : 대표적인 비지도 학습으로 데이터에서 패턴과 구조를 찾아 <strong>그룹</strong>을 지어준다.</li>
</ul>
</li>
</ul>
<h3 id="✔-span-stylebackground-color-fafaa0reinforced-learning강화-학습-span">✔ <span style='background-color: #FAFAA0'>Reinforced Learning(강화 학습) </span></h3>
<ul>
<li>시행착오를 통해 학습하는 방법 중 하나로 실수와 보상을 통해 학습을 하여 목표를 찾아가는 알고리즘이다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 정렬(sorting) - 합병 정렬(Merge Sort)]]></title>
            <link>https://velog.io/@jungeun-dev/Merge-Sort</link>
            <guid>https://velog.io/@jungeun-dev/Merge-Sort</guid>
            <pubDate>Fri, 01 Oct 2021 16:50:40 GMT</pubDate>
            <description><![CDATA[<h2 id="🔨-먼저-분할정복divide-and-conquer이란">🔨 <strong>먼저 분할정복(divide and conquer)이란?</strong></h2>
<ul>
<li>분할, 정복, 결합으로 문제를 2개의 작은 문제로 분할하고 각각을 해결한 다음 , 결과를 모아 원래의 문제를 해결하는 방법이다.</li>
<li>합병 정렬과 퀵 정렬이 해당된다.</li>
</ul>
<h2 id="🔨-합병-정렬">🔨 <strong>합병 정렬</strong></h2>
<ul>
<li>분할 정복 알고리즘의 하나로 힙 정렬처럼 비교에 기초한 정렬이며 O(nlog n)시간에 수행한다.</li>
<li>외부의 우선순위 큐를 사용하지 않고, 데이터를 순차적 방식으로 접근한다.</li>
</ul>
<h3 id="👉--과정-">👉 ** 과정 **</h3>
<ol>
<li>리스트의 길이가 1인 경우 이미 정렬된 것으로 본다. (재귀의 base case) </li>
<li>base case가 아닌경우 리스트를 절반으로 비슷한 크기의 두개의 리스트로 나눈다.</li>
<li>두개로 나뉜 리스트들을 또 각각 재귀적으로 합병 정렬을 이용해 정렬해 준다.</li>
<li>두개로 나뉜 리스트들을 다시 하나의 정렬된 리스트로 결합해준다.
<img src="https://images.velog.io/images/jungeun-dev/post/f303b10f-31d3-4f7f-b16a-66237aee1f84/image.png" alt=""></li>
</ol>
<h3 id="👉-코드-단일-연결리스트-이용">👉 <strong>코드 (단일 연결리스트 이용)</strong></h3>
<h4 id="mergesort">mergeSort()</h4>
<blockquote>
<pre><code class="language-c">linkedList* mergeSort(linkedList* li) {
    linkedList* L1 = li;
    linkedList* L2;

    if (L1-&gt;num == 1) return L1;
    int k = (L1-&gt;num) / 2;
</code></pre>
</blockquote>
<pre><code>L2 = partition(L1, k);
L1 = mergeSort(L1);
L2 = mergeSort(L2);</code></pre><blockquote>
</blockquote>
<pre><code>return merge(L1, L2);</code></pre><p>}
linkedList * partition(linkedList* L, int k) {
    linkedList* re = init();
    node* temp = L-&gt;Header;
    re-&gt;num = L-&gt;num - k;
    L-&gt;num = k;</p>
<blockquote>
</blockquote>
<pre><code>while (temp &amp;&amp; k &gt; 0) {
    temp = temp-&gt;next;
    k--;
}</code></pre><blockquote>
</blockquote>
<pre><code>re-&gt;Header-&gt;next = temp-&gt;next;
temp-&gt;next = NULL;</code></pre><blockquote>
</blockquote>
<pre><code>return re;</code></pre><p>} 
linkedList * merge(linkedList* L1, linkedList* L2) {
    node* tmp1 = L1-&gt;Header-&gt;next;
    node* tmp2 = L2-&gt;Header-&gt;next;
    linkedList * L = init();
    node* tmp3;
    if (tmp1-&gt;key &lt;= tmp2-&gt;key) {</p>
<blockquote>
<pre><code>    L-&gt;Header-&gt;next = tmp1; 
    tmp1 = tmp1-&gt;next;
}
else {
    L-&gt;Header-&gt;next = tmp2;
    tmp2 = tmp2-&gt;next;
}
tmp3 = L-&gt;Header-&gt;next;</code></pre></blockquote>
<pre><code>while (tmp1 &amp;&amp; tmp2) {
    if (tmp1-&gt;key &lt;= tmp2-&gt;key) {
        tmp3-&gt;next = tmp1;
        tmp3 = tmp3-&gt;next;
        tmp1 = tmp1-&gt;next;
    }
    else {
        tmp3-&gt;next = tmp2;
        tmp3 = tmp3-&gt;next;
        tmp2 = tmp2-&gt;next;
    }        
}
while (tmp1) {
    tmp3-&gt;next = tmp1;
    tmp3 = tmp3-&gt;next;
    tmp1 = tmp1-&gt;next;
}
while(tmp2) {
    tmp3-&gt;next = tmp2;
    tmp3 = tmp3-&gt;next;
    tmp2 = tmp2-&gt;next;
}
L-&gt;num = L1-&gt;num + L2-&gt;num;
return L;</code></pre><p>}</p>
<h4 id="전체-코드">전체 코드</h4>
<blockquote>
</blockquote>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
&gt;
//더미 노드 있는 연결리스트
&gt;
typedef struct node {
    int key;
    struct node * next;
}node;
&gt;
typedef struct linkedList {
    struct node* Header;
    int num;
}linkedList;
&gt;
linkedList * init() {
    linkedList* li = (linkedList*)malloc(sizeof(linkedList));
    li-&gt;Header = (node*)malloc(sizeof(node));
    li-&gt;Header-&gt;next = NULL;
    li-&gt;num = 0;
    return li;
}
&gt;
node* createNode(int key) {
    node* new = (node*)malloc(sizeof(node));
    new-&gt;key = key;
    new-&gt;next = NULL;
    return new;
}
&gt;
void addNode(linkedList* li, int key) {
    node* new = createNode(key);
    node* temp = li-&gt;Header;
&gt;
    while (temp-&gt;next) {
        temp = temp-&gt;next;
    }
    temp-&gt;next = new;
    li-&gt;num++;
}
void printList(linkedList* li) {
    node* tmp = li-&gt;Header-&gt;next;
&gt;
    for (int i = 0; i &lt; li-&gt;num; i++) {
        printf(&quot; %d&quot;, tmp-&gt;key);
        tmp = tmp-&gt;next;
    }
    printf(&quot;\n&quot;);
}
linkedList * merge(linkedList* L1, linkedList* L2) {
    node* tmp1 = L1-&gt;Header-&gt;next;
    node* tmp2 = L2-&gt;Header-&gt;next;
    linkedList * L = init();
    node* tmp3;
    if (tmp1-&gt;key &lt;= tmp2-&gt;key) {        
        L-&gt;Header-&gt;next = tmp1; 
        tmp1 = tmp1-&gt;next;
    }
    else {
        L-&gt;Header-&gt;next = tmp2;
        tmp2 = tmp2-&gt;next;
    }
    tmp3 = L-&gt;Header-&gt;next;
&gt;
    while (tmp1 &amp;&amp; tmp2) {
        if (tmp1-&gt;key &lt;= tmp2-&gt;key) {
            tmp3-&gt;next = tmp1;
            tmp3 = tmp3-&gt;next;
            tmp1 = tmp1-&gt;next;
        }
        else {
            tmp3-&gt;next = tmp2;
            tmp3 = tmp3-&gt;next;
            tmp2 = tmp2-&gt;next;
        }        
    }
    while (tmp1) {
        tmp3-&gt;next = tmp1;
        tmp3 = tmp3-&gt;next;
        tmp1 = tmp1-&gt;next;
    }
    while(tmp2) {
        tmp3-&gt;next = tmp2;
        tmp3 = tmp3-&gt;next;
        tmp2 = tmp2-&gt;next;
    }
    L-&gt;num = L1-&gt;num + L2-&gt;num;
    return L;
}
&gt;
linkedList * partition(linkedList* L, int k) {
    linkedList* re = init();
    node* temp = L-&gt;Header;
    re-&gt;num = L-&gt;num - k;
    L-&gt;num = k;
&gt;
    while (temp &amp;&amp; k &gt; 0) {
        temp = temp-&gt;next;
        k--;
    }
&gt;
    re-&gt;Header-&gt;next = temp-&gt;next;
    temp-&gt;next = NULL;
&gt;
    return re;
} 
&gt;
linkedList* mergeSort(linkedList* li) {
    linkedList* L1 = li;
    linkedList* L2;
&gt;
    if (L1-&gt;num == 1) return L1;
    int k = (L1-&gt;num) / 2;
&gt;
    L2 = partition(L1, k);
    L1 = mergeSort(L1);
    L2 = mergeSort(L2);
&gt;
    return merge(L1, L2);
}
&gt;
int main() {
    int n;
    int key;
    linkedList* li = init();
&gt;
    scanf(&quot;%d&quot;, &amp;n);
    for (int i = 0; i &lt; n; i++) {
        scanf(&quot;%d&quot;, &amp;key);
        addNode(li, key);
    }
    li = mergeSort(li);
&gt;
    printList(li);
}</code></pre>
<h3 id="👉-합병정렬-알고리즘-시간-복잡도">👉 <strong>합병정렬 알고리즘 시간 복잡도</strong></h3>
<p>** &lt; 시간 복잡도 계산 &gt; **</p>
<ul>
<li><p><span style='background-color: #FAFAA0'>분할 단계</span> : 비교 연산과 이동 연산이 수행 되지 않는다.</p>
</li>
<li><p><span style='background-color: #FAFAA0'>합병 단계</span> : 이진 트리로 도식화 할 수 있다. 트리의 높이는 log n 이고 한번의 합병 단계에서는 n번의 비교연산을 한다.
<img src="https://gmlwjd9405.github.io/images/algorithm-merge-sort/sort-time-complexity-etc.png" alt="img"></p>
</li>
<li><p><span style='background-color: #FAFAA0'>이동 횟수</span>: 깊이 (log n) * 이동 (2n) (=n개의 요소가 임시배열에 복사 된 뒤 다시 가져오므로) = 2nlog(n)</p>
<ul>
<li><span style='background-color: #f5f0ff'> <strong>T(n) = nlog n(비교) + 2nlog n(이동)  = O(nlog n)</strong></span>
<img src="https://images.velog.io/images/jungeun-dev/post/d580511a-f524-4df6-86d7-8c127fc9a345/image.png" alt=""></li>
</ul>
<p>다음 표를 보면 <span style='background-color: #f5f0ff'> <strong>(퀵정렬,힙정렬, 합병정렬) **</span>은 
다른 정렬에 비해 <span style='background-color: #f5f0ff'></strong>효율적** </span>이다는 것을 알수있다.</p>
</li>
</ul>
<h3 id="👉-합병정렬-알고리즘-특징">👉 <strong>합병정렬 알고리즘 특징</strong></h3>
<ul>
<li><p><strong>장점</strong></p>
<ul>
<li><span style='background-color: #f5f0ff'>안정 정렬</span> 로 중복된 값을 입력 순서와 동일하게 정렬 해준다.</li>
<li><span style='background-color: #f5f0ff'>시간 복잡도가 좋은 편 </span>이다.</li>
<li>데이터의 분포의 영향을 덜 받는다.</li>
<li>만일 연결리스트로 구성하면, 링크 인덱스만 변경하면 되므로 제자리 정렬이 가능하다.</li>
</ul>
</li>
<li><p><strong>단점</strong></p>
<ul>
<li>배열로 정렬시 추가적인 리스트가 필요하다.(제자리정렬이 아니다)</li>
<li>자료가 큰 경우 이동횟수가 많다.</li>
</ul>
</li>
</ul>
<h3 id="👉-관련된-post">👉 <strong>관련된 post</strong></h3>
<ul>
<li>선택 정렬(selection sort) : <a href="https://velog.io/@jungeun-dev/Selection-Sort">Selection Sort</a></li>
<li>삽입 정렬(insertion sort) : <a href="https://velog.io/@jungeun-dev/insertion-sort">Insertion Sort</a></li>
<li>힙 정렬(heap sort) : <a href="https://velog.io/@jungeun-dev/Heap-Sort">Heap Sort</a></li>
<li>합병 정렬(merge sort) : <a href="https://velog.io/@jungeun-dev/Merge-Sort">Merge Sort</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스](Graph) - 순위 (C++)]]></title>
            <link>https://velog.io/@jungeun-dev/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Graph-%EC%88%9C%EC%9C%84-C</link>
            <guid>https://velog.io/@jungeun-dev/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Graph-%EC%88%9C%EC%9C%84-C</guid>
            <pubDate>Fri, 01 Oct 2021 05:42:44 GMT</pubDate>
            <description><![CDATA[<h2 id="👉-문제-주소-👈">👉 <a href="https://programmers.co.kr/learn/courses/30/lessons/49191">문제 주소</a> 👈</h2>
<h3 id="1-문제">1. 문제</h3>
<blockquote>
<p>n명의 권투선수가 권투 대회에 참여했고 각각 1번부터 n번까지 번호를 받았습니다. 권투 경기는 1대1 방식으로 진행이 되고, 만약 A 선수가 B 선수보다 실력이 좋다면 A 선수는 B 선수를 항상 이깁니다. 심판은 주어진 경기 결과를 가지고 선수들의 순위를 매기려 합니다. 하지만 몇몇 경기 결과를 분실하여 정확하게 순위를 매길 수 없습니다.</p>
</blockquote>
<blockquote>
<p>선수의 수 n, 경기 결과를 담은 2차원 배열 results가 매개변수로 주어질 때 정확하게 순위를 매길 수 있는 선수의 수를 return 하도록 solution 함수를 작성해주세요.
<img src="https://images.velog.io/images/jungeun-dev/post/f660499a-d495-4910-92b6-e7aa53bc9d1f/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/jungeun-dev/post/b6427ffa-58e5-43e5-a843-6b3a5c82449c/image.png" alt=""></p>
</blockquote>
<h3 id="2-생각-과정">2. 생각 과정</h3>
<p>(다소 더럽긴하지만,,,,)
<img src="https://images.velog.io/images/jungeun-dev/post/b85078b0-b83a-4064-b937-cd27ab788a41/image.png" alt=""></p>
<blockquote>
<p>각 선수마다 bool배열을 만들어준다.
해당 bool배열은 해당 선수와의 대결에서 이겼는지 졌는지 알수있다면 true로 바꾼다.
위의 예시 5명의 선수를 예를 들면 2번 선수는 
자기 자신과의 대결은 바로 true로 바꿔지고, 5와의 대결에서 승리하여 2,5가 true로 바뀐다. 그다음 누구한테 졌는가를 찾아보면 4,3,1에게 패배하여 4,3,1이 true로 바뀐다. 그러면 5개의 bool배열이 true로 되면 이는 2번 선수가 몇등인지 알수있다는 것이다.</p>
</blockquote>
<p>먼저 각 선수들이 누구한테 졌는지 확인하고 그다음 누구한테 이겼는지 확인한다. 확인 과정은 bfs로 큐에 확인해야할 선수들을 넣어주는 방식이다.</p>
<blockquote>
<p>bfs 과정을 말로 설명해보면,
예를 들어 5번 선수가 누구한테 졌는지 알아본다고 하자, results를 확인하면 5번 선수는 2번 선수에게 졌다는 걸 알 수있다. 그러면 2번 bool은 true가 되고 queue에 2번이 담긴다. 그리고 더이상 queue에 담을 선수가 없으니 2번을 pop해주면 2번에게 진 선수들 4,3,1이 모두 queue에 담기고 해당 bool은 true가 된다. 그러면 5번 선수의 bool배열은 1,2,3,4,5 모두 true가 되어 5번 선수의 등수를 알 수 있다는 것을 알수있다.</p>
</blockquote>
<h3 id="3-풀이-코드">3. 풀이 코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;queue&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;vector&lt;int&gt;&gt; results) {
    int answer = 0;

    vector&lt;vector&lt;bool&gt;&gt; info (n + 1 , vector&lt;bool&gt; (n + 1, false));

    // 대결 시 진 애들 표시
    for(int i = 1 ; i &lt;= n ; i++){
        queue&lt;int&gt; q;
        q.push(i);
        info[i][i] = true;
        while(!q.empty()){
            int start = q.front();
            q.pop();

            for(vector&lt;int&gt; r : results){
                if(r[0] == start &amp;&amp; !info[i][r[1]]){
                    info[i][r[1]] = true;
                    q.push(r[1]);
                }
            }
        }
    }

    // 대결시 이긴 애들 표시
    for(int i = 1 ; i &lt;= n ; i++){
        queue&lt;int&gt; q;
        q.push(i);
        while(!q.empty()){
            int start = q.front();
            q.pop();

            for(vector&lt;int&gt; r : results){
                if(r[1] == start &amp;&amp; !info[i][r[0]]){
                    info[i][r[0]] = true;
                    q.push(r[0]);
                }
            }
        }
    }

    for(vector&lt;bool&gt; bools : info){
        int i = 0;
        for(bool b : bools) {
            if(b == true) i++;
        }
        if(i == n) answer++;
    }                                       
    return answer;

}</code></pre>
<p>문제풀이 글을 처음 쓰고 해서 풀이 생각과정을 말로 길게 써보았다.
(질문 또는 지적이 있다면 댓글 남겨주시면 감사하겠습니다 🙇‍♀️)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 정렬(sorting) - 힙 정렬(Heap Sort)]]></title>
            <link>https://velog.io/@jungeun-dev/Heap-Sort</link>
            <guid>https://velog.io/@jungeun-dev/Heap-Sort</guid>
            <pubDate>Tue, 28 Sep 2021 07:36:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jungeun-dev/post/77e4fbb3-18c9-4671-886d-8bd012f4e367/image.png" alt=""></p>
<h2 id="🔨-먼저-힙heap이란">🔨 <strong>먼저 힙(Heap)이란?</strong></h2>
<p><img src="https://images.velog.io/images/jungeun-dev/post/78e2ec1a-d2c5-49c5-a48d-7a33686139f8/image.png" alt=""></p>
<ul>
<li>최댓값 및 최솟값을 찾아내는 연산을 빠르게 하기 위하여 고안된 <strong>완전 이진 트리</strong>를 기본으로 한 <strong>자료구조</strong><blockquote>
<ul>
<li><strong>최대 힙</strong> : 부모노드의 키값이 자식노드의 키값보다 항상 크다.</li>
<li><strong>최소 힙</strong> : 부모노드의 키값이 자식노드의 키값보다 항상 작다.
키 값의 대소관계는 오로지 부모와 자식 관계에서만!! 형제사이에서는 안정해져있다 !</li>
</ul>
</blockquote>
</li>
</ul>
<p>👉 이번 과정에서는 최대 힙을 이용한 내림차순 정렬을 알아보려고 한다</p>
<h2 id="🔨-힙-정렬">🔨 <strong>힙 정렬</strong></h2>
<ul>
<li>최대 힙 트리 or 최소 힙 트리를 구성하여 정렬 하는 방법</li>
<li>내림 차순 정렬을 위해서는 최대힙을 구성, 오름차순 정렬을 위해서는 최소 힙을 구성</li>
</ul>
<h3 id="👉--과정-">👉 ** 과정 **</h3>
<p> ** &lt;내림차순의 경우&gt; **</p>
<ol>
<li>n개의 자료들로 최대 힙을 만든다.</li>
<li>힙에서 root의 자료(최대값)를 꺼내서 배열의 뒤로 저장한다.</li>
<li>다시 힙 정렬 (그 다음 최대값이 root로 정렬됨)</li>
<li>위의 과정 반복 하면 감소되는 순서로 배열에 저장된다</li>
</ol>
<h3 id="👉-최대-힙max-heap-구현-삽입식-힙-">👉 *<em>최대 힙(Max Heap) 구현 (삽입식 힙) *</em></h3>
<blockquote>
<p>힙 구현시 연결리스트과 배열을 이용하여 구현 할 수 있다. 
 이번 과정에서는 배열을 이용한 순차 힙에 대해 다루겠다.</p>
</blockquote>
<p>**<span style='background-color: #ddffdd'> 1. 최대 힙(max heap) 삽입 ** </span>
<img src="https://ehpub.co.kr/wp-content/uploads/2016/06/10.-%EC%B4%88%EA%B8%B0-%ED%9E%99-%EA%B5%AC%EC%84%B1.png" alt="img"></p>
<blockquote>
<ol>
<li>새로운 요소가 들어왔을 때, 가장 마지막 노드에 이이서 삽입한다.</li>
<li>힙 순서 속성 복구 ( 부모 노드들과 교환해서 제자리를 찾는다)</li>
</ol>
</blockquote>
<pre><code class="language-c">int H[101]; // 전역 변수 H배열
int n; // 전역 변수 요소 개수

void insertItem(int key) {
    n++;
    H[n] = key; // 마지막 노드에 삽입
    upHeap(n);
    printf(&quot;0\n&quot;);
}

//힙 순서 복구 (부모와 비교하여 교환)
void upHeap(int idx) {
    int parent = idx / 2; 
    int tmp;
    if (H[parent] &lt; H[idx] &amp;&amp; parent &gt;=1) {
        tmp = H[parent];
        H[parent] = H[idx];
        H[idx] = tmp;
        upHeap(parent);
    }
    return;
}
</code></pre>
<p>** <span style='background-color: #ddffdd'> 2. 최대 힙(max heap) 삭제 **</span>
<img src="https://ehpub.co.kr/wp-content/uploads/2016/06/9.-%ED%9E%99-%EC%A0%95%EB%A0%AC-%EC%88%98%ED%96%89-%EA%B3%BC%EC%A0%95.png" alt="img"></p>
<blockquote>
<ol>
<li>루트 노드(최댓값) 삭제</li>
<li>삭제된 루트 노드에 힙의 마지막 노드를 가져온다</li>
<li>힙 순서 속성 복구 (자식 노드들과 비교해서 제자리를 찾는다)</li>
</ol>
</blockquote>
<pre><code class="language-c">int H[101]; // 전역 변수 H배열
int n; // 전역 변수 요소 개수

int removeMax() {
    int key = H[1];
    H[1] = H[n--];
    downHeap(1);
    return key;
}
void downHeap(int idx) {
    int left = idx * 2;
    int right = idx * 2 + 1;
    int tmp;

    if (left &lt;= n) {
        if (right &lt;= n) {
            if (H[left] &gt; H[right]) {
                if (H[idx] &lt; H[left]) {
                    tmp = H[idx];
                    H[idx] = H[left];
                    H[left] = tmp;
                    downHeap(left);
                }
            }
            else {
                if (H[idx] &lt; H[right]) {
                    tmp = H[idx];
                    H[idx] = H[right];
                    H[right] = tmp;
                    downHeap(right);
                }
            }
        }
        else {
            if (H[idx] &lt; H[left]) {
                tmp = H[idx];
                H[idx] = H[left];
                H[left] = tmp;
            }
        }
    }
    else return;
}
</code></pre>
<h3 id="👉-선택정렬-알고리즘-시간-복잡도">👉 <strong>선택정렬 알고리즘 시간 복잡도</strong></h3>
<p>** &lt; 시간 복잡도 계산 &gt;    **                   </p>
<ul>
<li>완전 이진 트리의 경우 높이가 log n이므로 하나의 요소 삽입시 힙을 재정비 하는 시간이 log n만큼 소요</li>
<li>요소의 개수가 n개 이므로 전체적으로 O(nlog n)</li>
<li><span style='background-color: #f5f0ff'> *<em>T(n) = O(nlog n) *</em></span></li>
</ul>
<p><img src="https://gmlwjd9405.github.io/images/algorithm-heap-sort/sort-time-complexity.png" alt="img"></p>
<p> 다음 표를 보면 <span style='background-color: #f5f0ff'> <strong>(퀵정렬,힙정렬, 합병정렬) **</span>은 
 다른 정렬에 비해 <span style='background-color: #f5f0ff'></strong>효율적** </span>이다는 것을 알수있다.</p>
<h3 id="👉-삽입정렬-알고리즘-특징">👉 <strong>삽입정렬 알고리즘 특징</strong></h3>
<ul>
<li><strong>장점</strong><ul>
<li><span style='background-color: #f5f0ff'>시간 복잡도가 좋은 편 </span>이다.</li>
<li>전체 자료 정렬이 필요한 경우가 아닌 <span style='background-color: #f5f0ff'>가장 큰 값(작은 값) 몇개만 필요한 경우  </span> 매우 유용하다.</li>
</ul>
</li>
</ul>
<h3 id="👉-관련된-post">👉 <strong>관련된 post</strong></h3>
<ul>
<li>선택 정렬(selection sort) : <a href="https://velog.io/@jungeun-dev/Selection-Sort">Selection Sort</a></li>
<li>삽입 정렬(insertion sort) : <a href="https://velog.io/@jungeun-dev/insertion-sort">Insertion Sort</a></li>
<li>힙 정렬(heap sort) : <a href="https://velog.io/@jungeun-dev/Heap-Sort">Heap Sort</a></li>
<li>합병 정렬(merge sort) : <a href="https://velog.io/@jungeun-dev/Merge-Sort">Merge Sort</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>