C Language [핵심정리] - 44
1. 퀵 정렬 함수 사용하기
버블 정렬 함수는 직접 구현했습니다만, 퀵 정렬의 경우에는 해당 정렬을 사용하기 위해 퀵 정렬 함수를 사용합니다. 퀵 정렬 함수에는 정렬할 배열 또는 메모리의 주소, 요소 개수, 요소 크기, 비교 함수를 넣어줍니다. (<stdlib.h>파일에 선언되어 있습니다.)
qsort 함수를 사용하기전 비교 함수를 만들어야 합니다.
오름차순일 경우 1) one < two 일 때는 - 1을 반환 2) one = two 일 때는 0을 반환 3) one > two 일 때는 1을 반환
내림차순일 경우 1) one < two 일 때는 1을 반환 2) one = two 일 때는 0을 반환 3) one > two 일 때는 - 1을 반환
이건 qsort 함수를 사용하기 위한 약속입니다.
비교함수를 만들 때는 반드시 int 형 반환 값과 const void 포인터 매개변수(정렬 할 배열의 자료형이 제각각이므로 void 포인터로 받습니다.) 2개가 있어야 합니다. 다만, const void 포인터로는 값을 비교할 수 없기에 사용하려는 자료형으로 변환한 후 역참조를 통해 값을 가져옵니다. + 해당 함수 내 포인터는 const 키워드를 사용했기 때문에 포인터가 가리키는 값은 상수 입니다. 따라서 함수 내에서 임의로 값을 수정하면 안되요.
이를 더 간단하게 다음과 같이 표현할 수 있습니다.
값을 반환할 때는 반드시 -1, 0, 1 일 필요는 없고, 값이 같을 때는 0 크거나 작을 때는 양수 또는 음수 값을 반환하면 됩니다.
+ 보통 변하지 않는 상수 값을 정의하기 위해서 const 키워드를 사용하는데요. 일반적으로 매개변수에 const 키워드를 붙인 경우는 해당 매개변수가 포인터일 때 입니다. 사용한 이유는 특정 함수에 전달되는 포인터의 내용이 훼손되는 걸 방지하기 위해서입니다. 다른 함수에 포인터가 전달될 경우 call-by-value가 아닌 call-by-reference 형태로 전달되므로 다른 함수에서 포인터 값을 임의로 수정하려는 목적이 아니라면 항상 const 를 사용해야 합니다.
Call by Value 와 Call by Reference의 차이점
함수 호출 방법에는 크게 두 가지가 있습니다. 1) Call by value(값에 의한 호출) 2) Call by reference(참조에 의한 호출)
Call by value 는 인자로 받은 값을 복사하여 처리합니다. 그에 반해 call by reference 는 인자로 받은 값의 주소를 참조하여 직접적으로 값에 영향을 줍니다. 간단히 설명하자면 값을 복사하냐 아니면 값을 참조 후 직접 처리하냐의 차이입니다.
1) Call by value(값에 의한 호출)
장점 : 복사하여 처리하기 때문에 안전합니다. (= 값이 보존됩니다.)
단점 : 복사를 하기 때문에 메모리 사용량이 증가합니다.
2) Call by reference(참조에 의한 호출)
장점 : 복사하여 직접 참조를 하기에 빠릅니다.
단점 : 직접 참조를 하기에 원래의 값이 변형됩니다. (위험이 존재함)
2. 연결 리스트 구현하기
연결 리스트는 데이터가 담긴 노드(메모리 공간)를 일렬로 연결했다고 해서 연결 리스트라고 불리며 특징은 다음과 같습니다.
1) 리스트의 중간 지점에 노드를 간단하게 추가하거나 삭제할 수 있습니다.
2) 특정 노드를 찾으려면 모두 검색해야 합니다. (최악의 경우)
3) 크기가 고정되어 있지 않습니다.
다른 노드를 가리키는 포인터가 하나씩만 있는 리스트를 단일 연결 리스트(singly linked list)라고 합니다.단일 연결 리스트에서 노드의 종류는 크게 두가지가 있으며, 역할은 다음과 같습니다.
이 두 종류의 노드는 역할만 다를 뿐 모두 NODE 구조체를 사용합니다.
이제 연결 리스트를 만들어봅시다.
먼저 연결 리스트의 구조체를 정의합니다. 연결 리스트는 노드들의 집합이므로 실제로는 노드의 구조체만 정의하면 되요.
next 에는 NODE 구조체로 만든 다른 노드의 메모리 주소를 저장합니다. 즉, 자기 자신이 아닌 다른 노드의 메모리 주소를 저장합니다.
연결 리스트에 노드를 추가하는 규칙은 다음과 같습니다.
1) 노드에 메모리 할당
2) next 멤버에 다음 노드의 메모리 주소 저장
3) data 멤버에 데이터 저장
4) 마지막 노드라면 next 멤버에 NULL 저장