Java教程

常用排序算法及其复杂度

本文主要是介绍常用排序算法及其复杂度,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

冒泡排序(BubbleSort)

void BubbleSort(int arr[], int len)
{
    if (arr == NULL || len == 0) return;
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                arr[j] = arr[j] ^ arr[j + 1];
                arr[j + 1] = arr[j] ^ arr[j + 1];
                arr[j] = arr[j] ^ arr[j + 1];
            }
        }
    }
}

选择排序(SelectSort)

遍历一遍数据,找到最小值或最大值放入相应位置上

  • 设a[0]为最小值,遍历数组,与最小值比较,找到数组最小值,记录下标,与数组a[0]元素交换,重复过程

代码

void SeclectSort(int arr[],int n)
{
    int MinIndex=0;
    int k = 0;
    if (arr == NULL || n <= 0)
        return;
    for (int i = 0; i < n; i++)
    {
        MinIndex = i;
        for (int j = i + 1; j < n; j++)
        {
            if (arr[j] < arr[MinIndex])
                MinIndex = j;
        }
        swap(arr[i], arr[MinIndex]);
    }
}

插入排序(InsertSort)

将待排序的数据分成两部分,一部分有序,一部分无序,将无序的元素依次插入到有序中

代码

void InsertSort(int arr[], int n)
{
    if (arr == NULL || n == 0) return;
    int i, j, temp;
    for (int i = 1; i < n; i++)
    {
        temp = arr[i];
        j = i - 1;
        while (temp < arr[j] && j >= 0)
        {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = temp;
    }
}

快速排序(QuickSort)

找一个标准值,比标准值小的放到其左侧,大的放在右侧,左右两半部分分别重复以上操作

int Sort(int arr[], int low, int high)
{
    if (arr == NULL || sizeof(arr)/sizeof(*arr)==0 ) return;
    int pivot = arr[low];
    while (low < high)
    {
        while (low<high && arr[high]>=pivot)
        {
            high--;
        }
        arr[low] = arr[high];
        while (low < high && arr[low] <= pivot)
        {
            low++;
        }
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    return low;
}
​
void QuickSort(int arr[], int low,int high)
{
    if (low < high)
    {
        int pivot = Sort(arr, low, high);
        QuickSort(arr, low, pivot - 1);
        QuickSort(arr, pivot+1, high);
    }
}

堆排序(HeapSort)

大堆:父亲的值比孩子大

小堆:父亲的值比孩子小

void MaxHeapfy(int arr[],int dad, int len)
{
    int son = 2 * dad + 1;
    if (arr == NULL || len == 0) return;
    while (son < len)
    {
        if (son + 1 < len && arr[son + 1] > arr[son]) son++;
        if (arr[dad] > arr[son]) return;
        else
        {
            swap(arr[son], arr[dad]);
            dad = son;
            son = 2 * dad + 1;
        }
    }
}
​
void HeapSort(int arr[], int len)
{
    for (int i = len / 2 - 1; i >= 0; i--)
    {
        MaxHeapfy(arr, i, len);
    }
    for (int i = len - 1; i > 0; i--)
    {
        swap(arr[0], arr[i]);
        len--;
        MaxHeapfy(arr,0 ,i);
    }
}

希尔排序(ShellSort)

数据分组,各组内插入排序

void ShellSort(int arr[], int len)
{
    if (arr == NULL || len == 0) return;
    for (int gap = len / 2; gap > 0; gap /= 2)
    {
        for (int i = gap; i < len; i++)
        {
            int temp = arr[i];
            int j = i - gap;
            while (j >= 0 && temp < arr[j])
            {
                arr[j + gap] = arr[j];
                j = j - gap;
            }
            arr[j + gap] = temp;
        }
    }
}

归并排序(MergeSort)

将多个有序数组进行合并

void Merge(int arr[], int l,int r)
{
    int mid = l + (r - l) / 2;
    int p0 = 0;
    int p1 = l;
    int p2 = mid + 1;
    int* aux = new int[r-l+1];
    while (p1 <= mid && p2 <= r)
    {
        if (arr[p1] < arr[p2])
            aux[p0++] = arr[p1++];
        else
            aux[p0++] = arr[p2++];
    }
    while (p1 <= mid)
        aux[p0++] = arr[p1++];
    while (p2 <= r)
        aux[p0++] = arr[p2++];
    for (int i = 0; i < p0; i++)
        arr[i + l] = aux[i];
    delete[] aux;
}
​
void MergeSort(int arr[], int l, int r)
{
    if (arr == NULL || l >= r) return;
    int mid = l + (r - l) / 2;
    MergeSort(arr, l, mid);
    MergeSort(arr, mid + 1, r);
    Merge(arr, l,r);
}

基数排序(RadixSort)

不基于比较的排序

只能用于非负数排序

LSD :低位优先

MSD:高位优先

int GetMax(int arr[], int len)
{
    int Maxval = *max_element(arr, arr + len);
    int Maxbit = 0;
    while (Maxval>0)
    {
        Maxval /= 10;
        Maxbit++;
    }
    return Maxbit;
}
​
void RadixSort(int arr[], int len)
{
    int n = GetMax(arr, len);
    int* count = new int[10];
    int* temp = new int[len];
    int radix = 1;
    for (int i = 0; i < n; i++)
    {
        for (int i = 0; i < 10; i++)
            count[i] = 0;
        for (int i = 0; i < len; i++)
        {
            count[(arr[i] / radix) % 10]++;
        }
        for (int i = 1; i < 10; i++)
        {
            count[i] += count[i - 1];
        }
        for (int i = len - 1; i >= 0; i--)
        {
            temp[count[(arr[i] / radix) % 10] - 1] = arr[i];
            count[(arr[i] / radix) % 10]--;
        }
        for (int i = 0; i < len; i++)
        {
            arr[i] = temp[i];
        }   
        radix *= 10;
    }
    delete[] count;
    delete[] temp;
}

桶排序(BucketSort)

void BucketSort(int arr[], int len)
{
    int Maxval = *max_element(arr, arr + len);
    int Minval = *min_element(arr, arr + len);
    int bucket = len;
    int gap = (Maxval - Minval) / (bucket - 1);
    vector<int>* aux = new vector<int>;
    vector<list<int>> vec ;
    vector<int>* sorted = new vector<int>;
    vec.resize(bucket);
    for (int i = 0; i < len; i++)
    {
        int index = (arr[i] - Minval) / gap;
        vec.at(index).push_back(arr[i]);
    }
    for (int i=0;i<vec.size();i++)
    {
        aux->assign(vec[i].begin(), vec[i].end());
        sort(aux->begin(), aux->end());
        sorted->insert(sorted->end(), aux -> begin(), aux->end());
    }
    for (int i = 0; i < len; i++)
        arr[i] = sorted->at(i);
    delete aux;
    delete sorted;
​
}

排序比较

排序名称最好时间复杂度平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序O(n)O(n^2)O(n^2)O(1)
选择排序O(n^2)O(n^2)O(n^2)O(1)
插入排序O(n)O(n^2)O(n^2)O(1)
快速排序O(nlogn)O(nlogn)O(n^2)O(logn)
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)
希尔排序-O(n^1.3)-O(1)
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)
基数排序O(d(n+r))O(d(n+r))O(d(n+r))O(r)
桶排序O(n)O(n)O(n^2)O(n+m)
这篇关于常用排序算法及其复杂度的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!