이진탐색트리(Binary Search Tree)




















학습참고 : https://www.youtube.com/watch?v=9ZZbA2iPjtM


반응형

Queue 큐




큐는 스택과 다르게 앞뒤가가 뚫린 긴통이라고 보면 된다. 즉 입구와 출구가 다르다.

뒤에서 넣고 앞에서 꺼낸다. 그래서 먼저 들어간 것이 제일 먼저 나오는 FIFO구조이다.


큐를 조작하는 방법에는 put동작과 get동작이 있다.

put  : 뒤에서 넣음

get  :  앞에서 꺼냄




사진 : 위키백과


 

큐 구현방법에는 배열구현과 연결리스트 구현이 있다. 


큐노드 클래스



큐 초기화(이중연결 리스트)


Put

K의 값은 가지는 노드를 만들어 꼬리의 앞에 삽입한다. 


Get

큐가 비었는지 확인하고(머리노드 다음이 꼬리이면 꺼낼 노드가 없다)

C++같은 메모리 직접 관리가 가능한 언어는 당연히 메모리를 삭제했으니 메모리해제과정이 필요하다.


출력


확인

맨처음 put한 데이터가 맨 위에있다.


Get테스트




반응형

이진트리 구현


순회종류의 맞게 출력결과를 보기 위해 테스트해봤다.


트리는 목적/구성에 따라 맞는 순회방법을 결정해주어야한다.




테스트예제



레벨그림



결과

1. 전위순회(Preorder) - 루트 -> 왼쪽서브트리 -> 오른쪽 서브트리

2. 후위순회(Posterorder) - 왼쪽서브트리 -> 오른쪽서브트리 -> 루트 

3. 중위순회(Inorder) - 왼쪽서브트리 -> 루트 -> 오른쪽서브트리


반응형

'알고리즘자료구조 > 자료구조' 카테고리의 다른 글

이진탐색트리(Binary Search Tree)  (0) 2019.03.22
Queue 큐_이중연결리스트 구현  (0) 2019.03.21
트리구조_이진트리(Binary tree)  (0) 2019.03.18
Tree구조  (0) 2019.03.17
알고리즘)재귀호출  (0) 2019.03.10

트리


어떤 요구조건을 만족하는 정점과 선분들의 비어있지 않는 집합

정점은 또한 노드라고도 표현한다.


노드 : 동그라미 하나하나 트리의 요소를 나타냄

루트노드 : 부모노드의 최상단

단말노트 : 자식이 없는 노드

서브트리 : 트리안에 존재하는 트리

트리의 높이 : 가장 최상단부터 레벨을 1,2,3이라 매긴다.



트리의 성질

트리에는 어떤 두 노드를 연결 하는 경로는 한개다. (부모-자식간 양방향의 경로가 있어도 경로는 한개)



최소 공통 선조

어떤 두 노드는 최소 공통 선조를 지님.

루트가 최소공통선조가 되거나 근의 자식들중의 부분트리에 두 노드가 속하게 되므로 최소 공통선조는 항상 존재

각 노드가 최소공통 선조에 이르는 경로를 연결하면 두 노드간 최소 경로가 된다.



이진트리(Binary tree)


각각의 노드가 최대 두 개의 자식 노드를 가지는 트리 자료 구조로, 자식 노드를 가지는 트리 구조로,

 자식 노드를 각각 왼쪽 자식 노드와 오른쪽 자식 노드라고 한다.


이진트리 순회방법

목적/구성에 따라 순회하는 방법이 다르다.(기준은 루트노드 기준)


1. 전위순회(Preorder) - 루트 -> 왼쪽서브트리 -> 오른쪽 서브트리

F, B, A, D, C, E, G, I, H (root, left, right)


2. 중위순회(Inorder) - 왼쪽서브트리 -> 루트 -> 오른쪽서브트리

A, B, C, D, E, F, G, H, I (left, root, right)


3. 후위순회(Posterorder) - 왼쪽서브트리 -> 오른쪽서브트리 -> 루트

A, C, E, D, B, H, I, G, F (left, right, root)




학습참고 :

https://ko.wikipedia.org/wiki/%ED%8A%B8%EB%A6%AC_%EC%88%9C%ED%9A%8C

https://coderkoo.tistory.com/9


반응형

'알고리즘자료구조 > 자료구조' 카테고리의 다른 글

이진탐색트리(Binary Search Tree)  (0) 2019.03.22
Queue 큐_이중연결리스트 구현  (0) 2019.03.21
트리구조_이진트리(순회방법)_연습  (0) 2019.03.19
Tree구조  (0) 2019.03.17
알고리즘)재귀호출  (0) 2019.03.10

