基本思想
通过 x 与中位数的比较,将原问题归结为规模减半的子问题,如果 x 小于中位数,则子问题由小于 x 的数构成,否则子问题由大于 x 的数构成。
步骤
优点
缺点
时间复杂度分析
二分检索法充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。
代码实现
#include
#include
using namespace std;
int BinSearch(vector<int>&v,int key)
{
int left,right,mid;
left=0;
right=v.size()-1;
while(left<=right)
{
mid=(left+right)/2;
if(key<v[mid]) //key小于中间值时
right=mid-1;//确定左子表范围
if(key>v[mid]) //key 大于中间值时
left=mid+1;//确定右子表范围
if(key==v[mid])//当key等于中间值时,证明查找成功
return mid;
}
if(left > right)
return -1;
}
int main()
{
int key = 5;
vector<int> v = {1,2,3,4,5,6,7,8,9,10};
cout<<BinSearch(v,key)<<endl;
return 0;
}
基本思想
任取待排序元素序列中的某元素作为基准值,将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此让整个数据变成有序序列。
将区间按照基准值划分为左右两半部分的常见方式有:
划分左右两半部分
int Partition1(vector<int>&v, int left, int right)
{
int begin = left;
int end = right;
int value=v[right];
while (begin < end)
{
while (begin < end && v[begin] <= value)
{
begin++;
}
while (begin < end && v[end] >= value)
{
end--;
}
Swap(v + begin, v + end);
}
Swap(v + begin, v + right);
return begin;
}
int Partition2(vector<int>&v, int left, int right)
{
int begin = left;
int end = right;
int pivot = v[right];
while (begin < end)
{
while (begin < end && v[begin] <= pivot)
{
begin++;
}
v[end] = v[begin];
while (begin < end && v[end] >= pivot)
{
end--;
}
v[begin] = v[end];
}
v[begin] = pivot;
return begin;
}
int Partition3(vector<int>&v, int left, int right)
{
int d = left;
for (int i = left; i < right; i++)
{
if (v[i] < v[right])
{
Swap(v + i, v + d);
d++;
}
}
Swap(v + d, v + right);
return d;
}
快速排序
void QuickSort(vector<int>&v, int left, int right)
{
if (left >= right)
{
return;
}
int div;
div = Partition1(v, left, right);
QuickSort(v, left, div - 1);
QuickSort(v, div + 1, right);
}
用栈实现快速排序
#include
void QuickSortNor(vector<int>&v, int size)
{
std::stack<int> stack;
stack.push(size - 1); // right
stack.push(0); // left
while (!stack.empty())
{
int left = stack.top();
stack.pop();
int right = stack.top();
stack.pop();
if (left >= right)
{
continue;
}
else
{
int d = Partition1(v, left, right);
// [d + 1, right]
stack.push(right);
stack.push(d + 1);
// [left, d - 1]
stack.push(d - 1);
stack.push(left);
}
}
}
效率分析
时间
空间
稳定性
基本思想
代码实现:
void Merge(int array[], int left, int mid, int right, int extra[])
{
int size = right - left;
int left_index = left;
int right_index = mid;
int extra_index = 0;
while (left_index < mid && right_index < right)
{
if (array[left_index] <= array[right_index])
{
extra[extra_index] = array[left_index];
left_index++;
}
else
{
extra[extra_index] = array[right_index];
right_index++;
}
extra_index++;
}
while (left_index < mid)
{
extra[extra_index++] = array[left_index++];
}
while (right_index < right)
{
extra[extra_index++] = array[right_index++];
}
for (int i = 0; i < size; i++)
{
array[left + i] = extra[i];
}
}
// 要排序的区间是 array[left, right)
void __MergeSort(int array[], int left, int right, int extra[])
{
if ((right == left + 1) || (right <= left))
{
return;
}
int mid = left + (right - left) / 2;
// [left, mid) [mid, right)
__MergeSort(array, left, mid, extra);
__MergeSort(array, mid, right, extra);
Merge(array, left, mid, right, extra);
}
void MergeSort(int array[], int size)
{
int *extra = (int *)malloc(sizeof(int)* size);
__MergeSort(array, 0, size, extra);
free(extra);
}
void MergeSortNor(int array[], int size)
{
int *extra = (int *)malloc(sizeof(int)* size);
for (int i = 1; i < size; i = i * 2)
{
for (int j = 0; j < size; j = j + 2 * i)
{
int left, mid, right;
left = j;
mid = j + i;
right = mid + i;
if (mid >= size)
{
continue;
}
if (right > size)
{
right = size;
}
Merge(array, left, mid, right, extra);
}
}
free(extra);
}
特性总结: