트리(Tree)



트리(Tree)?

트리는 비 선형(Non-linear) 자료구조로 root(부모), leaf(자식)로 구성됩니다.


트리의 레벨은 깊이를 의미하며, 높이는 가장 높은 레벨을 의미합니다.


이진트리?

이진트리 : 이진트리는 가장 널리 쓰이는 트리의 형태로, 자식을 1~2개만 가지는 트리



이진트리의 레벨이 d, 노드의 수가 N이라고하면

아래 식을 만족합니다.

완전 이진트리?


최 하위 노드를 제외하고 자식노드가 꽉찬 트리



연결리스트를 이용한 이진트리 예제


트리는 비 선형구조라 순서가 없지만, 자동으로 입력하기위해 순서를 부여 하였습니다.


tree로 사용할 구조체 


값, 자식 노드(left, right)와 

값을 자동으로 넣기 위해 next 할당


초기 root와 부모노드를 위한 변수 parent 선언


parent 노드를 지정해주면서 left, right에 값을 할당


#include "stdio.h"
#include "stdlib.h"

typedef struct _tree
{
char value;
struct _tree *left;
struct _tree *right;
struct _tree *next;
} tree;

tree *root, *parent;


초기화 함수


void init_tree(void){
root = (tree*)malloc(sizeof(tree));
root->left = NULL;
root->right = NULL;
root->value = '\0';
parent = root;
}


트리에 값을 넣는 함수


임시 트리에 값을 할당하고, 최초 root인 경우를 제외하고는 left, right에 할당


tree *addVaule(char value){
tree *new;
new = (tree*)malloc(sizeof(tree));
new->value = value;
new->left = NULL;
new->right = NULL;
if(parent->value != '\0' && parent->left != NULL && parent->right != NULL){
if(!parent->right->next)parent->right->next = new;
parent = parent->next;
}
if(parent->value=='\0'){ // root
parent->value = new->value;
}else if(parent->left == NULL){ // left
parent->left = new;
if(!parent->next)parent->next = new;
}else{ // right
parent->right = new;
if(!parent->left->next)parent->left->next = new;
}
}


순서대로 전위, 중위, 후위 순회 방식으로 출력하는 함수


재귀 방식을 사용해서 출력 합니다.


void printPreorder(tree *t){
printf("%-2c",t->value);
if(t->left)printPreorder(t->left);
if(t->right)printPreorder(t->right);
}
void printInorder(tree *t){
if(t->left)printInorder(t->left);
printf("%-2c",t->value);
if(t->right)printInorder(t->right);
}
void printPostorder(tree *t){
if(t->left)printPostorder(t->left);
if(t->right)printPostorder(t->right);
printf("%-2c",t->value);
}


메인함수

트리를 초기화 한 후 A~G 문자를 삽입 한 후 

전위, 중위, 후위 순회에 맞게 출력합니다.

void main(){
init_tree();
char treeValue[] = {'A','B','C','D','E','F','G'};
for(int i=0; i<sizeof(treeValue); i++){
addVaule(treeValue[i]);
}
printf("PreOrder : ");
printPreorder(root);
printf("\nInOrder : ");
printInorder(root);
printf("\nPostOrder : ");
printPostorder(root);
}

아래와 같은 이진 트리를 생성하고 순회합니다.



실행결과



참고 : C로 배우는 알고리즘 (이재규)




관련 포스팅



'언어 > Data Strcuture' 카테고리의 다른 글

[C] 삽입 정렬(Insertion Sort)  (0) 2019.04.19
[C] 선택 정렬(Selection Sort)  (0) 2019.04.19
[C] 큐(Queue)  (2) 2019.04.01
[C] 스택(Stack)  (1) 2019.03.29
[C] 연결리스트(LinkedList)  (0) 2019.03.28

큐(Queue)



큐(Queue)?

큐는 FIFO(First In First Out)구조로 가장 먼저 들어간 값이 가장먼저 나오는 구조입니다.


삽입하는 put 동작과 삭제하는 get 동작이 있습니다.


front(앞)에서 값을 얻어내고, rear(뒤)에 값을 넣습니다.


1. 큐 형태


2. 큐 종류


큐의 종류는  선형 큐, 원형 큐, 우선순위 큐 등이 있습니다.


- 선형 큐(Linear Queue) : 기본적인 큐의 형태로 막대모양의 큐로 빈 공간 사용 시 모든 자료를 꺼내거나 옮겨야 한다는 단점이 있음