Tree구조



naver


트리는 2차원적 비 선형구조이다. 

나무의 모양을 거꾸로 뒤집어 놓은 모양이다. 

뿌리가 가장 위에 있으며 가지(link)들은 밑으로 벌어지며 향한다.



트리구조에서 쓰는 용어


노드 :  어떤 정보를 담고 있다

링크 :  노드간의 연결을 나타냄

경로 : 나무 내에서 링크에 의해 연결된 일년의 노드의 집합




루트(root) : 나무의 제일 위에 있는 있는 노드, 뿌리노드라고 하며 이 뿌리 노드로부터 다른 노드에 이르는 경로는 오직 하나 밖에 존재하지 않는다. ex 위 그림에서는 0노드가 루트(뿌리)노드


부모자식관계  :  노드 1(부모)과 3,4(1노드의 자식)은 부모 자식관계이다.


조부모노드 : 두 단계 위에있는 노드를 가리킬때 ex 노드1은 노드7의 조부모


레벨 : 뿌리 노드로부터 현재 노드까지 의 경로를 거치는 동안의 노드 수를 말한다. 즉 뿌리노드로부터 얼마나 떨어져 있는가 ex 밑에서 부터 4레벨(7,8,9,10,11,12,13,14),3레벨(3,4,5,6),2레벨(1,2),1레벨(0) 올라감


형제관계 :같은 레벨에 있는 노드들은 형제 관계이다. ex (1, 2)노드들은 형제관계 (3 , 4 , 5 , 6 )노드들은 형제관계


종료 노드 : 자식이 없는 노드 ex (7,8,9,10,11,12,13,14)노드



트리의 성질


-나무 구조에서 한 노드에서 다른 노드로 가는 경로는 유일하다.

(나무를 타는 경로가 중복되지않고, 되돌아감이 없다면)

나무구조의 임의의 두 노드는 최소 공통 선조(두 노드가 갖는 가장까운 부모 노드)를 갖는다. 



-N개의 노드를 갖는 나무는 N-1개의 링크를 가진다.

트리구조는 뿌리 노드를 제외하고 모든 노드가 자신의 선조를 향해 하나의 링크를 갖는다.

그래서 N개의 노드를 가진 나무는 N-1개의 링크를 가진다



-꽉 찬 이진트리는 레벨이 d라고 할때 노드의 수는 N이 다음과 같은 조건을 만족한다.




학습참고 : C로배우는 알고리즘_이재규



반응형

병합정렬(merge sort)


병합의 개념 : 두개 이상의 정렬된 자료집합을 하나의 정렬된 자료집합으로 합치는 것


병합의 방법 : 대상 자료집합이 정렬된 상태이므로 순차적으로 작은 자료를 뽑아서 놓으면됨



장점 :안정적인 정렬 방법

데이터의 분포에 영향을 덜 받는다.

즉, 입력 데이터가 무엇이든 간에 정렬되는 시간은 동일하다. (O(nlog₂n)로 동일)


단점 :

만약 레코드를 배열(Array)로 구성하면, 임시 배열이 필요하다.

제자리 정렬(in-place sorting)이 아니다.

(나열된 것 중에 가장 작은 또는 가장 큰 것을 선택하여 앞 또는 끝으로 보내는 작업을 반복하여최종적으로 크기 순서대로 정렬이 되는 방식.(오름차순 , 내림차순))



두 집합이 병합되는 부분


i: 정렬된 왼쪽 리스트에 대한 인덱스

j: 정렬된 오른쪽 리스트에 대한 인덱스

k: 정렬될 리스트에 대한 인덱스



실제로 숫자들이 정렬되는 과정




반응형

거품 정렬


배열의 인접 요소를 비교하여 교환하는 모양이 보글보글하다고 해서 붙여진 이름이다.


거품 정렬은 인접한 배열의 요소를 비교 교환하여 전체적으로는

대충 정렬을 하면서 최대값을 배열의 제일 뒤로 보내는 것을 반복한다.



거품 정렬의 개선

아래 함수를 추가하여 정렬이 되어있는 체크





정렬이 되어 있다면 바로 빠져 나오도록

(but 정렬이 되어있을때는 시간이 적지만 그렇지 않을 경우는 더 시간이 느려진다.

s=0과 if s인지 판단하는 문장이 추가 됐기 때문)



반응형

재귀호출



자기자신을 호출한다.

재귀적으로 문제를 해결함은 또 문제를 점점 더 작은 단위로 쪼개어 해결함을 의미한다.



잘못된 재귀 호출

문제 해결에 변화없는 호출

void rose()

