[데이터 구조] 요소를 찾는 몇 가지 일반적인 알고리즘 I - 선형 검색, 이진 검색

        이 글은 총 1310 단어로 구성되어 있으며, 예상 읽는 시간은 5분입니다.

목차

찾다

방법 1: 선형 검색

방법 2: 이진 검색


찾다

        이제 정렬된 배열이 있다고 가정합니다. 아래를 참조하세요. 현재 작업은 배열에 요소가 존재하는지 확인하는 것입니다.

/img/posts/skip-list/1simplearray.png

        이 배열에서 값이 57인 요소를 찾아야 합니다.

방법 1: 선형 검색

        이름에서 알 수 있듯이 선형 검색에서는 목록을 처음부터 끝까지 탐색하고 각 항목의 값이 원하는 값인지 비교해야 합니다. 일치하는 값을 찾으면 순회가 종료됩니다.

        값 57을 찾으세요.

        현재 찾고 있는 값보다 큰 값이 발견되면 검색이 종료될 수 있습니다(이후의 값은 찾고 있는 값보다 더 커지기 때문입니다).

        예를 들어, 값 35를 찾으려면

이것이 좋은 접근 방식입니까?

        이 솔루션이 가능합니다. 그러나 좀 더 주의를 기울이면 배열의 순서 속성을 최대한 활용하지 못한다는 것을 알 수 있습니다. 최악의 경우, 이 알고리즘의 시간 복잡도는 O(N)이 됩니다. 찾고 있는 요소가 더 이상 배열에 없으면 찾고 있는 값을 배열의 모든 요소와 비교해야 합니다. .

방법을 더 잘 설계할 수 있나요?

        물론 이진 검색을 사용해 보세요.

방법 2: 이진 검색

        이진 검색의 개념은 간단합니다. 당신이 일반적으로 영어 사전에서 단어를 어떻게 찾는지 생각해 보세요. 예를 들어, "quirky"라는 단어를 사전에서 찾으려면 사전이 이미 각 페이지를 배열해 두었기 때문에 해당 단어를 찾기 위해 사전의 첫 페이지에서 마지막 페이지까지 넘길 필요가 없습니다. 단어를 알파벳 순서로 정렬했습니다. 문자 q 앞뒤의 페이지 번호를 빠르게 건너뛸 수 있습니다.

        예제로 돌아가서 먼저 배열 중앙의 값 48을 살펴보고 이 값이 목표 값과 일치하면 검색을 직접 종료할 수 있습니다.

        하지만 값 48을 찾고 있지 않다면 어떻게 될까요? 그런 다음 중간에 있는 값을 사용하여 목표 값과 비교하겠습니다. 목표값이 이보다 작다면 이보다 작은 값을 찾아야 합니다. 즉, 48부터 시작하여 오른쪽 값을 고려하지 않고 왼쪽으로 검색해야 합니다.

        값 33을 찾으세요.

        이진 검색을 사용하면 검색 순서를 단축하고 비교할 값의 수를 절반으로 줄일 수 있습니다. 또한, 이 과정을 계속해서 반복할 수도 있는데, 즉 '중간값'을 지속적으로 선택하여 목표값과 비교하여 결과가 일치하는지 판단하고 일치하지 않으면 왼쪽으로 검색할지 오른쪽으로 검색할지 계속해서 판단하는 것이다. , 검색할 시퀀스를 지속적으로 좁히고 쿼리 수를 줄일 수 있습니다.

        현재의 시간복잡도는 얼마인가?

        알고리즘의 시간 복잡도는 비교 횟수에 따라 결정됩니다. 이 알고리즘을 이해했다면 이 알고리즘의 시간복잡도는 임을 알아야 하며 O(log_2n), 구체적인 도출식은  빅오 - 어떤 요소들이 시간복잡도에 영향을 미칠까요?를 참조하시기 바랍니다.

        이 알고리즘은 배열의 순서 특성을 최대한 활용합니다. 이 알고리즘은 많은 수의 값이 배열에 순차적으로 저장될 때 성능을 최대한 활용할 수 있습니다.

그렇다면 이것이 완벽한 솔루션일까요?

        분명히 이 방법은 검색할 때 실제로 노동력을 매우 절약해 줍니다. 하지만 요소를 삽입하거나 삭제하려는 경우 순차 배열은 이러한 상황에 적합하지 않습니다.

        예를 들어:

/img/posts/skip-list/8arrayinsertion.png

/img/posts/skip-list/9arraydeletion.png

        상상할 수 있듯이 배열 오른쪽에 추가 공간이 있는 경우 삽입 및 삭제 작업이 유용하지만, 그렇지 않으면 삽입할 때마다 동적 메모리 할당을 호출하고 전체 배열을 새로 할당된 배열에 복사해야 합니다. Python의 List 데이터 구조는 비슷한 방식으로 List를 할당하여 향후 확장을 위해 시퀀스 끝에 용량을 남겨 둡니다. 목록의 공간이 부족하면 Python은 더 큰 새 목록을 할당하고 이전 목록의 모든 값을 새 목록에 복사한 다음 이전 목록을 삭제합니다. (이것이 Python 목록에 삽입하는 것이 O(1) 시간 복잡도인 이유입니다 .)

삽입 및 삭제 중에 더 나은 성능을 발휘하는 데이터 구조를 구성하는 더 좋은 방법이 있습니까?

        물론, 그것은 연결리스트입니다!

       

번역 중…

추천

출처blog.csdn.net/weixin_42839065/article/details/131871698