데이터 구조 자바 에디션 정렬 (1)

오랜만이다~ 

콘텐츠

1. 개념

1.1 안정성

2. 7대 랭킹

2.1 삽입 정렬

2.1.1 직접 삽입 정렬 - 원리

2.1.2 성능 분석

2.1.3 반접기 삽입 정렬(이해)

2.2 힐 정렬

2.2.1 원칙

2.2.2 성능 분석

2.3 선택 정렬

2.3.1 원칙

2.3.2 성능 분석

2.4 힙 정렬

2.4.1 원칙

2.4.2 성능 분석

2.5 버블 정렬

2.5.1 원칙

2.5.2 성능 분석

2.6 빠른 정렬(중요)

2.6.1 원칙

2.6.2 성능 분석


1. 개념

정렬은 하나 또는 일부 키워드의 크기에 따라 일련의 레코드를 오름차순 또는 내림차순으로 정렬하는 작업입니다. 일반적인 컨텍스트에서 정렬이 언급되면 일반적으로 오름차순을 나타냅니다. 일반적인 의미의 정렬은 제자리 정렬을 의미합니다.

1.1 안정성

두 개의 동일한 데이터, 정렬 알고리즘이 정렬 후 상대 위치가 변경되지 않도록 할 수 있는 경우 알고리즘을 안정적인 정렬 알고리즘이라고 합니다. (즉, 동일한 요소의 상대 위치가 변경되기 전 요소의 순서와 상대 위치 변경 후 요소의 순서가 일관되어야 함)
불안정한 정렬로 구현할 수 있는 안정적인 정렬
그러나 본질적으로 불안정한 정렬은 안정적인 정렬이 될 수 없습니다.

아래 그림과 같이 :

2. 7대 랭킹

2.1 삽입 정렬

2.1.1 직접 삽입 정렬 - 원리

원칙:
전체 간격은 정렬된 간격, 정렬되지 않은 간격으로 나뉩니다.
매번 순서가 없는 구간의 첫 번째 요소를 선택하고 삽입할 정렬된 간격에서 적절한 위치를 선택합니다.
문제 해결 아이디어:
① 임시 저장 지점 tmp를 찾아 각 정렬되지 않은 간격에 아래 첨자 i가 표시된 첫 번째 요소를 넣습니다.
② 다른 변수 j를 사용하여 tmp가 나타내는 요소의 크기를 판단합니다.
③ 종료 루프 조건을 j<0이 될 때까지 설정
코드 쇼는 아래와 같습니다.
  public static void insertSort(int[] array) {
        for (int i = 1; i < array.length; i++) {
            int tmp = array[i];
            int j = i-1;
            for (; j >= 0 ; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                }else {
                    //array[j+1] = tmp;  只要j回退的时候,遇到了 比tmp小的元素就结束这次的比较
                    break;
                }
            }
            //j回退到了 小于0 的地方
            array[j+1] = tmp;
        }

    }

2.1.2 성능 분석

최대 평균 가장 나쁜
시간 복잡도 켜짐) 오(N²) 오(N²)
공간 복잡도 오(1) 오(1) 오(1)
안정 안정화 안정화 안정화

2.1.3 반접기 삽입 정렬(이해)

원칙:

반 검색의 아이디어를 사용하여 정렬

문제 해결 아이디어:

① 각 루프에 대해 왼쪽 값을 0으로, 오른쪽 값을 i로 설정합니다.

② 둘의 중간에 좌표가 나타내는 값과 판단할 값의 관계를 판단하기 위해 타협

③array[mid]<판정값이면 left=mid+1, 그렇지 않으면 array[mid]>판정값 right=mid (배열[mid]보다 큰 값을 찾아 교환하기 위함)

코드 쇼는 아래와 같습니다.

public static void bsInsertSort(int[] array) {
 for (int i = 1; i < array.length; i++) {
 int v = array[i];
 int left = 0;
 int right = i;
 // [left, right)
// 需要考虑稳定性
while (left < right) {
int m = (left + right) / 2;
if (v > array[m]) {
left = m + 1;
 } else {
right = m-1;
 }
 }
// 搬移
for (int j = i; j > left; j--) {
array[j] = array[j - 1];
 }
        array[left]=v;
    }
}

2.2 힐 정렬

2.2.1 원칙