{ rose(); }

무한루프 -> 시스템 내부의 스택에 복귀주소와 인자를 저장해야 하기 때문에

스택에는 자료가 쌓인다.




재귀 호출의 요건

재귀호출이 이루어질 때마다 문제는 점점 작아져야 하고,

재귀 호출이 끝이 나는 종료 조건이 있어야 한다.




1. 거듭제곱을 구하는 재귀 함수


N의 거듭 제곱은 N!이라고 표현한다.


ex) 4를 넣었을때

4 x(3 x(2 x(1 ))) = 24

//0! 되면 재귀함수 탈출




2. 피보나치 수열 구하는 재귀 함수

한 함수 내에서 한번만 이루어져야 하는 것은 아니다.

한 함수 내에서 두 번 혹은 그 이상도 자기자신을 호출할 수 있다.






3. 하노이의탑


세 개의 기둥과 서로 다른 크기의 N개의 원반으로 구성된다. 이 원반들은 세 개의 기둥 중의 하나에 반드시 꽂혀 있어야하며, 자신보다 작은 원반 위에는 그 원반을 놓을 수 없다.

즉 원반은 아래에 가장 큰 것이 와야하며, 자신보다 큰 원반은 자기 위에 놓을 수 없다.


N이 3일때

  1. 기둥 1의 원반을 기둥 3으로 옮긴다

  2. 기둥 1의 원반을 기둥 2로 옮긴다.

  3. 기둥 3의 원반을 기둥 2로 옮긴다.

  4. 기둥 1의 원반을 기둥 3으로 옮긴다.

  5. 기둥 2의 원반을 기둥 1로 옮긴다.

  6. 기둥 2의 원반을 기둥 3으로 옮긴다.

  7. 기둥 1의 원반을 기둥 3으로 옮긴다.


재귀적 표현

  1. 기둥 1에서 N-1개의 원반을 기둥 2로 옮긴다.

  2. 기둥 1에서 1개의 원반을 기둥 3으로 옮긴다.

  3. 기둥 2에서 N-1개의 원반을 기둥 3으로 옮긴다.



원반 n개 , from 기둥에서 to 기둥으로 by기둥을 이용해서 옮기는 과정

           void hanoi(int n, int from ,int by, int to)

           {

               if (n == 1)

               {

                   move(from, to);

               }

               else

               {

                   hanoi(n - 1, from, to, by); //알고리즘 1번

                   move(from, to);        //알고리즘 2번

                   hanoi(n - 1, by, from, to); //알고리즘 3번

               }

           }

           void move(int from, int to)

           {

               Console.WriteLine(string.Format("{0}에서~{1}로 ",from,to));

           }


<결과>





반응형

문제

int형 배열과 정수 k를 입력받는데, 배열 요소에 정수 k를 더 했을 경우 k를 더하지 않은 요소들과 비교해가장 큰 수가 될 경우를 카운팅해서 출력하는 문제이다. 

예를 들어 2,3,5,2 배열이 주어지고 정수 3이 주어지면 첫 번째 요소( 2 )에 정수k인 3을 더하면 5가 되는데 나머지 요소와 비교했을 때 가장 큰 수가 아니기 때문에 카운트하지 않게 된다.

이렇게 차레대로 비교를 하면 되는데 요소 3일 경우와 5일 경우는 정수 k를 더했을 때 요소중 가장 큰 수가 되기 때문에 출력 결과는 2를 출력하면 된다.

조건 : 요소 비교 중 값이 같을 경우는 가장 큰수가 될 수 없다.

 

풀이

처음 생각하기에는 처음 요소를 다른 요소와 비교하면서 가장 크다고 판단되면 카운트해서 그 카운트가 배열의 길이에서 1을 뺀 수와 같으면(자기 자신을 제외한 다른 요소들의 개수) 가장 크다고 판단하여 그 개수를 출력하려고 했지만.. 

위에 경우 처럼 배열의 길이에서 1을 뺀 값을 나를 제외한 나머지 요소들의 개수라고 판단해버리면 배열 요소 중 자신과 같은 값을 갖고 있는 요소가 있게 되면 요소에 k를 더한 후 비교할 때 동점인 경우는 체크하지 않기 때문에 카운트 값이 맞지 않는다.

반대로 생각해보면  k를 더한 요소보다 더하지 않은 요소중에 더 큰 경우가 있다면? 더 비교할 필요도 없이 그 요소는 배열의 요소중 가장 큰 요소라고 할 수 없다. 

if(i!=j && vote[j] >= max) : 자기 자신과의 비교는 제외하고, 배열의 요소중 더 큰 값이 있다면 break 키워드로 반복문을 빠져나온다.

