面试排序算法总结

来源:互联网 发布:java中单例设计模式 编辑:程序博客网 时间:2024/05/21 22:37

直接插入排序

从第二个元素开始,每次选择一个元素插入到之前已经排好序的部分。
选择插入位置的时候从后往前,将带插入元素取出,依次后移大于带插入元素的数。
算法复杂度:
最好是正序有序,需要n次比较。
最差逆序有序,复杂度O(n2)
平均复杂度O(n2)
插入排序是稳定的

void insertsort(int a[],int size){    int tmp;    for(int i = 1; i < size; ++i){        tmp = a[i];        int j = i-1;        while(j>=0&&a[j]>a[i]){            a[j+1] = a[j];            j--;        }        a[j+1] = tmp; //最后j位置数小于带插入的数,在j+1位置插入数    }}

希尔排序

实际也是一组插入排序,只不过是分组插入排序。给定增量值d,将序列分为d个子序列,先插入排序子序列,最后对全部序列进行 一次插入排序。
也就是增量值必须取小于n的值,且最后一个增量必须为1。
由于大于1的增量,排序是不稳定的。
平均复杂度:O(nlogn)

void shellsort(int a[],int size){    int d,i,j;    int tmp; //暂存数据    d = n/2;    while(d>0){        for(i = d; i < size; ++i){            j = i-d;            tmp = a[i];            while(j>=0 && a[j] > tmp){                a[j+d] = a[j];                j -= d;            }            a[j+d] = tmp;        }        d /= 2;    }}

快速排序

对冒泡排序的一种改进,基于交换
算法复杂度在最坏情况下为O(n2),平均为O(nlogn)
同时快排是不稳定的

void quicsort(int a[],int low,int high){    if(low>=high) return;    int i = low, j = high;    int tmp = a[i];    while(i<j){        while(i<j && a[j] > tmp) j--;        if(i<j) a[i++] = a[j];        while(i<j && a[i] < tmp) i++;        if(i<j) a[j--] = a[i];    }    a[i] = tmp;    quicksort(a,low,i-1);    quicksort(a,i+1,high);}

选择排序

排序不稳定

void selectsort(int a[],int size){    int tmp,k;    for(int i = 0; i < size-1; ++i){        tmp = a[i];        k = i;        for(int j = i+1; j < size; ++j){            if(a[j] < tmp){                tmp = a[j];                k = j;            }        }        if(k != i) swap(a[i],a[k]);    }}

堆排序

  1. 在数组中建堆
  2. 从最后一个非叶节点进行调整
  3. 将堆顶元素与最后的元素交换,然后调整堆。
    复杂度为:O(nlogn)
void heapAdjust(int a[],int i,int size){    int tmpMin = a[i];    for(int j = i*2+1; j < size; j = j*2+1){        if(j<size-1&&a[j+1]<a[j]) j += 1;        if(a[i] < a[j]) break;        a[i] = a[j];        i = j;    }}void buildHeap(int a[],int size){    for(int i = size/2+1; i >= 0; --i){        heapAdjust(a,i,size);    }}void heapsort(int a[],int size){    buildHeap(a,size);    for(int i = size-1; i > 0; --i){        swap(a[0],a[i]);        heapAdjust(a,0,i);    }}

归并排序

归并排序是稳定排序,复杂度为O(nlogn),缺点是需要额外的O(n)空间

void merge(int a[], int tmp[],int left,int mid, int right) {    int i = left, j = mid+1;    int k = i;    while (i <= mid && j <= right) {        if (a[i] < a[j]) {            tmp[k++] = a[i++];        }        else {            tmp[k++] = a[j++];        }    }    while (i <= mid) tmp[k++] = a[i++];    while (j <= right) tmp[k++] = a[j++];    for (int p = left; p <= right; p++) {        a[p] = tmp[p];    }}void m_sort(int a[],int tmp[],int left,int right) {    if (left == right) return;    int mid = (left + right) / 2;    m_sort(a, tmp,left, mid);    m_sort(a,tmp, mid + 1, right);    merge(a, tmp,left, mid,right);}void mergesort(int a[], int size) {    int *tmp = new int[size];    m_sort(a, tmp, 0, size - 1);    delete[]tmp;}
0 0
原创粉丝点击