八大排序之快速排序

2020-09-29  本文已影响0人  Source_Chang

核心思想:分治

第一种:挖坑法
C++:

// 挖坑法
int QuickSort::partitionV1(std::vector<int> &arrNumbers, int startIndex, int endIndex) {
    
    int key = arrNumbers[startIndex];
    int i = startIndex;
    int j = endIndex;
    while ( i < j ) {
        
        while ( i < j && arrNumbers[j] >= key ) {
            
            --j;
        }
        
        if ( i < j ) {
            
            arrNumbers[i] = arrNumbers[j];
        }
        
        while ( i < j && arrNumbers[i] <= key ) {
            
            ++i;
        }
        
        if ( i < j ) {
            
            arrNumbers[j] = arrNumbers[i];
        }
    }
    arrNumbers[i] = key;
    
    return i;
}


void QuickSort::sortV1(std::vector<int>& arrNumbers, int startIndex, int endIndex) {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    int index = partitionV1( arrNumbers, startIndex, endIndex );
    sortV1( arrNumbers, startIndex, index - 1 );
    sortV1( arrNumbers, index + 1, endIndex );
}


void QuickSort::sortV1(std::vector<int>& arrNumbers) {
    
    sortV1( arrNumbers, 0, arrNumbers.size() - 1 );
}

Objective-C:

// 挖坑法
+ (NSInteger)partitionV1:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
              startIndex:(NSInteger)startIndex
                endIndex:(NSInteger)endIndex {
    
    
    NSNumber *key = arrMNumbers[startIndex];
    NSInteger i = startIndex;
    NSInteger j = endIndex;
    while ( i < j ) {
        
        while ( i < j && arrMNumbers[j].integerValue >= key.integerValue ) {
            
            --j;
        }
        
        if ( i < j ) {
            
            arrMNumbers[i] = arrMNumbers[j];
        }
        
        while ( i < j && arrMNumbers[i].integerValue <= key.integerValue ) {
            
            ++i;
        }
        
        if ( i < j ) {
            
            arrMNumbers[j] = arrMNumbers[i];
        }
    }
    arrMNumbers[i] = key;
    
    return i;
}


+ (void)quickSortV1:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
         startIndex:(NSInteger)startIndex
           endIndex:(NSInteger)endIndex {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    NSInteger index = [self partitionV1:arrMNumbers
                             startIndex:startIndex
                               endIndex:endIndex];
    [self quickSortV1:arrMNumbers
           startIndex:startIndex
             endIndex:index - 1];
    [self quickSortV1:arrMNumbers
           startIndex:index + 1
             endIndex:endIndex];
}


+ (nullable NSArray<NSNumber *> *)quickSortV1:(nonnull NSArray<NSNumber *> *)arrNumbers {
    
    NSMutableArray<NSNumber *> *arrMNumbers = [arrNumbers mutableCopy];
    [self quickSortV1:arrMNumbers
           startIndex:0
             endIndex:arrMNumbers.count - 1];
    
    return [arrMNumbers copy];
}

第二种:指针交换法
C++:

// 指针交换法
int QuickSort::partitionV2(std::vector<int> &arrNumbers, int startIndex, int endIndex) {
    
    int i = startIndex;
    int j = endIndex;
    while ( i != j ) {
        
        while ( i < j && arrNumbers[j] >= arrNumbers[startIndex] ) {
            
            --j;
        }
        
        while ( i < j && arrNumbers[i] <= arrNumbers[startIndex] ) {
            
            ++i;
        }
        
        if ( i < j ) {
            
            // swap
            arrNumbers[i] = arrNumbers[i] ^ arrNumbers[j];
            arrNumbers[j] = arrNumbers[i] ^ arrNumbers[j];
            arrNumbers[i] = arrNumbers[i] ^ arrNumbers[j];
        }
    }
    if ( i != startIndex) {
        
        arrNumbers[i] = arrNumbers[i] ^ arrNumbers[startIndex];
        arrNumbers[startIndex] = arrNumbers[i] ^ arrNumbers[startIndex];
        arrNumbers[i] = arrNumbers[i] ^ arrNumbers[startIndex];
    }
    
    return i;
}


void QuickSort::sortV2(std::vector<int>& arrNumbers, int startIndex, int endIndex) {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    int index = partitionV2( arrNumbers, startIndex, endIndex );
    sortV2( arrNumbers, startIndex, index - 1 );
    sortV2( arrNumbers, index + 1, endIndex );
}


void QuickSort::sortV2(std::vector<int>& arrNumbers) {
    
    sortV2(arrNumbers, 0, arrNumbers.size() - 1);
}

Objective-C:

// 指针交换法
+ (NSInteger)partitionV2:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
              startIndex:(NSInteger)startIndex
                endIndex:(NSInteger)endIndex {
    
    NSInteger i = startIndex;
    NSInteger j = endIndex;
    while ( i != j ) {
        
        while ( i < j && arrMNumbers[j].integerValue >= arrMNumbers[startIndex].integerValue ) {
            
            --j;
        }
        
        while ( i < j && arrMNumbers[i].integerValue <= arrMNumbers[startIndex].integerValue ) {
            
            ++i;
        }
        
        if ( i < j ) {
            
            NSNumber *temp = arrMNumbers[i];
            arrMNumbers[i] = arrMNumbers[j];
            arrMNumbers[j] = temp;
        }
    }
    NSNumber *temp = arrMNumbers[i];
    arrMNumbers[i] = arrMNumbers[startIndex];
    arrMNumbers[startIndex] = temp;
    
    return i;
}


