1 Sorting模板

Partition

模板一:用数组内的数切一刀,能返回index (L399 Nuts & Bolts Problem)左边的数都小于等于pivot,右边的都大于等于pivot,这个数是在数组里的

public int partition(int[] nums, int l, int r) {
    //初始化左右指针和pivot
    int left = l, right = r;
    int pivot = nums[left];

    //进行partition
    while (left < right) {
        while (left < right && nums[right] >= pivot) {
            right--;
        }

        nums[left] = nums[right];

        while (left < right && nums[left] <= pivot) {
            left++;
        }
        nums[right] = nums[left];
    }

    // 返回pivot点到数组里
    nums[left] = pivot;
    return left;
}

模板二:用任何数字切一刀,不能返回index。(912 Sort an Array)把数组一刀切成两份,但切的这个数,不一定是数组内的数,切完以后左半部分>=右半部分

int left = start, right = end;
//key point 1: pivot is the value, not the index
int pivot = A[(start + end) / 2];

//key point 2: every time you compare left & right, it should be left <= right 
while (left <= right) {
    //key point 3: A[left] < pivot
    while (left <= right && A[left] < pivot) {
        left++;
    }

    //key point 3: A[right] > pivot
    while (left <= right && A[right] > pivot) {
        right--;
    }

    if (left <= right) {
         int tmp = A[left];
         A[left] = A[right];
         A[right] = tmp;

         left++;
         rigth--;
     }
 }

模板三:3 way partitions

main(){
    3WayP(A, 0, A.len - 1);
}

3WayP(A, s, e) {
    if (s >= e) {
        return;
    }

    int mid = s + (e - s) / 2;
    int pivot = A[mid];
    int i = s;
    int left = i, right = e;

    while (i <= right) {
        if (A[i] == pivot) {
            i++;
        } else if (A[i] < pivot) {
            swap(i, left);
            i++;
            left++;
        } else {
            swap(i, right);
            right--;
        }
    }    

    3wayP(A, s, left);
    3wayP(A, i, end);
}

模板四:geeksforgeeks,当我们传入pivot value,然后要求返回index。L399 Nuts & Bolts Problem的另一种模板

parition(A, s, e, pivotVal) {
    int i = s;
    for (j = s; j < e; j++) {
        if (A[j] < pivotVal) {
            swap(i, j);
            i++;
        } else if (A[j] == pivotVal) {
            swap(j, e);
            j--;
        }
        swap(i, e);
        return i;
    }
}

Quick Select

L5 Kth Largest Element (215)--- 相关703 用heap

Merge sort

还可以参照L532 Reverse Pair,那题用了ctici的模板。
注意从调用时包含end,传len-1。 还有从mid + 1 开始算。
public void sortIntegers2(int[] A) {
    // use a shared temp array, the extra memory is O(n) at least
    int[] temp = new int[A.length];
    mergeSort(A, 0, A.length - 1, temp);
}

private void mergeSort(int[] A, int start, int end, int[] temp) {
    if (start >= end) {
        return;
    }

    int mid = (start + end) / 2;

    mergeSort(A, start, mid, temp);
    mergeSort(A, mid+1, end, temp);
    merge(A, start, mid, end, temp);
}

private void merge(int[] A, int start, int mid, int end, int[] temp) {
    int left = start;
    int right = mid+1;
    int index = start;

    // merge two sorted subarrays in A to temp array
    while (left <= mid && right <= end) {
        if (A[left] < A[right]) {
            temp[index++] = A[left++];
        } else {
            temp[index++] = A[right++];
        }
    }
    while (left <= mid) {
        temp[index++] = A[left++];
    }
    while (right <= end) {
        temp[index++] = A[right++];
    }

    // copy temp back to A
    for (index = start; index <= end; index++) {
        A[index] = temp[index];
    }
}

Quick Sort

public void sortIntegers2(int[] A) {
    quickSort(A, 0, A.length - 1);
}

private void quickSort(int[] A, int start, int end) {
    if (start >= end) {
        return;
    }

    int left = start, right = end;
    // key point 1: pivot is the value, not the index
    int pivot = A[(start + end) / 2];

    // key point 2: every time you compare left & right, it should be 
    // left <= right not left < right
    while (left <= right) {
        // key point 3: A[left] < pivot not A[left] <= pivot
        while (left <= right && A[left] < pivot) {
            left++;
        }
        // key point 3: A[right] > pivot not A[right] >= pivot
        while (left <= right && A[right] > pivot) {
            right--;
        }
        if (left <= right) {
            int temp = A[left];
            A[left] = A[right];
            A[right] = temp;

            left++;
            right--;
        }
    }

    quickSort(A, start, right);
    quickSort(A, left, end);
}

Last updated