几种常见的排序算法

来源:互联网 发布:edraw max mac 密 编辑:程序博客网 时间:2024/06/05 17:00

【希尔排序】

思想是 通过每趟的缩小增量的排序,来使序列变得更加有序,最后来一趟直接插入排序,这样会使得效率会更高;

希尔排序平均时间复杂度为 O(logn);

【快速排序】

思想是 每一趟的快排都是以某个数为枢纽,枢纽的一边全是比它小,另外一边全是比它大的,经过这样几次的排序,最终得到一个有序的序列。

void quickSort(int arr[],int begin,int end){         int temp;         int i = begin,j = end;         if(i<j){             temp = arr[i];             while(i!=j){                 while(i<j&&arr[j]>temp) j--;                 if(i<j){                     arr[i] = arr[j];                     i++;                 }                 while(i<j&&arr[i]<temp) i++;                 if(i<j){                     arr[j] = arr[i];                     j--;                 }             }             arr[i] = temp;             quickSort(arr, begin, i-1);             quickSort(arr, i+1, end);         }     }

快排最好的情况是 O(nlogn),最坏的情况下 O(n^2),平均情况下是O(nlogn);
就平均情况而言,快排是所有排序算法中最好的,值得一提的是快排的空间复杂度是 O(logn);

【简单选择排序】

void simpleChoiceSort(int arr[],int n){        //每次都从待排序数组中选择一个来进行排序        int temp;        int i,j,k;        for(i=0;i<n;i++){            k = i;            temp = arr[i];            for(j=i+1;j<n;j++){                if(arr[i] > arr[j]){                    arr[i] = arr[j];                    k = j;                }            }            //因为arr[i]会及时更新,所以只需要对 arr[k]进行处理;            arr[k] = temp;            System.out.println(arr[i] +"***");        }    }

【堆排序】

堆排序的思路:
将无序的序列调整为一个完全二叉树,再调整成一个最大堆或最小堆,从而得到序列的最大的元素或最小的元素,然后与序列的最开始或最后的元素进行交换,重复几次,就可以使这个序列有序。

堆排序大顶堆得调整方法:
将当前结点a的值与子结点进行比较,如果有比它大的子节点,那么就选最大的与其交换,当 a这个结点来到下一层的时候重复上述过程,直到其孩子结点值都小于其值;

/**     * 数组元素下标是从1开始的,arr中存储的是一棵完全二叉树     */    void sift(int arr[],int low,int high){         int i = low,j = 2*i;        int temp = arr[i];        while(j<=high){            if(j<high&&arr[j]<arr[j+1])                ++j;            if(temp<arr[j]){                arr[i] = arr[j];                i = j;                j = 2*i;            }            else                break;        }        arr[i] = temp;    }    void  heapSort(int arr[],int n){        int i;        int temp;        for(i=n/2;i>=1;i--){            sift(arr,i,n);        }        for(i=n;i>=2;i--){            temp = arr[1];            arr[1] = arr[i];            arr[i] = temp;            sift(arr,1,i-1);        }    }

二路归并排序

思想:将一个待排序序列首先按一组一个元素这样分成很多组,明显第一次这样分,组内元素都是有序的,毕竟里面元素都只有一个;

接照进行 两个两个归并,进行组内排序,最后会对形成的两个大的有序序列进行归并,这样就可以了;

归并的算法复杂度是 O(nlogn),任何时候都是O(nlogn),跟初始序列无关。

0 0
原创粉丝点击