원칙:
힐 소팅 방법은 수축 증분 방법으로도 알려져 있습니다. 힐 정렬 방법의 기본 아이디어는 먼저 정수를 선택하고 정렬할 파일의 모든 레코드를 그룹으로 나누고 정렬할 파일의 모든 레코드를 그룹으로 나누는 것입니다.
거리가 인 레코드를 동일한 그룹으로 그룹화하고 각 그룹 내의 레코드를 정렬합니다. 그런 다음 위의 그룹화 및 정렬 작업을 반복하십시오. =1 에 도달하면 모든 레코드가 통합 그룹 내에서 정렬됩니다.
1. 힐 정렬은 직접 삽입 정렬의 최적화입니다.
2. gap > 1 일 사전 정렬되며 목적은 배열을 순서에 더 가깝게 만드는 것입니다. gap == 1이면 배열이 이미 정렬에 가깝기 때문에 빠릅니다. 이러한 방식으로 최적화의 전반적인 효과를 얻을 수 있습니다.

 문제 해결 아이디어: (본체는 그것을 여러 부분으로 나누고 각 부분은 자체 재귀를 수행합니다)

① 증분값을 구하는 문제는 특정 문제를 풀 때 소수인지 확인하기가 쉽지 않아 종종 gap/=2의 방식으로 푸는 경우가 많다.

②실제로는 삽입정렬이지만 직접정렬에서 j=i-1의 첨자값을 j=i-gap으로 대체한다.