- 원형 큐(Circular Queue) : 선형큐의 단점을 보완하는 구조로 front와 rear가 연결된 형태

- 우선순위 큐(Priority Queue) : 데이터 삽입 시 우선순위에 따라 정렬 후 저장하는 방식




배열을 이용한 원형 큐 예제


원형큐의 경우 front, rear 구분을 위한 공간이 하나 필요합니다.

그래서, 크기가 10인 큐의 경우 사용가능한 공간은 9가 됩니다.


큐로 사용할 int형 배열 선언 및 초기화 함수


#include "stdio.h"
#define MAX 10

int queue[MAX];
int front, rear;

void init_queue(){
front = rear = 0;
}


초기화 함수


front와 rear값을 같게하면 초기화 가능


void clear_queue(){
front = rear;
}


put 함수


(rear+1) % 큐 크기 == front 일 경우 오버 플로우 발생


int put(int k){
if((rear+1) % MAX == front){
printf("QUEUE OVER FLOW!\n\n");
return -1;
}else{
queue[rear] = k;
rear = ++rear % MAX;
return 1;
}


원형큐는 아래 그림과 같이 모듈러를 생각하면 편합니다.

get 함수


front와 rear가 같을 경우 빈 값이므로 언더플로우 발생


int get(){
int k;
if(front == rear){
printf("QUEUE UNDER FLOW!\n\n");
return -1;
}else{
k = queue[front];
front = ++front % MAX;
return k;
}
}


큐의 값을 출력하는 함수


void print_queue(){
printf("\n");
for(int i=front; i!=rear; ++i % MAX){
printf("queue[%d]=%d\n",i,queue[i]);
}
if(front == rear){
printf("queque is empty!!! \n");
}
printf("\n");
}

메인함수

큐의 크기가 10이므로 10번째 값을 넣을때에 오버플로우가 발생하고,
10번째 값을 가져올 때에는 언더플로우가 발생합니다.

void main(){
init_queue();
put(1);
put(3);
put(6);
put(9);
put(7);
put(2);
put(0);
put(0);
put(10);
put(20); // 10번째 값
printf("################################################################\n");
print_queue();
for(int i=0; i<3; i++){
get();
}
printf("################################################################\n");
print_queue();
for(int i=0; i<7; i++){
get();
}
printf("################################################################\n");
put(0);
put(0);
put(10);
clear_queue();
print_queue();
}

실행결과



참고 : C로 배우는 알고리즘 (이재규)




'언어 > Data Strcuture' 카테고리의 다른 글

[C] 삽입 정렬(Insertion Sort)  (0) 2019.04.19
[C] 선택 정렬(Selection Sort)  (0) 2019.04.19
[C] 트리(Tree)  (0) 2019.04.07
[C] 스택(Stack)  (1) 2019.03.29
[C] 연결리스트(LinkedList)  (0) 2019.03.28

스택(Stack)



스택(Stack)?

스택은 LIFO(Last In First Out)구조로 


가장 나중에 들어간 값이 가장먼저 나오는 구조입니다.


삽입하는 PUSH와 삭제하는 POP 동작이 있습니다.


1. 스택 형태


2. PUSH


3. POP




배열을 이용한 예제


스택으로 사용할 int형 배열 선언 및 초기화 함수


#include "stdio.h"
#define MAX 10


int stack[MAX];
int top;


void init_stack(void){
top = -1;
}


스택에 push하는 함수


스택 크기보다 크면 오버플로우 발생


int push(int t){
if(top >=MAX-1){
printf("########### STACK OVER FLOW ###########\n");
return -1;
}else{
stack[++top] = t;
return t;
}
}


스택에서 pop하는 함수


스택 크기보다 작으면 오버플로우 발생


int pop(void){
if(top<0){
printf("########### STACK UNDER FLOW ###########\n");
return -1;
}
return stack[top--];
}

스택의 값을 출력하는 함수


void print_stack(void){
printf("PRINT STACK \n");
for(int i=top; i>=0; i--){
printf("%-6d",stack[i]);
}
printf("\n");
}

메인함수

11개의 값을 push할 경우 10개는 정상적으로 push 되지만,
나머지 1개의 값은 스택 오버플로우가 발생합니다.

두번째 pop을 수행할 때 5개의 값은 정상적으로 pop 되지만,
나머지 1개의 값은 스택 언더플로우가 발생합니다.

void main(){
init_stack();
printf("########### PUSH ###########\n");
for(int i=0; i<11; i++){
push(i);
}
print_stack();
printf("########### POP ###########\n");
for(int i=0; i<5; i++){
pop();
}
print_stack();
for(int i=0; i<6; i++){
pop();
}
}

실행 결과


참고 : C로 배우는 알고리즘 (이재규)






'언어 > Data Strcuture' 카테고리의 다른 글

[C] 삽입 정렬(Insertion Sort)  (0) 2019.04.19
[C] 선택 정렬(Selection Sort)  (0) 2019.04.19
[C] 트리(Tree)  (0) 2019.04.07
[C] 큐(Queue)  (2) 2019.04.01
[C] 연결리스트(LinkedList)  (0) 2019.03.28

[SL-M2077]삼성 흑백 레이저 복합기


안녕하세요 요즘들어 인쇄, 스캔 작업을 할만한 공간이 많이 없는 것 같습니다.

스캔이나 인쇄가 필요할 때마다 고생을 많이해서

큰맘먹고 구매하게 됐습니다.

거의 10년만에 복합기를 구매했습니다.

전체적인 디자인은 깔끔하고 좋았습니다.


어떤 작업을 수행하는지 표시됩니다.



스티커를 다 떼지 않고 사진을 찍었습니다..


새 토너 기준 1,000장까지 인쇄가 가능하다고 합니다.



스캐너의 경우 응용프로그램을 추가 설치가 필요했습니다.


아래 URL에서 다운가능 합니다.


https://www.samsungsvc.co.kr/online/downLoadSrchTab.do?stModelName=SL-M2070&stModelBusinessName=SL-M2070&svcPrdCode=&searchTarget=&svcPrd3Code=&svcPrd2Name=&svcPrd3Name=%C6%D1%BD%C3%B9%D0%B8%AE%2F%BA%B9%C7%D5%B1%E2&dlpage=sl-m2070&anchorG=Y&stModelScrh=sl-m2070



전체적으로 가격대비 만족합니다.

별점으로 4점정도 주고싶네요!

★ ★ ★ ★ ☆





연결리스트(LinkedList)




연결리스트(LinkedList)?

연결리스트는 동적인 자료구조로 배열처럼 메모리에 연속된 공간을 차지하지 않습니다.



1. 단순 연결리스트(Simple LinkedList)


노드와 다음링크를 가리키는 링크로 구성


처음 시작을 의미하는 head와 마지막 노드인 tail로 구성

2. 환형 연결리스트(Circular LinkedList)


가장 마지막 노드가 처음의 노드를 가리키는 연결리스트

3. 이중 연결리스트(Doubly LinkedList)


전, 후 노드를 가리키는 링크를 가지는 연결리스트



단순 연결리스트 예제


구조체 (key, value, 다음을 가리키는 링크로 구성) 선언


typedef struct _node
{
int key; // key
char *value; // value
struct _node *next; // 다음 노드의 위치
} node;
node *head, *tail; // head, tail


초기화 함수

head 와 tail 초기화


void init_list(void){
head = (node*)malloc(sizeof(node));
tail = (node*)malloc(sizeof(node));
head -> next = tail;
tail -> next = tail;
}

노드 삽입 함수
입력받은 노드의 다음에 삽입


node *insert_list(int key, char *value, node *t){
node *s;
s = (node*)malloc(sizeof(node));
s->key = key;
s->value = value;
s->next = t->next;
t->next = s;
return s;
}

노드 삭제 함수
입력받은 노드를 삭제

int delete_list(node *t){
node *s = head;
while(s->next != tail){
if(s->next==t){
s->next = t->next;
free(t);
break;
}else{
s = s->next;
}
}
}

노드 검색 함수
key를 이용해서 원하는 노드를 검색

node *find_node(int key){
node *s = head->next;
while(s != tail->next){
if(key == s->key){
break;
}else{
s = s->next;
}
}
return s;
}


전체 검색 함수

void findAll(){
node * t = head->next;
printf("#########findAll()########\n");
while(t != tail){
printf("find(%d) = %s , address = %d\n",t->key,find_node(t->key)->value,&t->next);
t = t->next;
}
printf("##########################\n");
}

메인 함수
노드 초기화 후 5개 데이터를 추가하고 2개의 데이터 삭제 후 전체 출력

void main(){
init_list();
insert_list(0,"apple",head);
insert_list(1,"banana",find_node(0));
insert_list(2,"melon",find_node(1));
insert_list(3,"grape",find_node(2));
insert_list(4,"pineapple",find_node(3));

delete_list(find_node(2));
delete_list(find_node(1));
findAll();
}

실행 결과



참고 : C로 배우는 알고리즘 (이재규)



관련 포스팅


[Data Strcuture] - 트리(Tree)

[Data Strcuture] - 큐(Queue)

[Data Strcuture] - 스택(Stack)

[Data Strcuture] - 연결리스트(LinkedList)




'언어 > Data Strcuture' 카테고리의 다른 글

[C] 삽입 정렬(Insertion Sort)  (0) 2019.04.19
[C] 선택 정렬(Selection Sort)  (0) 2019.04.19
[C] 트리(Tree)  (0) 2019.04.07
[C] 큐(Queue)  (2) 2019.04.01
[C] 스택(Stack)  (1) 2019.03.29

VSCODE 환경 C개발환경


Visual Studio Code에서 C개발 환경 설정 방법입니다.



1.MinGW 다운로드


아래 URL에서 다운가능합니다.


https://sourceforge.net/projects/mingw-w64/files/latest/download


2. 환경변수 설정


아래 경로와 같이 설치된 경로 \bin폴더까지 복사를 한 후


D:\Program Files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin


Path변수에 추가를 해줍니다.




3. gcc컴파일러 확인


커맨드창 혹은 VSCODE 콘솔창에서 


gcc --version 명령을 통해 컴파일러 버전을 확인합니다.



4. 컴파일 및 테스트


컴파일 확인 결과 exe가 정상적으로 생성되는걸 확인할 수 있습니다.




'언어 > C' 카테고리의 다른 글

[C] 계좌 관리 프로그램  (2) 2017.01.10
[C] 파일 입·출력  (0) 2017.01.05
[C] 자기 참조 구조체와 연결리스트  (2) 2017.01.04
[C] 동적 메모리  (0) 2017.01.03
[C] 공용체  (0) 2016.12.27

mlab(MongoDB Cloud)사용하기


mlab은 MongoDB를 클라우드 형태로 제공해주는 서비스입니다.


관리페이지에서 관리하거나, 직접 원격 연결을 통해서도 관리가 가능합니다.


회원 가입 단계는 생략하였습니다.



1. Create new


로그인 후 메인 화면에서 Create new 버튼을 클릭합니다.



2. Cloud 사, 가격대 별 기능을 선택


3대장이라고 불리는 AWS, Google Colud, Azure 서비스 모두 선택이 가능합니다.


저는 AWS와 프리티어를 선택했습니다.



3. 지역선택


프리티어는 버지니아와, 아이슬란드 둘중 한곳만 선택이 가능합니다.



4. DATABASE name 입력


사용할 데이터베이스 이름을 입력합니다.



5. 확인


앞에서 선택한 옵션, 이름등을 확인하는 화면입니다. 


확인 후 SUBMIT ORDER버튼을 클릭하면 Database가 생성이 됩니다.



6. 생성완료


아까 초기화면에 정상적으로 생성된걸 확인할 수있습니다.



기본적으로 Collection이나 User를 추가할 수 있습니다.



감사합니다!



heroku, Github 연동


최근 클라우딩 서비스가 인기를 많이 끌고 있습니다.


heroku는 github와 간단하게 연동이 가능해서 정말 간단했습니다.


회원 가입 단계는 생략하였습니다.



1. Create New App


New 버튼 클릭 후 Create New App을 클릭합니다.



2. 사용 할 어플리케이션 명을 입력해 줍니다.


아래와 같이 접속 URL이 생성됩니다.


https://어플리케이션명.herokuapp.com


free 티어는 미국, 유럽만 선택 가능합니다.


완료하셨으면 Create App을 선택합니다.



3. deploy 할 레퍼지토리 선택


저는 github를 선택하였습니다.



레퍼지토리 명을 검색하고 선택하면 연결이 됩니다.



4. deploy 


Push가 있을때마다 자동으로 빌드할 수 있는 기능입니다.


저는 따로 선택하지 않았습니다.



github의 경우 브렌치를 선택해서 deploy가 가능합니다.


저는 master 브렌치를 선택해서 디플로이 했습니다.



deploy하는 동안 로그를 확인할 수 있습니다.




5. 확인


deploy가 완료되면 아래와 같이 view버튼일 활성화 됩니다.


view 버튼을 누르면 접속 확인이 가능합니다.


https://어플리케이션명.herokuapp.com




VSCODE 환경 SpringBoot 개발환경



보통 스프링 부트를 사용할 때 STS를 주로 사용하지만,


평소에 자주 사용하는 VSCode에 스프링 부트 개발 환경을 구성 해봤습니다.



가장 먼저, VSCode에서 스프링 부트를 사용하기 위해서는 


아래 두 확장 패키지를 설치해야 합니다.


1. Java Extension Pack(Micosoft)

  - java언어 지원 기능, 디버거, 테스트 실행, maven 프로젝트 관리 등의 확장을 패키징 한 패키지

2. Spring Boot Extension Pack(Pivotal)

  - spring 프레임워크에 적용할 수 있는 유용한 기능이 들어있는 패키지


각각 검색해서 설치 후 창을 다시 열어줍니다.




확장 패키지 설치가 끝났다면, JDK 경로를 설정해줍니다.


[파일] - 기본설정 > 설정을 눌러줍니다.



설정에서 JDK를 검색 한 후 


setting.json에서 편집을 눌러줍니다. 



아래 그림처럼 jdk 경로를 추가해줍니다.


 "java.home" : "jdk 설치 경로" 





jdk 설정까지 끝났다면, spring boot 프로젝트를 생성 해보겠습니다.


[보기] - 명령 팔레트 또는 Ctrl + Shfit + P를 입력해줍니다.


명령 팔레트에서 spring Initalizr를 클릭해줍니다.



언어를 선택하는 화면입니다.


JAVA를 선택 합니다.



Group ID를 지정하는 화면입니다.


저는 com.example로 지정했습니다.



Artifact ID를 지정하는 화면입니다.


저는 demo대신 test로 지정했습니다.



spring boot 버전 선택 화면입니다.


저는 Current 버전인 2.1.3 버전을 선택했습니다.



추가 도구(의존성)를 선택하는 화면입니다.


Spring Boot 개발 도구와 

서블릿을 사용을 위한 Web은 

필수로 선택 해야 할 것 같습니다.



기본적으로 만들어지는 프로젝트 구조입니다.



.\mvnw spring-boot:run 명령을 실행하면 

 

테스트 코드가 동작하는 걸 확인 할 수 있습니다.




'언어 > Spring' 카테고리의 다른 글

[Spring] 파일 업로드 null 파일(?) 생성  (0) 2017.11.09

AWS EC2 서버 구축(Ubuntu)


최근 클라우딩 서비스가 인기를 많이 끌고 있습니다.


Amazon사의 AWS 외에도 Microsoft사의 Azure, 

Google사의 google Colud Platform도 인기를 끌고있습니다.


시장 점유율 면에서 AWS가 가장 높기때문에 가장먼저 구축 해 보게되었습니다.



회원가입 부분은 생략하였습니다.

회원가입 시 국외 결제가 가능한 신용/체크카드 등록이 필요합니다. 

계좌 확인을 위해 1$가 결제됩니다.

(결제 확인 후 취소된다고 합니다.)

먼저, EC2는 하드웨어 투자 없이, 빠르게 구축이 가능하다는 장점때문에 선정하게 되었습니다.


1. EC2 인스턴스 시작

EC2 대시보드에서 인스턴스 시작 버튼을 눌러줍니다.


2. AMI(Amazon Machine Image) 선택

상단 검색 탭에 검색을 하거나, 운영체제를 직접 선택해서 

이미지를 선택할 수 있습니다.

저는 ubuntu LTS 16.04 버전을 선택했습니다.


3. 인스턴스 유형 선택

스펙에 따라서 비용이 달라집니다. 저는 프리티어를 선택 했습니다.


4. 인스턴스 검토

지정한 인스턴스에 대해 검토하는 화면입니다.

인스턴스 세부정보 편집을 눌러보면 세부사항을 확인이 가능합니다.



5. 키페어 생성

서버 접속 시 필요한 키를 생성하는 화면입니다.

키페어 이름을 입력하고 키 페어 다운로드를 진행한 후 인스턴스 시작을 눌러줍니다.

(*.pem 파일이 생성 되는데 Putty 접속을 위해서는 *.ppk 파일로 변환이 필요합니다.)


6. 구축완료

키페어 생성이 끝나면 구축이 완료 됩니다.


7. 인스턴스 화면

현재 구동중인 서버 상태와 IP정보 등 서버 정보를 확인할 수 있습니다.





+ Recent posts