排序算法总结(PHP实现)

排序算法看了忘忘了看,干脆写一遍。

  • 时间复杂度:希尔、快排、归并、堆 nlogn ,快排可退化为n^2
  • 空间复杂度:快排nlogn,归并n
  • 稳定性:冒泡、插入、归并稳定

冒泡排序

n-1次冒泡,每次一轮循环交换出一个最大/最小的

//C++
void maopao(int r[],int n)
{
    for(int i=0;i<n-1;i++)
        for(int j=0;j<n-i-1;j++)
        {
            if(r[j]>r[j+1])
            {
                int temp=r[j];
                r[j]=r[j+1];
                r[j+1]=temp;
            }
        }
}
//php 含有标志优化
function BubbleSort($arr) {
    $len = count($arr);
    //设置一个空数组 用来接收冒出来的泡
    //该层循环控制 需要冒泡的轮数
    for ($i = 1; $i < $len; $i++) {
        $flag = false;    //本趟排序开始前,交换标志应为假
        //该层循环用来控制每轮 冒出一个数 需要比较的次数
        for ($k = 0; $k < $len - $i; $k++) {
            //从小到大排序
            if ($arr[$k] > $arr[$k + 1]) {
                $tmp = $arr[$k + 1];
                $arr[$k + 1] = $arr[$k];
                $arr[$k] = $tmp;
                $flag = true;
            }
        }
        if(!$flag) return $arr;
    }
}

选择排序

n-1次选择,每次从无序中选一个最大/最小的放到第一位

void select_sort(int * a,int n)
{
    register int i,j,min,t;
    for(i=0;i<n-1;i++)
    {
        min=i;//查找最小值
        for(j=i+1;j<n;j++)
            if(a[min]>a[j])
                min=j;//交换
        if(min!=i)
        {
            t=a[min];
            a[min]=a[i];
            a[i]=t;
        }
    }
}
function selectSort($array){
    $temp = 0;
    for($i = 0;$i < count($array) - 1;$i++){
        $min = $i;
        for($j = $i+1;$j < count($array);$j++){
            if($array[$min] > $array[$j]){ //从小到大排列
                $min = $j;
            }
        }
        $temp = $array[$i];
        $array[$i] = $array[$min];
        $array[$min] = $temp;
    }
}

插入排序

n-1次插入,默认0有序,每次将当前的元素插入到有序数组中

void insert_sort(int array[],int n)
{
    int i,j;
    int temp;
    for(i=1;i<n;i++)
    {
        temp=array[i];
        j=i-1;
        //与已排序的数逐一比较,大于temp时,该数移后
        while((j>=0)&&(array[j]>temp))
        {
            array[j+1]=array[j];
            j--;
        }
        //存在大于temp的数
        if(j!=i-1) {array[j+1]=temp;}
    }

}
function insertSort($array){ //从小到大排列
//先默认$array[0],已经有序,是有序表
    for($i = 1;$i < count($array);$i++){
        $insertVal = $array[$i]; //$insertVal是准备插入的数
        $insertIndex = $i - 1; //有序表中准备比较的数的下标
        while($insertIndex >= 0 && $insertVal < $array[$insertIndex]){
            $array[$insertIndex + 1] = $array[$insertIndex]; //将数组往后挪
            $insertIndex--; //将下标往前挪,准备与前一个进行比较
        }
        if($insertIndex + 1 !== $i){
            $array[$insertIndex + 1] = $insertVal;
        }
    }
}

希尔排序

插入排序的优化,设置增量,按照增量间隔插入,期间不断缩小增量

void shellSort(int a[], int n)  
{  
    int i, j, gap;  
  
    for (gap = n / 2; gap > 0; gap /= 2)  
        for (i = gap; i < n; i++)  
            for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap)  
                Swap(a[j], a[j + gap]);  
}  
function shellSort($array){
    $count = count($array);
    $gap = floor($count/2);
    while($gap>0){
        for($i=$gap;$i<$count;$i++)
            for($j=$i-$gap;$j>=0&&$array[$j]>$array[$j+$gap];$j-=$gap)
            {
                $temp = $array[$j];
                $array[$j]=$array[$j+$gap];
                $array[$j+$gap]=$temp;
            }
            $gap=floor($gap/2);
    }
    return $array;
}

