经典面试算法实现,很多面试的笔试都喜欢出其中一个,特别是二分查找和冒泡算法,个人觉得出现的机率还是挺高的。平时工作中可能已经用到了,但自己却不知道,导致很多时候在面试的时候一下子写不出来。
1、顺序查找法
1)思路:逐个比较,直到找到结果或者查找失败。
2)时间复杂度:O(n)。
2、二分查找法
1)思路:选择中间元素,如果被查找的数据刚好在中间则返回;如果被查找的数据比中间数小,则把查找结束值设为中间值减1再重新查找;如果被查找的数据比中间数大,则把开始值设为中间值加1重新查找。
2)时间复杂度:O(log n)。
注:此查找法的前提是目标数组已从小到大排序。
3、冒泡算法
1)思路:遍历所有元素,相邻数据比较,如果前数据比后数据大,则交换。
2)时间复杂度:O(n^2)
4、快速排序
1)思路:分而治之,递归实现。此算法是对冒泡排序算法的一种改进。通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
2)时间复杂度:平均 O(n*log n),最坏 O(n^2)
5、选择排序
1)思路:找出一个最小数,交换到最前面。在剩下的数里面,再找一个最小的,交换到剩下数的最前面.重复前面步骤,直到所有数都已排好。
2)时间复杂度: O(n^2)
6、插入排序
1)思路:将一个记录插入到已经排好序的有序表中。
2)时间复杂度:O(n) ~ O(n^2)
<?php
class Algorithm
{
public function __contruct()
{
}
/**
* @name 顺序查找
* @param $arr 数组
* @param $val 查找的值
* @return int 数据对应的数组位置,-1为未找到
*/
public function sqSearch($arr,$val)
{
$count = count($arr);
for($i = 0; $i < $count; $i++){
if($arr[$i] == $val){
return $i;
}
}
return -1;
}
/*
* 二分查找法,前提:数据已排序
* @return int 数据对应的数组位置,-1为未找到
*/
public function binarySearch($arr,$srchVal)
{
$start = 0;
$end = count($arr);
while ($start < $end){
$mid = intval(($end + $start)/2);
$midVal = $arr[$mid];
//刚好找到
if($midVal == $srchVal){
return $mid;
}
//查询值比中间值大,则设置开始值位置
if($srchVal > $midVal){
$start = $mid + 1;
}else{
$end = $mid - 1;
}
}
//没有找到
return -1;
}
/*
* 冒泡排序
* 实现:相邻数据比较,如果前数据比后数据大,则交换
*/
public function bubbleSort($arr)
{
$count = count($arr);
for($i = 0; $i < $count; $i++){
for($j = 1; $j < $count; $j++){
if($arr[$j-1] > $arr[$j]){
$temp = $arr[$j-1];
$arr[$j-1] = $arr[$j];
$arr[$j] = $temp;
}
}
}
return $arr;
}
/*
* 快速排序
* 思想:分而治之,递归
* 实现:1、选择一个基准值
* 2、排序:小于基准值的排左边,大于基准值的排右边
* 3、递归2中的数组
*/
public function quickSort($arr)
{
$count = count($arr);
if($count < 2){
return $arr;
}
$polit = $arr[0];
$arrLeft = $arrRight = array();
for($i = 1; $i < $count; $i++){
if($arr[$i] < $polit){
$arrLeft[] = $arr[$i];
}else{
$arrRight[] = $arr[$i];
}
}
$arrLeft = $this->quickSort($arrLeft);
$arrRight = $this->quickSort($arrRight);
return array_merge($arrLeft,array($polit),$arrRight);
}
/*
* 选择排序
* 实现:先找出最小值,然后依次找出其次值
*/
public function selectSort($arr)
{
$count = count($arr);
for($i = 0; $i < $count; $i++){
$index = $i;
for($j = $i+1; $j < $count; $j++){
if($arr[$j] < $arr[$index]){
$index = $j;
}
}
//交换
$temp = $arr[$i];
$arr[$i] = $arr[$index];
$arr[$index] = $temp;
}
return $arr;
}
/**
* 插入排序
* @param $arr
* @return false
*/
public function insertSort($arr)
{
$count = count($arr);
if($count <= 0){
return false;
}
for($i = 1; $i < $count; $i++){
//需要插入的数据
$temp = $arr[$i];
//前一个数据
$j = $i-1;
//前比后大,则交换
while ($j >= 0 && $arr[$j] > $temp){
$arr[$j+1] = $arr[$j];
$j--;
}
//否则保留原来的值
$arr[$j+1] = $temp;
}
return $arr;
}
/**
* @name 阶乘
* @param $i
* @return float|int
*/
public function loopFun($i)
{
//echo $i;
if($i > 1){
$i2 = $i-1;
$result = $i * $this->loopFun($i2);
}else{
$result = $i;
}
return $result;
}
/**
* @name 倒序排列字符串
* @param $str
* @return $str;
*/
public function arSortString($str)
{
//php原生函数
//return strrev($str);
$len = strlen($str);
$strReturn = '';
for($i = ($len-1); $i >= 0; $i--){
$strReturn .= $str[$i];
}
return $strReturn;
}
/**
* @name 不使用第3个参数交换两个参数值
* @param $a
* @param $b
* @return $b,$a;
*/
public function switchVal($a,$b)
{
list($b, $a) = array($a, $b);
return 'A:'.$a.'-B:'.$b;
}
}
//测试
$algo = new Algorithm();
echo '<pre>';
//初始化测试数组
$arr = [10,22,2,3,1,99,5,9,8,100,33,44,55,66,77];
//顺序查找法
$data = $algo->sqSearch($arr,100);
print_r($data);
//二分查找法,需要先对数组排序(从小到大),此处使用快速排序算法
$dataQuick = $algo->quickSort($arr);
print_r($dataQuick);
$data = $algo->binarySearch($dataQuick,44);
print_r($data);
//其他方法测试类似
//冒泡算法
$data = $algo->bubbleSort($arr);
print_r($data);
//选择排序
$data = $algo->selectSort($arr);
print_r($data);
//插入排序
$data = $algo->insertSort($arr);
print_r($data);