归并排序、快排、堆排代码记录

321 阅读2分钟

三种常见的让手撕的代码,记录下来,写在博客里方便面试前看一看。

1. 归并排序

//处理合并
void merge(vector<int>& arr, int low, int middle, int high) {
    int* total = &arr[low];
    int* leftPart = new int[middle - low];
    for (int i = 0; i < middle - low; i++) {
        leftPart[i] = total[i];
    }
    int* rightPart = &arr[middle];
    int leftBound = middle - low;
    int rightBound = high - middle;
    for (int i = 0, j = 0, k = 0; j < leftBound || k < rightBound; ) {
        if ((j < leftBound) && (k >= rightBound || leftPart[j] <= rightPart[k]))
            total[i++] = leftPart[j++];
        if ((k < rightBound) && (j >= leftBound || rightPart[k] < leftPart[j]))
            total[i++] = rightPart[k++];
    }
    delete[] leftPart;
}
//处理递归
void mergeSort(vector<int>& arr, int low, int high) {
    if (high - low < 2) {
        return;        //递归基
    }
    int middle = (low + high) / 2;
    mergeSort(arr, low, middle);
    mergeSort(arr, middle, high);
    merge(arr, low, middle, high);
}

2. 快排

int partition(vector<int>& arr, int low, int high) {
    int tmp = rand() % (high - low + 1) + low;
    if( low != tmp)
        swap(arr[low], arr[tmp]);        //随机选取轴点
    int p = arr[low];        //轴点
    int middle = low;        //middle指向小于轴点的最后一个元素
    int k = low + 1;        //k用来遍历除开头轴点外的所有元素
    for (; k <= high; k++) {
        if (arr[k] < p) {
            swap(arr[k], arr[++middle]);
        }
    }
    swap(arr[low], arr[middle]);
    return middle;
}

void quickSort(vector<int>& arr, int low, int high) {
    if (low == high)
        return;
    int middle = partition(arr, low, high);
    if (middle > low)
        quickSort(arr, low, middle - 1);
    if (middle < high)
        quickSort(arr, middle + 1, high);

}

3. 堆排序

//下滤操作
void goDown(vector<int>& nums, int len, int i) {
	int leftIndex = i * 2 + 1;
	int rightIndex = (i + 1) * 2;
	if (leftIndex < len && nums[leftIndex] > nums[i] && (rightIndex >= len || nums[leftIndex] > nums[rightIndex])) {
		swap(nums[i], nums[leftIndex]);
		goDown(nums,len,leftIndex);
	}
	else if (rightIndex < len && nums[rightIndex] > nums[i] && (leftIndex >= len || nums[rightIndex] > nums[leftIndex])) {
		swap(nums[i], nums[rightIndex]);
		goDown(nums, len, rightIndex);
	}
}

//建堆操作
void makeHeap(vector<int>& nums) {
	int len = nums.size();
	//最后一个非叶子节点
	int i = len / 2 - 1;
	for (; i >= 0; i--) {
		goDown(nums,len, i);
	}
}

void heapSort(vector<int>& nums) {
	//先建堆
	makeHeap(nums);
	//选择堆顶最大元素加入已排序部分
	int len = nums.size();
	while (len > 1) {
		swap(nums[0], nums[len - 1]);
		goDown(nums, --len, 0);
	}
}