목록개발 (29)
넘치게 채우기
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/mbNqj/btrSwR4wIDv/udEJrTluNkFktgjxy2AsTK/img.png)
이진 탐색 트리? 이진 탐색 트리는 다음과 같은 조건이 있다: 같은 key값을 가지는 노드는 없다. 루트노드의 왼쪽 서브트리는 루트노드보다 작은 값들만 있어야 한다. 루트노드의 오른쪽 서브트리는 루트노드보다 큰 값들만 있어야 한다. 루트노드의 서브트리들 모두 이진 탐색 트리여야 한다. 이 조건들로, 이진 탐색 트리를 순회할 때 에는 보통 중위 순회를 이용한다. 이진 탐색 트리에는 세 가지 연산이 있다. 탐색(Search) 삽입(Insert) 삭제(Delete) 탐색 만약, 루트와 같은 값을 가진다면, 탐색을 멈춘다. 루트가 없는 경우 역시 탐색을 멈춘다. 만약, 루트보다 작은 값을 가진다면 왼쪽 서브트리에서, 더 큰 값을 가지면 오른쪽 서브트리에서 재귀한다. 구현 def _search(self, root..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/mEHsn/btrQfDfYKCp/l2uN73fFREfCucLOO6dvqK/img.png)
해시 테이블(Hash Table)은 해시 함수를 통해서 얻은 인덱스에 key 와 value값을 저장하는 자료 구조이다. 해시 함수는 같은 key값을 받으면 같은 인덱스값으로 반환시킨다. 해시 함수 해싱을 하는 해시 함수에는 다음과 같은 것들이 있다: 1. Division Method: 가장 쉽고 간단한 방법이다. key값을 해시 테이블의 크기로 나눈 나머지를 인덱스로 정하는 것이다. h(k) = k mod m (k = key, m = size of hash table) m값은 소수이고, 2의 제곱수와 먼 값을 사용해야 효율적이라고 한다. 2. Multiplication Method: key값과 A(0 < A < 1)의 곱의 소수 부분에 테이블의 크기 m을 곱한 값의 정수값을 인덱스로 한다. h(k) = ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bopI4q/btrPGP8oxFU/7oNdPw2c4wqGtnJg3W5A5K/img.png)
덱 덱(deque)는 double - ended - queue의 줄임말로, 앞뒤로 빼고, 넣는 것이 가능한 자료구조이다. 큐와 스택을 합친 자료구조라고 볼 수도 있다. 파이썬에서는 collections 라는 모듈에서 쉽게 사용할 수 있다. 리스트와 비슷해보이는 연산들이 있지만, 들여다보면 차이가 존재한다. 리스트는 맨 앞 데이터를 빼면, 뒤에 있는 데이터들이 다 앞으로 당겨져서 시간복잡도가 O(n)이 된다. 덱은 이중 연결리스트 기반으로 구현되어, 맨 앞 데이터를 빼더라도 시간복잡도가 O(1)이다. 덱의 연산 appendleft(): 앞쪽으로 데이터 enqueue popleft(): 앞쪽에서 데이터 dequeue append(data): 뒤쪽으로 데이터 enqueue pop(): 뒤쪽에서 데이터 dequ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cQgtwy/btrPvjIMtws/iTofYuzsllQfmR1c8sWCyk/img.png)
지난 2-2 글에서, 내가 구현한 배열을 이용한 큐는, 엄밀히 따지면 파이썬의 리스트를 이용한 것이다. '배열'이랑 구현한 것과 다른 점은, 큐의 크기를 정하지 않는다.(append하면 뒤에 새 칸을 만들고, pop하면, 칸이 줄어든다) pop 했을 때, 뒤 데이터들이 빈 자리를 채우러 앞으로 당겨진다. 그래서, '배열스러운' 큐를 다시 구현해보았다. 큐 - '배열'을 이용한 구현(Python) class queue(): #큐 선언 def __init__(self, size): self.size = size self.arr = [None] * self.size self.first = 0 self.last = 0 def isEmpty(self): #큐가 비어있는지 확인 if self.first >= sel..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bSq7eW/btrOyhS0rSK/8NsDj1rj4j22eXyPXjsSkk/img.png)
큐(Queue) 큐 자료구조는 우리가 평소에 줄을 서듯, 먼저 들어온 사람이 먼저 나가는, 선입선출(先入先出, First in First out)의 형식을 따른다. 큐의 연산 큐의 연산은 다음 5가지가 있다: isEmpty(): 큐가 비어있는지를 판단한다. True 또는 False값으로 반환된다. enqueue(data): 큐에 값을 입력시킨다. dequeue(): 큐의 제일 먼저온 값을 내보낸다. rear(): 큐의 맨 뒤에 있는 값을 반환한다. front(): 큐의 제일 반저온 값을 반환한다(큐에서 pop하지는 않는다) 큐의 구현 - 배열을 이용한 구현(Python) class queue(): #큐 선언 def __init__(self): self.arr = [] def isEmpty(self): #..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bgpA7i/btrNYd5phZz/WYLqkm5hk51LYeIn9knBxk/img.png)
스택(Stack) 스택 자료구조는 탄창에 총알을 넣고 빼듯, 먼저 넣은 데이터를 늦게 꺼내는 선입후출(先入後出, FILO(First in Last out)), 후입선출(後入先出, LIFO(Last in First Out))을 따른다. 스택의 연산 스택의 연산은 다음 4가지가 있다: isEmpty() : 스택이 비어있는지를 판단한다. push(data) : 스택의 맨 위에 데이터를 쌓는다 pop() : 스택의 맨 위 데이터를 스택에서 뺀다. top() : 스택의 맨 위의 값을 확인한다. 스택의 구현 - 배열을 이용한 구현(Python) class stack(): #스택 선언 def __init__(self): self.arr = [] def _len_(self): return len(self.arr) de..
연결 리스트(Python) - 전체 class Node(): #노드 선언 def __init__(self, data, next = None): self.data = data self.next = next class SimplyLinkedList(): def __init__(self): self.head = None def link(self, node, next): #노드 연결 node.next = next def getTail(self): #꼬리 노드 불러오기 currentNode = self.head while currentNode.next: currentNode = currentNode.next return currentNode def getIndex(self, data): #data의 인덱스 반환 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/lweAy/btrLyXReOrl/1kKKwh0ZqsrVGcokOsJknk/img.png)
이중 연결 리스트 이중 연결 리스트는 기존의 연결리스트와는 달리, 쌍방향으로 연결이 되어있다. 이미 한 노드를 지나쳐도, 돌아갈 수 있다. 장점 찾아야 하는 값이 tail쪽에 가까울 때, head부터 시작해서 탐색하는 번거로움 등을 없앨 수 있다. 위치를 모르는 상태에서 값을 찾을 때에도, 앞에서 절반, 뒤 끝에서 절반씩 탐색하면 훨씬 효율적이다. 단점 변수를 3개 사용한다.(이전 메모리주소, 내 엘리먼트, 다음 메모리주소) 이 과정에서 메모리를 더 사용하게된다. 구현이 복잡해진다. 그러나, 이런 단점들을 두고도, 얻게 되는 것이 많아서, 실제 연결리스트를 사용할 때, 이중 연결리스트를 많이 사용한다. 노드의 추가 노드 a↔b↔d에서 b↔d 사이에 c를 연결하고 싶으면, c의 다음 노드로 d를 연결해주고..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/LuATl/btrLj8Md6TM/WrIgttQv8JNEbQzB1THxRk/img.png)
연결 리스트는 순차 리스트와는 다르게, 리스트의 노드(요소)값의 메모리주소가 순차적이지 않다. 대신, 노드에 자신의 값과, 다음 노드의 메모리주소를 저장한다. 시작하는 노드를 머리(head)라고 하고, 맨 끝을 꼬리(tail)이라고 한다. 노드에서 다음 노드로 향하는 주소값을 포인터((Pointer)라고 한다. tail노드에서 가지고 있는 포인터값은 none 또는 null이라 한다. 접근 [2]에 있는 값을 보려면, 머리부터 다음 노드를 하나하나 찾아가야한다.(순차적으로 탐색해야한다) 시간복잡도는 O(N)이다. 삽입 A - B - C로 연결되어있는 연결 리스트 중 B-C 사이에 D 노드를 삽입하고 싶으면, B의 포인터를 D의 메모리주소, D의 포인터를 C의 메모리주소로 바꿔주면된다. 이때, 바꾸는 것의 ..