【C++】冒泡、选择、插入、希尔、堆、快速排序

sort(vc.begin(),vc.end(),布尔函数名称);//  <-这是永远的神 
/*布尔函数是两个值,的比较函数,返回布尔即可*/
/*例:
bool judge(int a,int b){
	return a>b;
}
*/

冒泡排序

童子功无需多言,可以说是代码量最少的排序了

void bubbleSort(int arr[], int len) //冒泡排序
{
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j + 1]);
        }
    }
}

选择排序

从最小的位置开始排起,利用打擂法(用第一个元素和其他元素依次比较),每次确定1个最小值

void selectionSort(int arr[], int len)//选择排序
{
    for (int i = 0; i < len; i++)
    {
        int minPos = i;
        int min = arr[i];
        for (int j = i + 1; j < len; j++)
        {
            if (arr[j] < min)
            {
                minPos = j;
                min = arr[j];
            }
        }
        swap(arr[minPos], arr[i]);
    }
}

插入排序

默认第0个已经入列。之后的1,2,3…依次与左边的元素比较,找到自己的位置,插入这个创建的有序序列

void insertSort(int arr[], int len)//插入排序
{
    for (int i = 1; i < len; i++)
    {
        int temp = arr[i];
        int j = i;
        /*在arr[i]左边的元素,都要和arr[i]比一次,每比一次就交换,如果比到了位置就停 两种情况:找到了比自己小的,或者到了最前面 */

        while (arr[j - 1] > temp && j >= 1)
        {
            swap(arr[j - 1], arr[j]);
            j--;
        }
    }
}

希尔排序

高配版插入排序

分批次,多进行几次插入排序,每次间隔并非1,而是选择一个增量

void shellSort(int arr[], int len)//希尔排序
{
    //希尔排序的增量
    int d = len;
    while (d > 1)
    {
        d = d / 2;//每次除以2,到1停止
        for (int i = d; i < len; i += d)
        {
            int temp = arr[i];
            int j = i;
            while (arr[j - d] > temp && j >= d)
            {
                swap(arr[j - d], arr[j]);
                j -= d;
            }
        }
    }
}

堆排序

利用了大根堆(二叉树的一种)。每次排出根(最大值)来,然后放到最后不管。每次必找到一个最大值的位置。

void heapSort_heapify(int arr[], int n, int parent) //n为结点个数(数组长度),parent为临时父节点
{
    if (parent >= n)
        return;

    int leftChild = 2 * parent + 1;
    int rightChild = 2 * parent + 2;
    //注意:先排自己的 左子树 和 右子树,最后排自己
    if (leftChild < n)
        heapSort_heapify(arr, n, leftChild);

    if (rightChild < n)
        heapSort_heapify(arr, n, rightChild);
    //两次交换,保证父结点必拿到最大值
    if (leftChild < n && arr[parent] < arr[leftChild])
        swap(arr[parent], arr[leftChild]);

    if (rightChild < n && arr[parent] < arr[rightChild])
        swap(arr[parent], arr[rightChild]);
}
void heapSort(int arr[], int len)
{
    for (int i = 0; i < len; i++)
    {
        heapSort_heapify(arr, len - i, 0); //从根 0 开始,建立大根堆
        swap(arr[0], arr[len - 1 - i]);    //每次大根堆的第一位和最后一位交换
    }
}

快速排序

选 基准数,然后两侧哨兵,右往左移动,左往右移动。

每一次哨兵碰头,基准数移到中间。 保证基准数左边都是小数,右边都是大数,

至少确定了一个基准数的位置

之后分成两组,递归来如法炮制

中间需 时刻 检测哨兵是否碰面,多两个参数方便进行递归调用。

void quickSort(int arr[], int left, int right) //快速排序
{//注意,用 左1 为基准数的话,要先让右哨兵开始移动,不然左哨兵会移动过大
    if (left >= right)
        return;
    int i = left;
    int j = right;
    const int &base = arr[left];//base仅用于比较,用const限定防止误操作,引用是减少内存空间的使用,更加快速
    while (i < j)
    {
        while (i < j && arr[j] >= base) //移动右哨兵寻找
            j--;
        while (i < j && arr[i] <= base) //移动左哨兵寻找
            i++;
        if (i < j) //没走多,就表明 左右 找到了,交换。 走多了,就是没找到
            swap(arr[i], arr[j]);
    }
    swap(arr[left], arr[i]);
    quickSort(arr, left, i - 1);
    quickSort(arr, i + 1, right);
}

测试代码

#include <bits/stdc++.h>
using namespace std;


void bubbleSort(int arr[], int len) //冒泡排序
{
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j + 1]);
        }
    }
}


void selectionSort(int arr[], int len)//选择排序
{
    for (int i = 0; i < len; i++)
    {
        int minPos = i;
        int min = arr[i];
        for (int j = i + 1; j < len; j++)
        {
            if (arr[j] < min)
            {
                minPos = j;
                min = arr[j];
            }
        }
        swap(arr[minPos], arr[i]);
    }
}


void insertSort(int arr[], int len)//插入排序
{
    for (int i = 1; i < len; i++)
    {
        int temp = arr[i];
        int j = i;
        /*在arr[i]左边的元素,都要和arr[i]比一次,每比一次就交换,如果比到了位置就停 
        两种情况:1.找到了比自己小的
        		2.或者到了最前面 */

        while (arr[j - 1] > temp && j >= 1)
        {
            swap(arr[j - 1], arr[j]);
            j--;
        }
    }
}


void shellSort(int arr[], int len)//希尔排序
{
    //希尔排序的增量
    int d = len;
    while (d > 1)
    {
        d = d / 2;//每次除以2,到1停止
        for (int i = d; i < len; i += d)
        {
            int temp = arr[i];
            int j = i;
            while (arr[j - d] > temp && j >= d)
            {
                swap(arr[j - d], arr[j]);
                j -= d;
            }
        }
    }
}


void quickSort(int arr[], int left, int right) //快速排序
{//注意,用左1为基准数的话,要先让右哨兵开始移动,不然左哨兵会移动过大
    if (left >= right)
        return;
    int i = left;
    int j = right;
    const int &base = arr[left];
    while (i < j)
    {
        while (i < j && arr[j] >= base) //移动右哨兵寻找
            j--;
        while (i < j && arr[i] <= base) //移动左哨兵寻找
            i++;
        if (i < j) //没走多,就表明找到了,交换。走多了,就是没找到
            swap(arr[i], arr[j]);
    }
    swap(arr[left], arr[i]);
    quickSort(arr, left, i - 1);
    quickSort(arr, i + 1, right);
}

void print(int arr[], int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << arr[i] << ' ';
    }
}
int main()
{

    //srand((unsigned)time(NULL)); //加上这行,每次运行的时候就以当前时间为种子初始化随机数
    int arr[20];
    for (int i = 0; i < 20; i++)
    {
        arr[i] = rand() % 30; //测试数据,伪随机数或者真随机数
        //cin>>arr[i];          //用户输入
    }
    //排序前
    print(arr, 20);

    //排序后
    // bubbleSort(arr, 20);
    selectionSort(arr, 20);
    // shellSort(arr, 20);
    // quickSort(arr, 0, 19);
    cout << endl;
    print(arr, 20);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值