데이터 구조 : 공통 정렬 알고리즘 (3) : 이진 삽입 정렬
삽입 정렬 :
1. 아이디어 : 모든 삽입이 정렬 될 때까지 각 단계에서 정렬 할 레코드가 시퀀스 코드 크기에 따라 이전에 정렬 된 단어 시퀀스의 적절한 위치에 삽입됩니다.
2. 핵심 질문 : 이전에 정렬 된 순서에서 적절한 삽입 위치를 찾으십시오.
방법 : 에 직접 삽입 정렬 , 이진 삽입 정렬 , 셸 정렬
이진 삽입 정렬
1. 기본 아이디어 :
기본 개념 : 이분법 삽입 정렬의 아이디어는 적절한 삽입 위치를 찾는 방법이 다르다는 점을 제외하고는 직접 삽입과 동일합니다. 여기서는 이분법에 따라 적합한 위치를 찾아 비교 횟수를 줄일 수 있습니다.
이진 정렬이라고하는 이진 삽입 정렬은 i 번째 요소가 삽입 될 때 이전 0 ~ i-1 요소를 반으로 나누고 중간에있는 요소를 먼저 비교합니다. 더 작 으면 전반이 절반으로, 그렇지 않으면 절반이됩니다. 두 번째 절반은 left <right까지 반으로 접힌 다음 i 번째 요소의 첫 번째 위치와 대상 위치 사이의 모든 요소가 뒤로 이동되고 i 번째 요소가 대상 위치에 배치됩니다.
이진 검색의 개념에 따라 확인할 레코드는 정렬 된 목록과 정렬되지 않은 목록으로 구분되며, 정렬되지 않은 목록의 첫 번째 키가 정렬 된 목록의 중간에있는 레코드와 비교할 때마다 비교됩니다. 레코드보다 작 으면 다음 하위 테이블에 요소를 삽입하고, 레코드보다 크면 요소를 이전 하위 테이블에 삽입합니다. 모든 레코드가 테이블에 삽입 될 때까지 반복적으로 반복하십시오.
2. 예
이진 삽입 정렬로 배열 a [6] = {5,36,24,10,6,12} 정렬
이미지 출처 : https://www.cnblogs.com/zwtgyh/p/10631760.html
암호
#include<iostream>
using namespace std;
/*二分查找函数,返回插入下标*/
template <typename T>
int BinarySearch(T array[], int start, int end, T k)
{
while (start <= end)
{
int middle = (start + end) / 2;
int middleData = array[middle];
if (middleData > k)
{
end = middle - 1;
}
else
start = middle + 1;
}
return start;
}
//二叉查找插入排序
template <typename T>
void InsertSort(T array[], int length)
{
if (array == nullptr || length < 0)
return;
int i, j;
for (i = 1; i < length; i++)
{
if (array[i]<array[i - 1])
{
int temp = array[i];
int insertIndex = BinarySearch(array, 0, i, array[i]);//使用二分查找在有序序列中进行查找,获取插入下标
for (j = i - 1; j >= insertIndex; j--) //移动元素
{
array[j + 1] = array[j];
}
array[insertIndex] = temp; //插入元素
}
}
}
//主函数
int main() {
//int *a = Random();
int a[6] = { 5, 36, 24, 10, 6, 12 };
InsertSort(a, 6);
for (int i = 0; i < 6; i++)
{cout << a[i] << " ";}
cout << endl;
return 0;
}
3. 요약 :
1. 요약 : 최악의 경우 : 정렬 된 시퀀스의 시작 부분에 삽입 될 때마다 전체 정렬 된 시퀀스의 요소를 뒤로 이동해야하며 시간 복잡도는 O (n2)입니다.
2. 가장 좋은 경우 : 정렬 할 배열은 양의 순서이고 각 요소의 위치는 삽입 위치입니다 .. 이때 시간 복잡도는 비교 일뿐입니다. 3. 시간 복잡도는 O (log2n)입니다.
4. 평균 상황 : O (n2)
공간 복잡성 측면에서 이진 삽입도 제자리에서 정렬되며 공간 복잡성은 (O (1))입니다.