排序(一):选择排序、冒泡排序、插入排序、希尔排序

一、排序分析:
1、选择排序
时间复杂度:O(n^2)
空间复杂度:O(1)
算法稳定性:不稳定(即有跳跃式交换)
这里写图片描述

//先确定最小元素(由前至后)
//默认开始时0号下标对应元素为最小值
//依次将当前i下标对应的元素与其之后的各元素j进行比较
//若j号下标对应的元素比当前默认最小值还要小,则交换
void SelectSort(int *arr, int len)//选择排序
{
    int min = 0;
    for(int i = 0; i < len-1; i++)
    {
        min = i;
        for(int j = i + 1; j < len; j++)
        {
            if(arr[j] < arr[min])
            {
                Swap(arr, j, min);
            }
        }
    }
}

2、冒泡排序
时间复杂度:O(n^2)
空间复杂度:O(1)
算法稳定性:稳定
这里写图片描述

//先确定最大值(由后至前)
//将最小值冒出,最大值沉底
//总循环len-1趟; 每趟比较(len-1)-i 次
//比较:将当前元素j与其后紧邻的元素j+1进行比较,若j较大,则交换;否则j++
void BubbleSort(int *arr, int len)//冒泡排序
{
    bool swap = false;
    for(int i = 0; i < len-1; i++)
    {
        swap = false;
        for(int j = 0; j < len-1-i; j++)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
                swap = true;
            }
        }
        //优化
        if(!swap)
        {
            return;
        }
    }
}

3、插入排序
时间复杂度:O(n^2)—有序—->O(n)
空间复杂度:O(1)
算法稳定性:稳定
这里写图片描述

//相当于将较大元素后移一位,插入较小元素至合适位置
//默认开始时0号下标元素有序,从1号下标开始排序
//tmp保存当前i指向元素,分别与i之前的元素j进行比较
//比较:若j大,则j将j+1号的元素覆盖,j--; 反之,仅j--继续比较
//每趟循环比较结束后:将tmp 赋给j+1号元素;且当前i之前的元素均有序
void InsertSort(int *arr, int len)//直接插入排序
{
    int tmp = 0;
    int j = 0;
    for(int i = 1; i < len; i++)
    {
        tmp = arr[i];
        for(j = i-1; j >= 0; j--)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
            }
            else
            {
                break;
            }
        }
        arr[j+1] = tmp;
    }
}

4、希尔排序
时间复杂度:O(n^1.3)-O(n^1.5)
空间复杂度:O(1)
算法稳定性:不稳定(即有跳跃式交换)
这里写图片描述

//递减增量排序(区域内有序->区域间有序->整体有序)
//增量:素数,且最后必须递减为1
//用于将所有元素划分不同增量块区域(跳跃式划分的,区域内各元素间隔当前增量,不连续);
//分别进行插入排序,使元素可以一次性的朝最终位置前进一大步,从而快速趋于有序;
//再通过增量递减使元素移动步长减小,直至完全有序。
//  1、得到当前增量大小,即将所有元素划分了当前增量块区域;
//  2、循环当前增量次数,对各区域元素进行插入排序
//  3、增量递减,重复上述两步,直至增量递减为1排序完成后结束
//希尔排序
void ShellSort(int *arr, int len)//初始化增量
{
    int drr[] = {5,3,1};
    int len_d = sizeof(drr) / sizeof(drr[0]);
    for(int i = 0; i < len_d; i++)
    {
        Shell(arr, len, drr[i]);
    }
}

void Shell(int *arr, int len, int gap)//对各增量区域进行插入排序
{
    int tmp = 0;
    int j = 0;
    for(int i = gap; i < len; i++)
    {
        tmp = arr[i];
        for(j = i-1; j >= 0; j--)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
            }
            else
            {
                break;
            }
        }
        arr[j+1] = tmp;
    }
}

二、代码实现:

#include<stdio.h>
#include"Sort.h"

static void Swap(int *arr, int i, int j)
{
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

void SelectSort(int *arr, int len)//选择排序
{
    int min = 0;
    for(int i = 0; i < len-1; i++)
    {
        min = i;
        for(int j = i + 1; j < len; j++)
        {
            if(arr[j] < arr[min])
            {
                Swap(arr, j, min);
            }
        }
    }
}

void BubbleSort(int *arr, int len)//冒泡排序
{
    int tmp = 0;
    bool swap = false;
    for(int i = 0; i < len-1; i++)
    {
        swap = false;
        for(int j = 0; j < len-1-i; j++)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
                swap = true;
            }
        }
        //优化
        if(!swap)
        {
            return;
        }
    }
}

void InsertSort(int *arr, int len)//直接插入排序
{
    int tmp = 0;
    int j = 0;
    for(int i = 1; i < len; i++)
    {
        tmp = arr[i];
        for(j = i-1; j >= 0; j--)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
            }
            else
            {
                break;
            }
        }
        arr[j+1] = tmp;
    }
}

//希尔排序
void ShellSort(int *arr, int len)//初始化增量
{
    int drr[] = {5,3,1};
    int len_d = sizeof(drr) / sizeof(drr[0]);
    for(int i = 0; i < len_d; i++)
    {
        Shell(arr, len, drr[i]);
    }
}
void Shell(int *arr, int len, int gap)//对各增量区域进行插入排序
{
    int tmp = 0;
    int j = 0;
    for(int i = gap; i < len; i++)
    {
        tmp = arr[i];
        for(j = i-1; j >= 0; j--)
        {
            if(arr[j] > arr[j+1])
            {
                Swap(arr, j, j+1);
            }
            else
            {
                break;
            }
        }
        arr[j+1] = tmp;
    }
}

void Show(int *arr, int len)
{
    for(int i = 0; i < len; i++)
    {
        printf("%d  ", arr[i]);
    }
    printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值