C++排序算法

参考慕课陈越姥姥的数据结构课程。

参考博客

使用的交换函数

void swab(int array[], int index1, int index2)
{
    int tmp = array[index1];
    array[index1] = array[index2];
    array[index2] = tmp; 
}

void printArray(int array[], int length)
{
    for(int i=0; i<length; ++i)
        cout<<array[i]<<" ";
    cout<<endl;
}

1.冒泡排序

时间复杂度O(n^2), 每次比较相邻的两个元素,将最大的元素后移

void bubbleSort(int arr[], int length)
{
    for(int i=0; i<length; ++i)
    {
        for(int j=0; j<length-1; ++j)
        {
            if(arr[j]>arr[j+1])
                swab(arr, j, j+1);
        }
    }
}

对于可能存在部分排序好的序列,可以优化为

void bubbleSort2(int arr[], int length)
{
    int flag = 0;
    for(int i=0; i<length; ++i)
    {
        for(int j=0; j<length-1; ++j)
        {
            if(arr[j]>arr[j+1])
            {
                swab(arr, j, j+1);
                flag=1;
            }
        }
        if(!flag)
            break;
    }
}

2.选择排序

时间复杂度O(n^2), 数组前半部分为已排序好的,每次选出未排序数组的最小值放在已排序数组的最后。

void selectionSort(int arr[], int length)
{
    for(int i=0; i<length; ++i)
    {
        int min_idx = i;
        for(int j=i+1; j<length; ++j)
        {
            if(arr[j]<arr[min_idx])
            {
                min_idx = j;
            }
        }
        swab(arr, i, min_idx);
    }
}

3.插入排序

时间复杂度O(n^2), 数组的前半部分为已排序数组,后半部分为未排序数组,针对未排序数组,依次取出,插入在排序数组中合适的位置。和选择排序的区别:选择排序每次选出未排序数组的最小元素作为已排序数组的最大值,插入在其最后;插入排序则是从未排序数组中依次取出,然后在排序数组中寻找合适位置插入。

void insertSort(int arr[], int length)
{
    for(int i=1; i<length; ++i)
    {
        for(int j=i-1; j>=0; --j)
        {
            if(arr[j+1]<arr[j])
                swab(arr, j+1, j);
            else
                break;
        }
    }
}

4.希尔排序

时间复杂度O(n^3/2),在插入排序的基础上优化,采用跳跃式插入排序。

void shellSort(int arr[], int length)
{
    for(int D=length/2; D>0;D/=2)
    {
        for(int i=D; i<length; ++i)
        {
            for(int j=i-D; j>=0; j-=D)
            {
                if(arr[j+1]<arr[j])
                    swab(arr, j+1, j);
                else
                    break;
            }
        }
    }
}

5.堆排序

时间复杂度O(nlogn),采用最大堆的方式。

void heapCore(int arr[], int length, int parent)
{
    if(parent>length)
        return ;
    int l_node = 2*parent + 1;
    int r_node = 2*parent + 2;
    int maxIdx = parent;
    if(l_node<length&&arr[l_node]>arr[maxIdx])
        maxIdx = l_node;
    if(r_node<length&&arr[r_node]>arr[maxIdx])
        maxIdx = r_node;
    if(maxIdx!=parent)
    {
        swab(arr, maxIdx, parent);
        heapCore(arr, length, maxIdx);
    }
}

void buildHeap(int arr[], int length)
{
    for(int i=(length-1)/2; i>=0; --i)
    {
        heapCore(arr, length, i);
    }
}

void heapSort(int arr[], int length)
{
    buildHeap(arr, length);
    for(int i=length-1; i>=0; --i)
    {
        swab(arr, i, 0);
        heapCore(arr, i, 0);
    }
}

6.归并排序

时间复杂度O(nlogn),分而治之的思想,递归的方法。

void merge(int arr[], int start, int end, int* res)
{
    int length = end-start+1;
    int lStart = start, rStart = length/2 + start;
    int resStart = start;
    while (lStart<=start+length/2-1&&rStart<=end)
    {
        if(arr[lStart]>arr[rStart])
        {
            res[resStart++] = arr[rStart++];
        }
        else
        {
            res[resStart++] = arr[lStart++];
        }
    }
    while(lStart<=start+length/2-1)
        res[resStart++] = arr[lStart++];
    while(rStart<=end)
        res[resStart++] = arr[rStart++];
    for(int i=start; i<=end; ++i)
        arr[i] = res[i];
}

