排序算法——交换排序

一、排序的概念

排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序,若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。本文所介绍的是内部排序。
二、插入排序

1、概念

  1. 思路:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
  2. 分类:冒泡排序、快速排序

2、冒泡排序

冒泡排序:冒泡排序是一种稳定排序算法, 其平均时间复杂度为O(n^2)。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

思路

  1. 比较相邻元素,如果前面比后面的大,就交换他们。
  2. 对每一对相邻元素进行①操作,从第一对到最后一对。因为每次交换都把较大的一个放到后面,所以最后的元素应该会是最大的数。
  3. 对除了最后一个之外的所有元素重复以上的步骤,因为最后一个元素是最大的不需要进行交换了。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

代码如下:

#include <iostream>

using namespace std;

// 冒泡排序,每次从前往后走将最大的内容放到最后面。
void bubbleSort(int numArray[], int sum){
    // 每完成一次冒泡排序操作,endIndex处的内容就已经是最小的,所以结束后endIndex--。
    for(int endIndex = sum - 1; endIndex > 0; endIndex--){
        // 每次遇到对比当前位置和后一个位置内容,如果当前的大就进行交换。
        for(int index = 0; index < endIndex; index++){
            if(numArray[index] > numArray[index+1]){
                swap(numArray[index], numArray[index+1]);
            }
        }
    }
}

int main(){
    int sum = 11;
    int arr[100] = {45,10,25,1,9,56,99,100,3,120, 99};
    cout << "排序前:";
    for(int i = 0; i < sum; i++)
        cout << arr[i]<< " ";
    cout << "\n";
    bubbleSort(arr, sum);
    cout << "排序后:";
    for(int i = 0; i < sum; i++)
        cout << arr[i]<< " ";
    cout << "\n";
    return 0;
}

2、快速排序

快速排序:快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1960年提出。快速排序的平均时间复杂度也是O(nlog2n)。尽管快速排序只需要一个元素的辅助空间,但快速排序需要一个栈空间来实现递归。最好的情况下,即快速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度为log2(n+1);但最坏的情况下,栈的最大深度为n。快速排序的空间复杂度为O(log2n)。

思路:过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

理解有问题的小伙伴可以看一下这篇文章:https://blog.csdn.net/qq_28584889/article/details/88136498

示例
在这里插入图片描述
代码如下

#include <iostream>

using namespace std;

// 使用array[left]作为哨兵,负责记录分割的值。
int qSort(int numArray[], int left, int right){
    int pos = left + 1; // 存放当前比key小的最后一个值的下一个位置
    int mid = (right + left) / 2; // 获得key的位置
    swap(numArray[mid], numArray[left]);
    // 因为left位置被作为哨兵,所以从left+1开始
    for(int index = left + 1; index <= right; index++){
    	// 遇到比key小的内容就放到pos位置上,并使pos++。
        if(numArray[index] < numArray[left])
            swap(numArray[index], numArray[pos++]);
    }
    // 将哨兵和最后一个比key小的元素交换位置,至此0~pos-1全部是比key小的内容
    swap(numArray[pos - 1], numArray[left]);
    return pos;
}

void quickSort(int numArray[], int left, int right){
	// 当下面条件满足时说明不需要再排序了。
    if(left >= right)
        return;
    // 将数组分成两份(左面比分割点小,右面大于等于分割点)并返回分割点位置
    int mid = qSort(numArray, left, right);
    quickSort(numArray, 0, mid - 1); // 对左面部分再进行排序
    quickSort(numArray, mid, right); // 对右面部分再进行排序
}

int main(){
    int sum = 11;
    int arr[100] = {45,10,25,1,9,56,99,100,3,120, 99};
    cout << "排序前:";
    for(int i = 0; i < sum; i++)
        cout << arr[i]<< " ";
    cout << "\n";
    quickSort(arr, 0, sum-1);
    cout << "排序后:";
    for(int i = 0; i < sum; i++)
        cout << arr[i]<< " ";
    cout << "\n";
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值