코드 쇼는 아래와 같습니다.

    public static void shell(int[] array,int gap) {
        for (int i = gap; i < array.length; i++ ) {
            int tmp = array[i];
            int j = i-gap;
            for (; j >= 0 ; j -= gap) {
                if(array[j] > tmp) {
                    array[j+gap] = array[j];
                }else {
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }
  public static void shellSort(int[] array) {
        int gap = array.length;
        while (gap > 1) {
            shell(array,gap);
            gap /= 2;
        }
        shell(array,1);//保证最后是1组
    }

2.2.2 성능 분석

유형 해당 매개변수
시간 복잡도 O(N의 1.3제곱 ~ N의 1.5제곱)
공간 복잡도 오(1)
안정 불안정한

2.3 선택 정렬

2.3.1 원칙

원칙:
매번 무순 간격에서 가장 큰(또는 가장 작은) 요소를 선택하고 정렬할 데이터 요소가 모두 소진될 때까지 무순 간격의 끝(또는 앞)에 저장합니다.
문제 해결 아이디어:
① 사실 쌍의 크기를 비교하여 교환하고, 최종적으로는 순서열이 되는 과정이다.
②최적화된 코드는 실제로 매번 최소값의 첨자를 직접 찾아 i값의 첨자와 직접 교환
코드 분석:
 public static void swap(int a,int b){
            int tmp=a;
            a=b;
            b=tmp;
        }
        //选择排序:不稳定的排序
        public static void selectSort(int []array){
            for(int i=0;i<array.length;i++){
                for(int j=i+1;j<array.length;j++){
                    if(array[i]>array[j]){
                        swap(array[i],array[j]);
                    }
                }
            }
        }//以下为优化好后的代码,此处的优化,指的是交换次数的变化,而时间复杂度并为更改
        public static void selectSort1(int []array){
            for(int i=0;i<array.length;i++){
            //将最小值的下标记录下来,而i在交换中只需要与这个最小值进行比较
            int minSize=i;
            for(int j=i+1;j<array.length;j++){
                if(array[j]<array[minSize]){
                    minSize=j;
                }
            }swap(array[i],array[minSize]);
        }

2.3.2 성능 분석

유형 해당 매개변수
시간 복잡도 오(N²)
공간 복잡도 오(1)
안정 불안정한

2.4 힙 정렬(힙에 대한 이전 섹션에서 자세히 설명)

2.4.1 원칙

원칙:
기본 원칙도 선택 정렬이지만 순회를 사용하여 정렬되지 않은 간격의 가장 큰 수를 찾는 대신 힙을 사용하여 정렬되지 않은 간격의 가장 큰 수를 선택합니다.
문제 해결 아이디어:
① 힙 빌드(큰 루트 힙 빌드)
② 아래로 스왑하여 조정
코드 쇼는 아래와 같습니다.
 public static void heapSort(int []array){
        createHeap(array);
        int end=array.length-1;
        while(end>0){
            swap(array[0],array[end]);
            shiftDown(array,0,end);
            end--;
        }
    }
    public static void createHeap(int[]array){
        for(int parent=(array.length-1-1)/2;parent>=0;parent--){
            shiftDown(array,parent,array.length);
        }
    }//向下调整
    public static void shiftDown(int[]array,int parent,int len){
        int child=2*parent+1;//左孩子下标
        while(child<len){
            if(child+1<len && array[child]<array[child+1]){
                child++;//保证下标为较大值的下标
            }
            if(array[child]>array[parent]){
                swap(array[child],array[parent]);
                parent=child;
                child=2*parent+1;
            }else{
                break;
            }
        }
    }

2.4.2 성능 분석

유형 해당 매개변수
시간 복잡도 O(N * 로그 N)
공간 복잡도 오(1)
안정 불안정한

2.5 버블 정렬

2.5.1 원칙

원칙:
무순구간에서는 인접한 수의 비교를 통해 무순구간이 끝날 때까지 가장 큰 수를 버블링하며, 이 과정은 배열이 전체적으로 정렬될 때까지 계속된다.
문제 해결 아이디어:
① j를 사용하여 각 이동의 크기를 비교하고 가장 큰 것은 각 이동이 끝날 때 바닥으로 가라앉습니다.
②i를 사용하여 패스 수를 나타냅니다.
③ 최적화된 코드에 flg=false를 추가하여 교환이 없도록 하고 루프에서 직접 점프하여 시간을 절약합니다.
코드 분석:
  //冒泡排序(稳定的排序。时间复杂度为n²,在排好序的情况下时间复杂度为n,空间复杂度为O(1)
    public static void bubblesort(int array[]){
        boolean flg=false;
        for (int i = 0; i < array.length-1; i++) {
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1]){
                    swap(array[j],array[j+1]);
                    flg=true;
                }
            } if(flg=false){
                break;
            }
        }
    }

2.5.2 성능 분석

유형 해당 매개변수
시간 복잡도 오(N²)
공간 복잡도 오(1)
안정 안정화

 2.6 빠른 정렬(중요)

2.6.1 원칙

원칙:
1. 범위에서 피벗 값 으로 정렬할 숫자를 선택합니다 .
2. 파티션: 정렬할 전체 구간을 순회하고, 기준 값보다 작은 값(같음을 포함할 수 있음)을 기준 값의 왼쪽에 놓고 기준 값보다 큰 값(같음을 포함할 수 있음)을 다음 위치에 넣습니다. 참조 값의 오른쪽;
3. 분할과 정복의 개념을 채택하고, 왼쪽과 오른쪽 셀을 같은 방식으로 처리합니다. 셀의 길이 == 1 , 즉 순서가 지정되었음을 의미하거나 셀의 길이 == 0이 될 때까지 , 이는 데이터가 없음을 의미합니다.
문제 해결 아이디어:
①기준점을 찾아 기준점을 구분선으로 하여 기준점 왼쪽의 값이 기준점보다 크면 오른쪽 빈 공간으로 전환하고 기준치보다 작으면 ++ 시작, 값이면 시작 벤치마크의 오른쪽이 벤치마크보다 작으면 왼쪽의 빈 위치로 전환합니다. end--;
②파트별로 재귀적
코드는 다음과 같습니다 1: (여기에 파기 방법이 있습니다)
  //快速排序
    public static void quickSort(int []array){
        quick(array,0,array.length-1);

    }
    public static void quick(int []array,int left,int right){
if(left>=right){
    return ;
}//找基准
        int pivot=patition(array,left,right);
//递归左边的
quick(array,left,pivot-1);
//递归右边的
quick(array,pivot+1,right);
    }
    public static int patition(int []array,int start,int end) {
        int tmp = array[start];
        while (start < end) {
            while (start < end && array[end] >= tmp) {
                end--;
            }//end下标遇到了小于tmp的值
            array[start] = array[end];
            while (start < end && array[start] <= tmp) {
                start++;
            }//start下标遇到了大于tmp的值
            array[end] = array[start];
        }//当start=end时
        array[start]=tmp;
        return start;
    }

문제 해결 아이디어 2:

① 벤치마크 찾기

②데이텀을 찾은 후 데이텀의 양쪽에 굴착공법의 단계를 동시에 수행 ②양쪽에서 모두 큰 것과 작은 것이 발견되면 위치를 직접 교환

코드 2: (호레법)

private static int partition(int[] array, int left, int right) { 
 int i = left; 
 int j = right; 
 int pivot = array[left]; 
 while (i < j) { 
 while (i < j && array[j] >= pivot) { 
 j--; 
 } 
 
 while (i < j && array[i] <= pivot) { 
 i++; 
 }
swap(array, i, j); 
 } 
 swap(array, i, left); 
 return i; 
}

2.6.2 성능 분석

유형 해당 매개변수
시간 복잡도 O(K*N*logn)~O(N^2)
공간 복잡도 O(로그N) ~ O(N)
안정 불안정한

 퀵 정렬 최적화에 대해, 그리고 나머지 병합 정렬은 다음 섹션에 나타납니다~~~

추천

출처blog.csdn.net/weixin_58850105/article/details/122968843