小丸子总结排序算法

来源:互联网 发布:qq飞车q吧数据 编辑:程序博客网 时间:2024/04/25 10:25

一. 排序算法(内部排序)

1.直接插入排序

(1)思路:每次将一个待排序的记录,根据关键字的大小,插入到排好序的序列里。

(2)代码:

function sort(arr){        for(var i = 1; i < arr.length; i++ ){            for(var j = 0; j < i; j++ ){                if(arr[j] > arr[i]){                    var tmp = arr[i];                    arr[i] = arr[j];                    arr[j] = tmp;                }            }        }        return arr;    }    var arr = [3,5,7,2,1,5,8,9,67,4,3,90];    sort(arr);

(3)复杂度:

  • 时间复杂度:O(n方)
  • 空间复杂度:O(1)

(4)稳定性:稳定排序。

2.折半排序

(1)思路:在直接插入排序的基础上,先跟已排序序列的中间节点比较,如果小于中间节点,则跟前一半序列比较,如果大于等于中间节点,则跟后一半序列比较。

(2)代码:

function sort(arr){        for(var i = 1; i < arr.length; i++ ){           var pivot = arr[parseInt((i - 1) / 2 )];            var l;            if(arr[i] < pivot){l = 0;}else{l = pivot;}            for(var j = l; j < i; j ++ ){                if(arr[i] < arr[j]){                    var tmp = arr[i];                    arr[i] = arr[j];                    arr[j] = tmp;                }            }        }        return arr;    }    var arr = [3,5,7,2,1,5,8,9,67,4,3,90];    sort(arr);

(3)复杂度:

  • 时间复杂度:O(n方)因为移动次数没变。
  • 空间复杂度:O(1)

(4)稳定性:稳定排序。

3.希尔排序(最小增量排序法)

(1)思路:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

(2)代码:

 function sort(arr){        var step =parseInt((arr.length-1) / 2);        while(step >= 1){            for(var i = 0; i < arr.length; i++ ){                var j = i + step;                if(j < arr.length){                    if(arr[i] > arr[j]) {                        var tmp = arr[i];                        arr[i] = arr[j];                        arr[j] = tmp;                    }                }            }            step  -= 1;        }        return arr;    }    var arr = [3,5,7,2,1,5,8,9,67,4,3,90];    sort(arr);

(3)复杂度:

  • 时间复杂度:O(n的1.5方)据说它的时间复杂度是个争议
  • 空间复杂度:O(1)

(4)稳定性:不稳定排序。

{2,4,1,2},2和1一组4和2一组,进行希尔排序,第一个2和最后一个2会发生位置上的变化。

4.冒泡排序

(1)思路:反复扫描待排序序列,在扫描的过程中顺次比较相邻的两个元素的大小,若逆序就交换位置。第一趟,从第一个数据开始,比较相邻的两个数据,(以升序为例)如果大就交换,得到一个最大数据在末尾;然后进行第二趟,只扫描前n-1个元素,得到次大的放在倒数第二位。以此类推,最后得到升序序列。如果在扫描过程中,发现没有交换,说明已经排好序列,直接终止扫描。所以最多进行n-1趟扫描。

(2)代码:写了无数次不想再写了。任性。

(3)复杂度:

  • 时间复杂度:O(n方)
  • 空间复杂度:O(1)

(4)稳定性:稳定性排序

5.快速排序

(1)思路:冒泡排序一次只能消除一个逆序,为了能一次消除多个逆序,采用快速排序。以一个关键字为轴,从左从右依次与其进行对比,然后交换,第一趟结束后,可以把序列分为两个子序列,然后再分段进行快速排序,达到高效

(2)代码:

 function sort(arr,l,r){        var index = partation(arr,l,r);        if(l < index-1){            sort(arr,l,index-1);        }        if(index < r){            sort(arr,index,r);        }    }    function partation(arr,l,r){        var pivot = arr[parseInt((l+r)/2)];        while(l <= r){            while(arr[l] < pivot)l++;            while(arr[r] > pivot)r--;            if(l <= r){                var tmp = arr[l];                arr[l] = arr[r];                arr[r] = tmp;                l++;                r--;            }        }        return l;    }    var arr = [3,5,7,2,1,5,8,9,67,4,3,90];    sort(arr,0,arr.length-1);

(3)复杂度:

  • 时间复杂度:O(nlog(n))
  • 空间复杂度:O(log(n))

(4)稳定性:不稳定排序

6.简单选择排序