快速排序

划分,不多说

void qsort(int a[],int l,int r)
{
    if(l>=r) return;


    int first=l;
    int last=r;
    int key=a[first];

    while(first<last)
    {
        while(first<last&&a[last]>=key) last--;
        a[first]=a[last];
        while(first<last&&a[first]<=key) first++;
        a[last]=a[first];


    }
    a[first]=key;
    qsort(a,l,first-1);
    qsort(a,first+1,r);
}
function quickSort(&$array,$l,$r){
    if($l>=$r) return;
    $key = $array[$l];
    $left = $l;
    $right = $r;
    while($left<$right)
    {
        while($left<$right&&$array[$right]>=$key) $right--;
        $array[$left]=$array[$right];
        while($left<$right&&$array[$left]<=$key) $left++;
        $array[$right]=$array[$left];


    }
    $array[$left]=$key;
    quickSort($array,$l,$right-1);
    quickSort($array,$left+1,$r);
}

堆排序

先建堆:从n/2个节点往前依次维护堆。维护:调整该节点与左右子节点关系,若有变动则维护变动子节点堆。做n次取节点,每次交换后维护剩下堆。

void headadjust(int a[],int i,int n)
{
    int lc=i*2;
    int rc=i*2+1;
    int max=i;

    if(i<=n/2){
        if(lc<=n&&a[max]<a[lc]) max=lc;
        if(rc<=n&&a[max]<a[rc]) max=rc;
        if(max!=i)
        {
            swap(a[i],a[max]);
            hheadadjust(a,max,n);
        }
    }
}
void heapbuild(int a[],int n)
{
    for(int i=n/2;i>=1;i--)
        headadjust(a,i,n);

}
void heapsort(int a[],int n)
{
    heapbuild(a,n);
    for(int i=n;i>=1;i--) {
        swap(a[1], a[i]);
        headadjust(a,1,i-1);
    }
}

归并排序

递归二分数组,然后将数组交叉合并

void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex)
{
    int i = startIndex, j=midIndex+1, k = startIndex;
    while(i!=midIndex+1 && j!=endIndex+1)
    {
        if(sourceArr[i] > sourceArr[j])
            tempArr[k++] = sourceArr[j++];
        else
            tempArr[k++] = sourceArr[i++];
    }
    while(i != midIndex+1)
        tempArr[k++] = sourceArr[i++];
    while(j != endIndex+1)
        tempArr[k++] = sourceArr[j++];
    for(i=startIndex; i<=endIndex; i++)
        sourceArr[i] = tempArr[i];
}
 
//内部使用递归
void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex)
{
    int midIndex;
    if(startIndex < endIndex)
    {
        midIndex = (startIndex + endIndex) / 2;
        MergeSort(sourceArr, tempArr, startIndex, midIndex);
        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
    }
}
function mergeSortRecursion(&$arr, $begin, $end) {
    if ($begin < $end) {
        $mid = floor(($begin + $end) / 2);
        // 把数组不断拆分,只到只剩下一个元素,对于一个元素的数组,一定是排序好的
        mergeSortRecursion($arr, $begin, $mid);
        mergeSortRecursion($arr, $mid + 1, $end);
        $i = $begin;
        $j = $mid + 1;
        $k = 0;
        $temp = array();
        // 开始执行归并,遍历两个数组,从它们里面取较小的元素插入到新数组中
        while ($i <= $mid && $j <= $end) {
            if ($arr[$i] < $arr[$j]) {
                $temp[$k++] = $arr[$i++];
            } else {
                $temp[$k++] = $arr[$j++];
            }
        }
        while ($i <= $mid) {
            $temp[$k++] = $arr[$i++];
        }
        while ($j <= $end) {
            $temp[$k++] = $arr[$j++];
        }
        for ($i = 0; $i < $k; $i++) {
            $arr[$i + $begin] = $temp[$i];
        }
    }
   
}

排序PHP

1198 Words

2017-09-26 08:00 +0800