728x90

프로그래밍/자료구조 11

연결리스트_단일방향 연결리스트 구현

C를 통해 구현을 할 예정이다. 연결리스트의 특성에 맞게, 노드를 동적으로 생성하고, 그 노드들을 연결시켜주면서 연결리스트는 완성이 된다. C에서는 malloc함수와 Free함수를 활용하여 메모리에 동적할당한다. 일단 노드를 struct를 이용하여 구성한다. typedef struct _node { int data;// 데이터를 담을 공간 (int형) struct _node * next; // 다음 노드(구조체)를 가리킬 next라는 이름의 포인터이다. } Node; 이렇게 구성된 노드를 계속해서 이어주는 자료구조라고 보면 된다. 필요할때마다 Node를 하나씩 동적할당하여 이들을 연결하는 것이다. 동적 할당하는 코드는 아래와 같다. newNode = (Node*)malloc(sizeof(Node)); 역..

SHA-256 해쉬함수

해쉬테이블을 공부하다보니, SHA-256이라는 해쉬 알고리즘이 있어 한번 확인을 해보았다. 해쉬를 한다는 부분이 어떤것인지 파악하기에 도움이 된다. (임의의 길이를 갖는 데이터를 고정된 길이의 데이터로 변환) 키값을 만들때도 사용되지만 위변조 여부를 판별하고 무결성을 검증하는데에도 사용된다.(결국 같은뜻 인듯 하다.) SHA-256은 2의 256제곱만큼 경우의 수를 만들 수 있어서 붙어진 이름이라고 한다. 아래 사진을 보면 hashtest.txt의 파일내 내용에 스페이스바 하나만 추가했을 뿐인데 해쉬코드가 굉장히 많이 변경되는것을 볼 수 있었다.

테이블(Table)과 해쉬(Hash)

테이블(Table) 자료구조의 이해 - 원하는 바를 '단번에' 찾아내는 방식이다. - 테이블 자료구조의 탐색 연산은 O(1)의 시간복잡도를 보인다. "저장되는 데이터는 키(key)와 값(value)이 하나의 쌍을 이룬다." "키(key)가 존재하지 않는 '값'은 저장할 수 없다. 그리고 모든 키는 중복되지 않는다" 배열을 기반으로 하는 테이블 https://github.com/GTAEKI/DataStructure_Study/blob/main/HashTable/ArrayTable/UnderstandTable.cpp 배열을 기반으로 하는 테이블의 문제점은 "고유 번호의 범위가 배열의 인덱스 값으로 사용하기에 적당하지 않다" "고유번호의 범위를 수요할 수 있는 매우 큰 배열이 필요하다." 이 두가지 문제를 해..

[#ifndef ~ #endif] 헤더파일 중복방지를 위해 사용

전처리기 #ifndef와 #endif를 사용하게 되면 C언어에서 헤더파일이 중복으로 실행되는 경우를 방지할 수 있다. #ifndef의 기능이 #define 되어있지 않다면 내부 내용을 실행하겠다는 전처리기이기 때문이다. 따라서 #ifndef _STACK_H__ #define _STACK_H__ 내부 내용 #endif 이런 형태로 작성을 해주게되면 처음 헤더파일이 실행될때는 _STACK_H__가 정의되어있지 않기 떄문에 #define_STACK_H__가 실행되게 되며 _STACK_H__가 정의가 된다. 그렇게 내부내용이 실행되게된다. 그 다음으로 헤더파일이 중복실행될 경우에는 이미 _STACK_H__는 정의가 되어있기 때문에 #ifndef에 걸러져서 #endif 아래쪽 내용을 실행하게 되어있다. 따라서 헤..

연결리스트의 개념적인 이해

"배열은 메모리의 특성이 정적이어서 (길이의 변경이 불가능해서) 메모리의 길이를 변경하는것이 불가능하다." 그래서 등장한것이 '동적인 메모리 구성'이다. 아래는 연결리스트를 진짜 구현한 것이 아니라, 개념적인 이해를 위한 예제이다. 아래를 보면 Node 구조체를 만들고 그 구조체는 data와 다음 주소를 가리키는 next로 구성되어있음을 알 수 있다. 데이터 입력받는 과정: malloc을통해 동적으로 Node구조체를 생성해주고, 헤드랑 테일이 가리키게 한다. 입력을 받을때마다 tail의 next가 새로 할당받은 Node를 가리키가 만들고 tail을 Node로 변경해준다. 출력과정 : cur에 처음 head를 지정해 주고, cur -> next가 존재하면 하나씩 밀어가며 출력한다. 삭제과정 : delNod..

C언어, 재귀함수로 하노이타워 구현하기

하노이타워를 C언어로 공부하면서 재귀라는 부분을 실제 코딩을 하며 어떻게 떠올릴 수 있을지가 가장 재미있는 부분이라고 생각했다. 실제로 그냥 머리속에서 하노이타워를 어떻게 구현할지 고민할때는 해답이 떠오르지가 않았다. 분명히 반복되는 부분이 있을것같은데, 머리속에서 찾을 수가 없었다. 윤성우님께서 문제를 내주실때도 알고나면 너무 쉬울것이라고 고민해 보는 시간을 꼭 갖고 해답을 보면 좋을것같다고 하였는데. 아니나 다를까 듣자마자, 정말 탁 트이는 기분이 들었다. 이제는 하노이타워는 언제든지 구현할 수 있겠다는 생각이 드는데 아직도 프로그래밍을 하다가 재귀를 떠올릴 수 있을것 같다는 확신이 들지는 않는것 같다. 반복되는 부분이 있다면 고민 꼭 해보자 void Hanoitower(int num, char fr..

함수의 재귀적 호출

이번 강의의 목표는 하노이 타워를 이해하는것이다. 특징 1. 제일 첫번째로 호출된 함수가 제일 마지막으로 종료가 되는 특징을 갖고있다. 2. 재귀에서 탈출조건을 반드시 명시해야한다. 그렇지 않으면 무한 반복하게된다. > 요즘은 운영체제가 너무 좋아져 가상메모리를 잘 잡아줘서 뻗는데까지 오래걸릴테지만 그래도 뻗는다. 디자인 사례 가장 대표적인 사례로 수학에서 펙토리얼이 있다. 이진 탐색 알고리즘의 재귀 구현 int BSearchRecur(int ar[], int first, int last, int targer) { int mid; if(first > last) return -1; mid = (first + last) / 2; if(ar[mid] == targer) return mid; else if(ta..

이진탐색 알고리즘

이진탐색 알고리즘 - 순차 탐색 보다 훨씬 좋은 성능을 보인다. - 배열이 정렬되어 있어야 한다는 제약이 따른다. (당연하다. 절반씩 나누어 탐색을 나아가는 알고리즘이기때문에 정렬이 되어있어야 한다.) - 절반씩 나누어 탐색을 나아가는 알고리즘(대소비교를 통해 왼쪽 오른쪽을 찾아나간다.) 포인트는 last에 mid -1을 해주는것과 first에 mid +1을 해주는 것이다. first와 last가 역전될 때까지 탐색을 지속적으로 시켜주기위해서 반드시 필요한 부분이다. 이진 탐색 알고리즘 최악의 경우 시간 복잡도 구해보기 - 시간 복잡도 계산을 위한 핵심 연산은 == 연산자이다! => if(target == ar[mid]) 에서 ==이다. 왜냐하면 여기서 true를 반환하게되면 return mid를 실행하..

알고리즘의 성능 분석방법

핵심 1. 시간복잡도를 중심으로 최악의 경우를 판단하여 알고리즘의 성능을 분석한다. 2. 연산의 중심이 되는 연산자의 연산횟수를 계산해서 T(n)함수를 그래프로 나타낸다. 알고리즘을 평가하는 두가지 요소 - 시간복잡도(time complexity) -> 얼마나 빠른가? - 공간복잡도(space complexity) -> 얼마나 메모리를 적게 사용하는가? 두개중 시간 복잡도를 더 중요시 한다고 한다. 시간 복잡도의 평가방법 - 중심이 되는 특정 연산의 횟수를 세어서 평가를 한다. - 데이터 수에 대한 연산 횟수의 함수 T(n)을 구한다. -> 함수를 그려놓으면 그래프로 볼 수가 있게 된다. -> 데이터가 늘어남에 따라 연산횟수가 얼마나 늘어나는지가 정말 중요하기 때문에 T(n)을 구한다. 알고리즘의 수행 ..

빅-오 표기법(Big-Oh Notation)

핵심 핵심은 최고차항을 제외한 나머지는 무시하는것이다. 내용 T(n)이 다항식으로 표현될 경우 사례가 많아질수록 최고차항이 아닌 나머지 항들의 영향력은 작아진다. 따라서 최고차항을 제외한 나머지는 무시한다. 로그형과 상수형의경우 데이터가 많이 유입될 수록 연산 시간이 지수형과 달리 늘어나는 폭이 줄어들고 있으므로 요즘과 같은 빅데이터의 시대에서 좋은 알고리즘이다. 당연히 데이터가 늘어날 수록 시간도 배로 늘어나는 지수형 알고리즘은 절대 써서는 안되는 알고리즘이다.

728x90