基础算法之快排、归并、二分

一、快速排序

快速排序基于分治思想,时间复杂度(nlogn)

快排的步骤:

  1. 确定分界点:q[left]、q[(left + right) / 2]、q[right] 三个其中一个都行
  2. 调整(划分)区间(快排的重点):把小于pivot的放在左区间,大于pivot的放在右区间
  3. 递归处理左右两个区间

算法思想:

在区间左右两端定义i和j两个指针,假设pivot为x,当i下标对应的元素小于x时i++,当i下标对应的元素不小于x时i不变,则开始移动j,当j下标对应的元素大于x时j--,当j下标对应的元素不大于x时j不变,交换i和j下标对应的元素,重复以上操作直到i和j相遇为止

//快速排序模板
void quick_sort(int q[], int left, int right){
    if(left >= right)
		return;
	int i = left - 1, j = right + 1, pivot = q[left + right >> 1];
	while(i < j){
		do{
			i++;
		}while(q[i] < pivot);
		do{
			j--;
		}while(q[j] > pivot);
		if(i < j)
			swap(q[i], q[j]);
	}
	quick_sort(q, left, j);
	quick_sort(q, j + 1, right);
}

二、归并排序

归并排序基于分治思想,时间复杂度(nlogn)

归并步骤:

  1. 确定分界点:mid = left + (right - left) / 2
  2. 递归排序左右区间
  3. 归并(归并排序的重点):把两个有序的数组合并成一个有序的数组(合二为一)

算法思想:

归并简单来说其实就是比较两个数组,把两个数组中比较小的数插入到新的数组中

//归并排序模板
void merge_sort(int q[], int left, int right){
	if(left >= right)
		return;
	int mid = left + (right - left) / 2; //(right + left) >> 1;
	merge_sort(q, left, mid);
	merge_sort(q, mid + 1, right);
	int k = 0, i = left, j = mid + 1;
    //两两比较
	while(i <= mid && j <= right){
		if(q[i] <= q[j])
			temp[k++] = q[i++];
		else
			temp[k++] = q[j++];
	}
    //把两个数组剩余的元素插入到temp数组
	while(i <= mid)
		temp[k++] = q[i++];
	while(j <= right)
		temp[k++] = q[j++];
    //将排序结果赋回给原数组
	for(int i = left, j = 0; i <= right; i++, j++)
		q[i] = temp[j];
}

三、二分查找

二分查找的本质是在某种性质下找到满足和不满足的边界

bool check(int x) {/* ... */} //检查x是否满足某种性质

// 区间[left, right] 被划分成[left, mid] 和 [mid + 1, right]时使用
int bsearch_1(int left, int right){
	while(left < right){
		int mid = left + right >> 1;
		if(check(mid))
			right = mid;
		else
			left = mid + 1;
	}
	return left;
}

// 区间[left, right] 被划分成[left, mid - 1] 和 [mid, right]时使用
int bsearch_1(int left, int right){
	while(left < right){
		int mid = left + right + 1 >> 1;
		if(check(mid))
			left = mid;
		else
			right = mid - 1;
	}
	return left;
}

你可能感兴趣的:(基础算法,算法,排序算法)