《算法设计与分析基础》学习 --- 蛮力法
要重温算法思想,并以《算法设计与分析基础》这本书作为教材。该书每一章介绍一种算法设计思想。今天从最简单的开始写起,打好基础。以后再逐步深入,学习更深入的算法。
蛮力法就是一种解决问题的最简单最直观的最容易理解方法,虽然它简单,而且在实际应用中因为效率的原因可能不能派上用场,但是还是不能忽略它。正如书中作者所说,在解决小规模问题的时候也不失为一个方法,而且也是更复杂算法的基础。
一、选择排序
以最简单的思路解决排序问题,对于N个元素的数组,通过N次扫描数组,每次选择出最小的元素放置到正确的位置,N趟扫描后即完成排序。
/*
蛮力法-选择排序
将输入数组排成非递减数组
array:待排数组
n:数组大小,即[0,n-1]
*/
void SelectionSort(int array[],unsigned int n)
{
int min;
for(int i=0;i<n-1;i++)
{
min=i;
for(int j=i+1;j<n;j++)
{
if(array[j]<array[min])
min = j;
}
if(i!=min)
{
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
}//SelectionSort
这是一个最差的排序方法,对于任何输入都是 O(n*n)的时间复杂度。但是它的最大优点就是交换次数最少。
二、冒泡排序
又是一个经典的蛮力排序算法。这里我仅仅对原始的冒泡做了点点改进,如果算法已经排好序的话该算法扫描一遍便完成排序。
/*
蛮力法-冒泡排序(稍微改进版)
将输入数组排成非递减数组
array:待排数组
n:数组大小,即[0,n-1]
*/
void BubbleSort(int array[],unsigned int n)
{
int i=n-1;
int last;
while(i>0)
{
last = 0;
for(int j=0;j<i;j++)
{
if(array[j]>array[j+1])
{
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
last = j; //记录最近一次交换值的位置
}
}
i = last;
}
}//BubbleSort
但是在最差的情况下,它还是O(n*n)的时间复杂度。
三、顺序查找和字符串的蛮力匹配
顺序查找,再简单不过的查找算法了,算是对蛮力思想的一种应用。以及字符串的蛮力匹配也是这样的。
/*
蛮力法-顺序查找
在数组中查找给定键的位置
array:待排数组
n:数组大小,即[0,n-1]
k:查找键
*/
int SequentialSearch(int array[],unsigned int n,int k)
{
int i = 0;
while(array[i] != k)
i++;
if(i<n)
return i;
else
return -1;
}//SequentialSearch
--------------------------------------
/*
蛮力法-字符串蛮力匹配
text[0,n-1]:查找文本
pattern[0,m-1]:查找字符串
返回匹配首位置,或者不匹配返回-1
*/
int BruteForcesStringMatch(char text[],unsigned int n,
char pattern[],unsigned m)
{
int j;
for(int i=0;i<=n-m;i++)
{
j=0;
while(j<m && pattern[j] == text[i+j])
j++;
if(j==m)
return i;
}
return -1;
}//BruteForcesStringMatch
对于蛮力思想用来求“最近对”问题,背包问题的代码。个人感觉这样的代码实在太没有实际意义了,就直接跳过了。等用分治的思想来写。OK,用最简单的几个算法回顾了蛮力思想。
By: 洪庚伟