if(cnt ==0 ) : cnt가 0인 경우가 자기 자신이 가장 큰 경우(k를 더했을 때)이기 때문에 cnt가 '0'인 요소일 때 resscent를 증가시키고 최종적으로 반환한다.

cnt를 bool 플래그로 쓴 것이다.

 

arcde46

반응형

'알고리즘자료구조 > 알고리즘문제' 카테고리의 다른 글

03.28_CodeSignal  (0) 2019.03.28
03.27_CodeSignal  (0) 2019.03.27
03.26_CodeSignal  (0) 2019.03.26
02.05_CodeSignal(체스 말판)  (0) 2019.02.05
02.03_CodeSignal(자릿수를 줄인 가장 큰 수)  (0) 2019.02.03

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀 점

문제

체스 말판이 위 특정 셀에 위치할 때 움직일 수 있는 방법의 개수를 구하는 문제이다.  특정 위치 이기 때문에  특정 셀 밑이거나 위에 있을 때 제한된다.

풀이 : 내가 작성한 코드

 

메모장에 적으면서

 처음 생각하기에 문자열의 앞cell[0]뒤cell[1] 8방향의 이동하게 문자를 더하는 값으로 확인이 가능할까 생각했지만 안된다고 판단하고, 체스 말이 위 체스 말이 움직 일 수 있는 방법이 최대 8가지이기 때문에 8방향을 모두 체크하고 각각 케이스에 검사하는 방법밖에 생각이 안 났다. 그래서 그냥 case문을..

풀이 : 다른 사람이 작성한 코드

가장 높은 vote를 받은 코드이다. 5개의 길이의 배열을 만드는데 무엇인가 했더니 체스 말판이 움직일 수 있는 방향 개수들이다. 그다음으로 문자 알파벳과 숫자를 체크하는데 'a'나 'h'를 빼는 이유는 체스가 저 두 문자에 위치했을 때 이동 방향 개수가 제한된다. 또, 체스 말판이 a에 가깝나 h에 가깝나를 체크한다. Math.Min(int,int )는 둘 중 작은 수를 반환하는 함수인데, 'a', h'에 가깝지 않아 2를 넘으면 4방향은 이동 가능이 보장이 된다. 반대로  마찬가지로 숫자 부분도 체크하여 리턴된 두 정수를 더한 뒤 배열에서 찾는다.. 

일단 문제 접근에 대한 방식 자체가 다르다ㅜ. 훨씬 더 깔끔하고 나도 문제에서 8가지 방향을 정해져 있다고 판단하고 포문을 8번 돌렸지만, 이 코드는 한 번 더 생각하여 제한된 이동 방향 개수 생각하고 그 값을 배열로 넣어두었다. 그리고 dist라는 말의 칸 이동 수가 정해져 있기 때문에 체스판 테두리에 가까웠을 때 제한되는 방법으로 깔끔하게 구현했다. 역시 접근 방법은 여러 가지로 생각하는 게 좋겠다. 

문제 : https://codesignal.com/

반응형

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀 점

문제

문자 열중의 문자 한개를 빼서 자릿수를 하나 줄여 가장 큰 수를 출력하는 문제이다. 

풀이 : 내가 작성한 코드

문자열중 가장 작은 수를 빼면 가장 큰 수가 나 올 줄 알았다.  그런데 222250은  0이 가장 작은데 22225가 된다. 하지만 답은 22250이 되어야 하고 그래서 이건 아니고..., 앞 자릿수보다 뒷자리수가 크면 앞 자릿수를 빼면 된다. 인덱스 비교로 현재 값보다 다음 자릿수의 값이 크면 break로 빠져나와 그 숫자를 제거한다.

풀이 : 다른 사람이 작성한 코드

string s로 처음 받아온 숫자를 문자열로 바꾼 뒤 그 문자열에 서 해당하는 문자만 빼고 int형으로 리턴했다. 나는 형 변환도 많고, 굳이 안 써도 되는 집합 자료구조는 등 많이 사용하는 게 습관이 됐는데 최대한 쓰지 않는 방법으로 문제를 풀도록 해야겠다. 

문제 : https://codesignal.com/

반응형

'알고리즘자료구조 > 알고리즘문제' 카테고리의 다른 글

03.28_CodeSignal  (0) 2019.03.28
03.27_CodeSignal  (0) 2019.03.27
03.26_CodeSignal  (0) 2019.03.26
03.07_CodeSignal(배열의 요소중 가장 큰수일 경우)  (0) 2019.03.07
02.05_CodeSignal(체스 말판)  (0) 2019.02.05

+ Recent posts