void mergeSortCore(int arr[], int start, int end, int* res)
{
    if(end==start)
        return ;
    mergeSortCore(arr, start, (end+start)/2, res);
    mergeSortCore(arr, (end+start)/2+1, end, res);
    merge(arr, start, end, res);
}

void mergeSort(int arr[], int length)
{
    int* res = new int[length];
    mergeSortCore(arr, 0, length-1, res);
    delete [] res;
}

7.快速排序

时间复杂度O(nlogn),每次将一个元素排在正确的位置上。

int part(int arr[], int start, int end)
{
	int baseIdx = start;
	while (start < end)
	{
		while (start<end&&arr[end]>arr[baseIdx])
			--end;
		while (start < end&&arr[start] <= arr[baseIdx])
			++start;
		swab(arr, start, end);
	}
	swab(arr, start, baseIdx);
	return start;

}
void qucikSortCore(int arr[], int start, int end)
{
    if(start<end)
    {
        int base = part(arr, start, end);
        qucikSortCore(arr, start, base-1);
        qucikSortCore(arr, base+1, end);
    }
}
void quickSort(int arr[], int length)
{
    qucikSortCore(arr, 0, length-1);
}

8.桶排序

时间复杂度O(n),当数组的范围很大时, 需要开辟很大额外空间。适用于数组的范围比较小的时候。

void bucketSort(int arr[], int length)
{
    int* tmp = new int[length+1];
    memset(tmp, 0, sizeof(tmp)*(length+1));
    for(int i=0; i<length; ++i)
    {
        ++tmp[arr[i]];
    }
    int idx=0;
    for(int i=0; i<length;++i)
    {
        while(tmp[i]>0)
        {
            arr[idx++] = i;
            --tmp[i];
        }
    }
    delete [] tmp;
}

 9.基数排序

时间复杂度P(N+B), 在桶排序的基础上优化,P为排序的趟数,N为数字的个数, B为桶的个数。

基数排序分为次位优先(Least Significant Digit, LSM)和主位优先(Main Significant Digit, MSD)。适用于数组比较小,但范围比较大的时候。

int findMax(int arr[], int length)
{
    int max = arr[0];
    for(int i=1;i<length;++i)
        if(arr[i]>max)
            max=arr[i];
    return max;
}

void radixSort(int arr[], int length)
{
    int radix=10;
    int max = findMax(arr, length);
     for(int i=1; max>0; i*=10, max/=10)
    {
        vector<int>* bucket = new vector<int> [length];
        for(int j=0;j<length;++j)
        {
            bucket[(arr[j]/i)%10].push_back(arr[j]); 
        }
        int k=0;
        for(int j=0; j<10; ++j)
        {
            for(int m=0; m<bucket[j].size(); ++m)
                arr[k++] = bucket[j][m];
        }
        delete bucket;
    }
}

排序时间比较

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中有许多不同的排序算法,包括冒泡排序、选择排序、插入排序、快速排序、希尔排序、归并排序等等。以下是其中一些算法的实现示例: 1. 冒泡排序 ``` void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n - 1; i++) for (j = 0; j < n - i - 1; j++) if (arr[j] > arr[j+1]) swap(arr[j], arr[j+1]); } ``` 2. 选择排序 ``` void selectionSort(int arr[], int n) { int i, j, min_idx; for (i = 0; i < n - 1; i++) { min_idx = i; for (j = i+1; j < n; j++) if (arr[j] < arr[min_idx]) min_idx = j; swap(arr[min_idx], arr[i]); } } ``` 3. 插入排序 ``` void insertionSort(int arr[], int n) { int i, key, j; for (i = 1; i < n; i++) { key = arr[i]; j = i - 1; while (j >= 0 && arr[j] > key) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } } ``` 4. 快速排序 ``` int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { i++; swap(arr[i], arr[j]); } } swap(arr[i+1], arr[high]); return i + 1; } void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } ``` 5. 归并排序 ``` void merge(int arr[], int l, int m, int r) { int n1 = m - l + 1; int n2 = r - m; int L[n1], R[n2]; for (int i = 0; i < n1; i++) L[i] = arr[l + i]; for (int j = 0; j < n2; j++) R[j] = arr[m + 1 + j]; int i = 0, j = 0, k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } } void mergeSort(int arr[], int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); merge(arr, l, m, r); } } ``` 这些排序算法在实际应用中都有不同的优缺点,需要根据实际情况选择合适的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值