目录
1.1冒泡排序(BubbleSort)
1.2鸡尾酒排序(CocktailSort)
2.选择排序(SelectionSort)
3.1插入排序——直接插入排序(StraightInsertionSort)
3.2插入排序——二分查找排序(BinarySearchSort)
3.3插入排序——希尔排序(ShellSort)
4.归并排序(MergeSort)
5.堆排序(HeapSort)
6.快速排序(QuickSort)
7.计数排序(CountingSort)
8.基数排序(RadixSort)
9.桶排序(BucketSort)
参考:http://www.cnblogs.com/eniac12/p/5329396.html
原理
$arr[$j + 1]) { // 比较相邻两个元素,较大的后移
$t = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $t;
}
}
}
return $arr;
}
print_r(BubbleSort($arr));
鸡尾酒排序也就是定向冒泡排序, 鸡尾酒搅拌排序, 搅拌排序 (也可以视作选择排序的一种变形), 涟漪排序, 来回排序 or 快乐小时排序, 是冒泡排序的一种变形。此演算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序。
原理:数组中的数字本是无规律的排放,先找到最小的数字,把他放到第一位,然后找到最大的数字放到最后一位。然后再找到第二小的数字放到第二位,再找到第二大的数字放到倒数第二位。以此类推,直到完成排序。
$arr[$i + 1]) {
$t = $arr[$i];
$arr[$i] = $arr[$i + 1];
$arr[$i + 1] = $t;
}
}
$right--; // 右边界缩小
for ($i = $right; $i > $left; $i--) { // 从右向左,将最小元素放在前面
if ($arr[$i-1] > $arr[$i]) {
$t = $arr[$i -1];
$arr[$i - 1] = $arr[$i];
$arr[$i] = $t;
}
}
$left++; // 左边界增大
}
return $arr;
}
print_r(CocktailSort($arr));
原理:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完.。
原理
= 0 && $arr[$j] > $get) { // 当指针指向的元素比要比较的元素大
$arr[$j + 1] = $arr[$j]; // 则将指针指向的元素向后移动一位
$j--; // 指针前移
}
$arr[$j + 1] = $get; // 直到指针指向的元素与要比较元素小或者相等,则要比较元素插入到指针指向元素后
}
return $arr;
}
print_r(StraightInsertionSort($arr));
原理:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
$get) { // 如果中间数大于比较元素,则比较元素属于前半段
$right = $mid -1; // 右边界左移
} else { // 否则比较元素属于后半段
$left = $mid + 1; // 左边界右移
}
}
for ($j = $i -1; $j >= $left; $j--) { // 最后的$left就是待插入位置
$arr[$j + 1] = $arr[$j]; // 将待插入位置的右边整体向右移动一个单位
}
$arr[$left] = $get; // 将比较元素插入该空位
}
return $arr;
}
print_r(BinarySearchSort($arr));
希尔排序,也叫递减增量排序,是插入排序的一种更高效的改进版本。希尔排序是不稳定的排序算法。
原理:希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
增量序列:由Knuth提出,递归表达式为:h = 3 * h + 1;减小增量:h = (h - 1) / 3;此公式产生的逆置序列为:..., 314, 121, 40, 13, 4, 1。
= 1) {
for ($i = $h; $i < $length; $i++) {
$j = $i - $h;
$get = $arr[$i]; // 暂存要比较的元素
while ($j >= 0 && $arr[$j] > $get) { // 组内判断,若组内元素大于该元素
$arr[$j + $h] = $arr[$j]; // 则两者位置互换
$j = $j - $h; // 指针继续向前移动增量的距离,继续比较
}
$arr[$j + $h] = $get;
}
$h = ($h - 1) / 3; // 递减增量
}
return $arr;
}
print_r(ShellSort($arr));
原理:归并排序的实现分为递归实现与非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组。
归并排序算法主要依赖归并(Merge)操作。归并操作指的是将两个已经排序的序列合并成一个序列的操作,归并操作步骤如下:
原理:
$arr[$max]) {
$max = $left_child;
}
if ($right_child < $heap_size && $arr[$right_child] > $arr[$max]) {
$max = $right_child;
}
if ($max != $i) {
Swap($arr, $i, $max); // 当前结点与最大值进行交换
Heapify($arr, $max, $heap_size); // 递归,继续调整
}
}
// 建堆,时间复杂度O(n)
function BuildHeap(&$arr, $len)
{
$heap_size = $len;
for ($i = floor($heap_size / 2) - 1; $i >= 0; $i--) { // 从每一个非叶子结点开始向下进行堆调整
Heapify($arr, $i, $heap_size);
}
return $heap_size;
}
// 堆排序
function HeapSort($arr, $len)
{
$heap_size = BuildHeap($arr, $len); // 建立最大堆(无序区)
while ($heap_size > 1) { // 堆(无序区)元素大于1,未完成排序
Swap($arr, 0, --$heap_size); // 将堆定元素沉到堆底(成为有序区),堆(无序区)-1
Heapify($arr, 0, $heap_size); // 从新的栈顶元素开始向下调整
}
return $arr;
}
print_r(HeapSort($arr, $len));
快速排序使用分治策略(Divide and Conquer)来把一个序列分为两个子序列。
原理:
= $right)
return;
$pivot_index = Partition($arr, $left, $right); // 基准的索引
QuickSort($arr, $left, $pivot_index - 1);
QuickSort($arr, $pivot_index + 1, $right);
return $arr;
}
print_r(QuickSort($arr, 0, $len - 1));
计数排序适合排序一定范围内的数,例如0-99之间的排序
原理:
= 0; $i--) { // 从后向前扫描保证排序稳定性
// 把每个元素A[$i]放到它在输出数组B中的正确位置上
// 当遇到重复元素时,会被放到当前的前一个位置上保证稳定性
$arrB[--$arrC[$arrA[$i]]] = $arrA[$i];
}
for ($i = 0; $i < $len; $i++) { // 把B中的数据拷贝回A
$arrA[$i] = $arrB[$i];
}
return $arrA;
}
print_r(CountingSort($arrA, $len));