(Study 6) Special divide and conquer strategy algorithm --BFPTR

Leads problem: given a collection of N, wherein the k-th smaller number obtained, the first K of a small element refers to an element of K L after the collection of elements in ascending order good.

1: the inertia of thinking is the number of each set are sorted, and then find the index of the element k, the best case is to be O (nlogn)

2: BFPTR algorithm, even in a worst case, it is possible to achieve O (n) algorithm by the learning algorithm, it is intuitive feel, the algorithm first set of numbers divided in groups of 5, and then find the median of each group, the median into a set, and then find the median of the set of m, then the array are divided according to the median, the discharge is smaller than m to the left than to the right place m large, and the observation position m k of the corresponding recursive relationship and, in the quick sort algorithm previously learned, in fact, the algorithm changes the hub (Pivot) selection method, and can significantly improve the efficiency of the algorithm

Personal point of understanding:

The elements are divided . 5 in groups, ( doing so make more rational the subsequent division, a study by five out of mathematicians ) on each sort, then find the median median m divided after when most of the collection has been in an orderly state, then take a quick sort of thinking, the collection is divided, that is, to modify the main unit selection rule quick sort, the median median of the set as a principal component, the worst case the time complexity is also O (n)

Pseudo-code (purely personal understanding, hope to get criticism):

. 1 : the Find () { // find a set of N k-th smaller number 
      FindMid (); // a set of N is divided into groups of five, a total of n / 5 groups, each group for insert sequencing, to identify each median, and included in set M.
    // find the median Mid M in 
      FindIndex (); // set N found in the index Mid
       // to Mid bounded into the small Mid Mid N than the left, into the larger than Mid Mid the right, and after recording divided Mid subscripts
 // If Mid subscript <k, then looking at the right set Mid
 // If Mid subscript> k, then set the left looking Mid
 // if the Mid index = k, find the small numbers of K 
}

Code (reference to some bloggers)

//
//  main.cpp
//  作业6
//
//  Created by yizhihenpidehou on 2020/3/31.
//  Copyright © 2020 yizhihenpidehou. All rights reserved.
//
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxen=100;
void InsertSort(int n[],int low,int high){ //插入排序
    int i,j;
    for(i=low+1;i<=high;i++){
        j=i-1;
        int tmp=n[i];
        while(j>=low&&tmp<n[j]){
            n[j+1]=n[j];
            j--;
        }
        n[j+1]=tmp;
    }
}
int FindMid(int n[],int low,int high){ //找出中位数
    if(low==high) return n[low];
    int i,k;
    for(i=low;i+4<=high;i+=5){
        InsertSort(n, i, i+4);
        k=i-low;
        swap(n[low+k/5],n[i+2]);
    }
    int cnt=high-i+1;
    if(cnt>0){
        InsertSort(n, i, high);
        k=i-low;
        swap(n[low+k/5],n[i+cnt/2]);
    }
    k=k/5;
    if(k==0) return n[low];
    returnFindMid (n-, Low, Low + K); 
} 
int FindMidIndex ( int n-[], int Low, int High, int MIDD) { // find the median subscript 
    for ( int I = Low; I <= High ; I ++ ) {
         IF (n-[I] == MIDD) {
             return I; 
        } 
    } 
    return - . 1 ; 
} 
int the Partition ( int n-[], int Low, int High, int index) { // according to the determined the median of the median position to be divided, to obtain division 
    if(low<=high){
        int i=low,j=high;
        swap(n[index],n[low]);
        int tmp=n[low];
        while(i!=j){
            while(i<j&&n[j]>=tmp){
                j--;}
            n[i]=n[j];
            while(i<j&&n[i]<=tmp){
                i++;}
            n[j]=n[i];
        }
        n[i]=tmp;
        return i;
    }
        return -1;
}
int BFPTR(int n[],int low,int high,int k){
    int midd=FindMid(n,low,high);
    int indexx=FindMidIndex(n,low,high,midd);
    int newIndex=Partition(n,low,high,indexx);
    int rank=newIndex-low+1;
    if(rank==k) return newIndex;
    else if(rank>k) return BFPTR(n,low,newIndex-1,k);
    return BFPTR(n,newIndex+1,high,k-rank);
}
int main(int argc, const char * argv[]) {
    int num[maxen]={-1,12,1,8,10,6,2,5,9,11,3,4,7};
    int k;
    scanf("%d",&k);
    int low=1;
    int high=12;
    int index=BFPTR(num,low,high,k);
    printf("%d\n",num[index]);
    for(int i=low;i<high;i++){
        printf("%d ",num[i]);
    }
    printf("\n");
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/pipihoudewo/p/12629480.html