(1)思路:第一趟时,从第一个记录开始,通过n – 1次关键字的比较,从n个记录中选出关键字最小的记录,并和第一个记录进行交换。第二趟从第二个记录开始,选择最小的和第二个记录交换。以此类推,直至全部排序完毕。

(2)代码:不写了。任性

(3)复杂度:

  • 时间复杂度:O(n方)
  • 空间复杂度:O(1)

(4)稳定性:不稳定排序:{3, 3, 2}。

7.堆排序

(1)思路:把待排序记录的关键字存放在数组r[1…n]中,将r看成是一刻完全二叉树的顺序表示,每个节点表示一个记录,第一个记录r[1]作为二叉树的根,一下个记录r[2…n]依次逐层从左到右顺序排列,任意节点r[i]的左孩子是r[2i],右孩子是r[2i+1],双亲是r[i/2向下取整]。然后对这棵完全二叉树进行调整建堆。

(2)代码:

/*堆排序(大顶堆) 2011.9.14*/ #include <iostream>#include<algorithm>using namespace std;void HeapAdjust(int *a,int i,int size)  //调整堆 {    int lchild=2*i;       //i的左孩子节点序号     int rchild=2*i+1;     //i的右孩子节点序号     int max=i;            //临时变量     if(i<=size/2)          //如果i不是叶节点就不用进行调整     {        if(lchild<=size&&a[lchild]>a[max])        {            max=lchild;        }            if(rchild<=size&&a[rchild]>a[max])        {            max=rchild;        }        if(max!=i)        {            swap(a[i],a[max]);            HeapAdjust(a,max,size);    //避免调整之后以max为父节点的子树不是堆         }    }        }void BuildHeap(int *a,int size)    //建立堆 {    int i;    for(i=size/2;i>=1;i--)    //非叶节点最大序号值为size/2     {        HeapAdjust(a,i,size);        }    } void HeapSort(int *a,int size)    //堆排序 {    int i;    BuildHeap(a,size);    for(i=size;i>=1;i--)    {        //cout<<a[1]<<" ";        swap(a[1],a[i]);           //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面           //BuildHeap(a,i-1);        //将余下元素重新建立为大顶堆           HeapAdjust(a,1,i-1);      //重新调整堆顶节点成为大顶堆    }} int main(int argc, char *argv[]){     //int a[]={0,16,20,3,11,17,8};    int a[100];    int size;    while(scanf("%d",&size)==1&&size>0)    {        int i;        for(i=1;i<=size;i++)            cin>>a[i];        HeapSort(a,size);        for(i=1;i<=size;i++)            cout<<a[i]<<" ";        cout<<endl;    }    return 0;}

(3)复杂度:

  • 时间复杂度:O(nlog(n))
  • 空间复杂度:O(1)

(4)稳定性:不稳定排序:{3, 3, 2}。

8.归并排序

(1)思路:假设初始序列右n个记录,首先将这n个记录看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2向上取整 个长度为2(n为奇数时,最后一个序列的长度为1)的有序子序列。在此基础上,在对长度为2的有序子序列进行两两归并,得到若干个长度为4的有序子序列。如此重复,直至得到一个长度为n的有序序列为止。

(2)代码:

 function sort(arr,l,r){        if(l >= r)return;        var mid = parseInt((l+r)/2);        sort(arr,l,mid);        sort(arr,mid+1,r);        arr = merge(arr,l,r,mid);    }    function merge(arr,l,r,mid){        if(l >= r)return arr;        var tmp = [];        var leftP = l,rightP = mid + 1;        while((leftP <= mid) && (rightP <= r)){            if(arr[leftP] <= arr[rightP]){                tmp.push(arr[leftP]);                leftP++;            }else{                tmp.push(arr[rightP]);                rightP++;            }        }        while(leftP <= mid){tmp.push(arr[leftP]);leftP++;}        while(rightP <= r){tmp.push(arr[rightP]);rightP++;}        for(var i=l;i<=r;i++){arr[i] = tmp[i-l];}        return arr;    }    var arr = [3,5,7,2,1,5,8,9,67,4,3,90];    sort(arr,0,arr.length-1);

(3)复杂度:

  • 时间复杂度:O(nlog(n))
  • 空间复杂度:O(n)

(4)稳定性:稳定排序

二. 外部排序

(1)按可用内存的大小,把外存上含有n个记录的文件分成若干个长度为L的子文件,把这些子文件依次读入内存,并利用有效的内部排序方法对它们进行排序,再将排序后得到的有序子文件重新写入外存;

(2)对这些有序子文件逐趟归并,使其逐渐由小到大,直至得到整个有序文件为止。

0 0