+ (void)quickSortV2:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
         startIndex:(NSInteger)startIndex
           endIndex:(NSInteger)endIndex {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    NSInteger index = [self partitionV2:arrMNumbers
                             startIndex:startIndex
                               endIndex:endIndex];
    [self quickSortV2:arrMNumbers
           startIndex:startIndex
             endIndex:index - 1];
    [self quickSortV2:arrMNumbers
           startIndex:index + 1
             endIndex:endIndex];
}


+ (nullable NSArray<NSNumber *> *)quickSortV2:(nonnull NSArray<NSNumber *> *)arrNumbers {
    
    NSMutableArray<NSNumber *> *arrMNumbers = [arrNumbers mutableCopy];
    [self quickSortV2:arrMNumbers
           startIndex:0
             endIndex:arrMNumbers.count - 1];
    
    return [arrMNumbers copy];
}

第三种:前后指针法
C++:

// 前后指针法
int QuickSort::partitionV3(std::vector<int> &arrNumbers, int startIndex, int endIndex) {
    
    int cur = startIndex;
    int pre = cur - 1;
    while ( cur <= endIndex ) {
        
        while ( cur <= endIndex && arrNumbers[cur] <= arrNumbers[startIndex] ) {
            
            ++cur;
            pre = cur - 1;
        }
        
        while ( cur <= endIndex && arrNumbers[cur] >= arrNumbers[startIndex] ) {
            
            ++cur;
        }
        
        if ( cur <= endIndex && pre + 1 < cur ) {
            
            std::swap( arrNumbers[pre + 1], arrNumbers[cur] );
            pre = pre + 1;
            cur = pre + 1;
        }
    }
    if ( pre <= endIndex && pre != startIndex ) {
        
        std::swap( arrNumbers[pre], arrNumbers[startIndex] );
    }
    
    return pre;
}


void QuickSort::sortV3(std::vector<int>& arrNumbers, int startIndex, int endIndex) {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    int index = partitionV3( arrNumbers, startIndex, endIndex );
    sortV3( arrNumbers, startIndex, index - 1 );
    sortV3( arrNumbers, index + 1, endIndex );
}


void QuickSort::sortV3(std::vector<int>& arrNumbers) {
    
    sortV3(arrNumbers, 0, arrNumbers.size() - 1);
}

Objective-C:

// 前后指针法
+ (NSInteger)partitionV3:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
              startIndex:(NSInteger)startIndex
                endIndex:(NSInteger)endIndex {
    
    NSInteger cur = startIndex;
    NSInteger pre = cur - 1;
    while ( cur <= endIndex && pre <= endIndex ) {

        while ( cur <= endIndex && arrMNumbers[cur].integerValue <= arrMNumbers[startIndex].integerValue ) {

            ++cur;
            pre = cur - 1;
        }

        while ( cur <= endIndex && arrMNumbers[cur].integerValue >= arrMNumbers[startIndex].integerValue ) {

            ++cur;
        }

        if ( cur <= endIndex && pre + 1 <= endIndex && pre + 1 < cur ) {

            NSNumber *temp = arrMNumbers[cur];
            arrMNumbers[cur] = arrMNumbers[pre + 1];
            arrMNumbers[pre + 1] = temp;

            pre = pre + 1;
            cur = pre + 1;
        }
    }
    if ( pre != startIndex && pre <= endIndex ) {

        NSNumber *temp = arrMNumbers[pre];
        arrMNumbers[pre] = arrMNumbers[startIndex];
        arrMNumbers[startIndex] = temp;
    }
    
    return pre;
}


+ (void)quickSortV3:(nonnull NSMutableArray<NSNumber *> *)arrMNumbers
         startIndex:(NSInteger)startIndex
           endIndex:(NSInteger)endIndex {
    
    if ( endIndex <= startIndex ) {
        
        return;
    }
    
    NSInteger index = [self partitionV3:arrMNumbers
                             startIndex:startIndex
                               endIndex:endIndex];
    if ( index == -1 ) {
        
        return;
    }
    [self quickSortV3:arrMNumbers
           startIndex:startIndex
             endIndex:index - 1];
    [self quickSortV3:arrMNumbers
           startIndex:index + 1
             endIndex:endIndex];
}


+ (nullable NSArray<NSNumber *> *)quickSortV3:(nonnull NSArray<NSNumber *> *)arrNumbers {
    
    NSMutableArray<NSNumber *> *arrMNumbers = [arrNumbers mutableCopy];
    [self quickSortV3:arrMNumbers
           startIndex:0
             endIndex:arrMNumbers.count - 1];
    
    return [arrMNumbers copy];
}

DEMO

上一篇下一篇

猜你喜欢

热点阅读