选择排序,冒泡排序,直接插入排序,shell排序

一、选择排序:
时间复杂度:无序O(n^2) 有序O(n)
空间复杂度:O(1)
算法稳定性:不稳定(相同数值都交换了)
原理:选择一个值arr[0]作为标杆,然后循环找到除这个值外最小的值(查找小于标杆的最小值),
交换这两个值,这时最小值就被放到了arr[0]上,然后再将arr[1]作为标杆,从剩下未排序的值中找到最小值,
并交换这两个值。
例:4 1 5 12 0
第一趟:1 4 5 12 0->0 4 5 12 1
第二趟:0 1 5 12 4
第三趟:0 1 4 12 5
第四趟:0 1 4 5 12

void Select_Sort(int *arr, int len)
{
    int i, j;
    int min, tmp;
    for (i = 0; i < len; i++)
    {
        min = i;//i++后标杆位置后移
        for (j = i + 1; j < len; j++)
        {
            if (arr[j] < arr[min])//j往后走比较arr[j]与arr[min]标杆的大小,使标杆处是最小的值。
            {
                tmp = arr[j];
                arr[j] = arr[min];
                arr[min] = tmp;
            }
        }
    }
}

二、冒泡排序:挨个挨个去比较
时间复杂度:O(n^2)
空间复杂度:O(1)
算法稳定性:稳定
原理:从数组的第一个位置开始两两比较arr[j]和arr[j+1],
如果arr[j]大于arr[j+1]则交换他两个的位置,直到数组结束;
从数组的第一个位置开始,重复上面的动作,止到数组长度减一个位置结束;
从数组的第一个位置开始,重复上面的动作,止到数组长度减二个位置结束;
例:4 1 5 12 0
第一趟:1 4 5 0 12 i=0 j<4
第二趟:1 4 0 5 12 i=1 j<3
第三趟:1 0 4 5 12 i=2 j<2
第四趟:0 1 4 5 12 i=3 j<1

void Bubble_Sort(int *arr, int len)//下沉
{
    int i, j;
    int tmp=0;
    bool swap = false;
    for (i = 0; i < len - 1; i++)
    {
        swap = false;
        for (j = 0; j < len - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
                swap = true;
            }
        }
        if (!swap)//swap==false没有交换
        {
            return;
        }
    }
}
void Bubble_Sort1(int *arr, int len)//上浮
{
    int i;
    int j;
    int tmp;
    bool swap=false;
    for (i = 0; i < len; i++)
    {
        swap = false;
        for (j = i + 1; j < len; j++)
        {
            if (arr[i] > arr[j])
            {
                tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
                swap=true;
            }
        }

        if(!swap)
        {
            return;
        }
    }
}
void Bubble_Sort2(int *arr, int len)//不开辟tmp
{
    int i, j;
    for (i = 0; i<len - 1; i++) //扫描次数len-1   
    {
        for (j = len - 1; j>i; j--)
        {
            if (arr[j] > arr[j - 1])
            {
                arr[j] += arr[j - 1];
                arr[j - 1] = arr[j] - arr[j - 1];
                arr[j] = arr[j] - arr[j - 1];
            }
        }
    }
}

三、直接插入排序:
时间复杂度:无序O(n^2) 有序O(n)
空间复杂度:O(1)
算法稳定性:稳定
原理:把一个元素按升序或(降序)插入已经有序的一个序列里面,插入后保持序列的有序。
假设有序列arr[1..n],则将arr[2]插入arr[1..1]中,将arr[3]插入arr[1..2]中,
将arr[4]插入arr[1..3]中。如此经过n-1次的插入,便可以使arr[1..n]有序。
把待插入数与已有序的数列依次比较,找到合适位置,进行数据挪动,插入到合适位置。
例:4 1 5 12 0
第一趟:tmp=1 1<4 1 4
第二趟:tmp=5 1 4 5
第三趟:tmp=12 1 4 5 12
第四趟:tmp=0 0<12,0<5,0<4,0<1 0 1 4 5 12

void Insert_Sort(int *arr, int len)
{
    int i,j;
    int tmp=0;
    for (i = 1; i < len; i++)
    {
        tmp = arr[i];//把将要比较的值放入tmp里
        for (j = i - 1; j >= 0; j--)//j在i的前一位
        {
            if (tmp < arr[j])//如果tmp里的值比j的值小就互换tmp和j的值
            {
                arr[j + 1] = arr[j];//即把j里的值放在下一位,把tmp的值放在原来j的位置
            }
            else
            {
                break;
            }
        }
        arr[j + 1] = tmp;//不是则就放在它原来的位置,包扩j减到-1位置 j+1位0号位置
    }
}

四、希尔(shell)排序 :直接插入的优化
时间复杂度:O(n^1.3)——O(n^1.5)
空间复杂度:O(1)
算法稳定性:不稳定
原理:设定一个增量gap,每次插入排序使相距为d的元素排成一个有序列,
然后缩小增量,继续插入排序,最后一次gap=1,排序完成 。
在进行大量数据排序上,效率较高,因为相比于冒泡,选择排序,
其每次操作省略了三步赋值的开销,只有一步。

void Shell(int *arr, int len,int gap)
{   
    int i, j;
    int tmp = 0;
    for (i = gap; i < len; i++)
    {
        tmp = arr[i];
        for (j = i - gap; j >= 0; j-=gap)
        {
            if (tmp < arr[j])
            {
                arr[j + gap] = arr[j];
            }
            else
            {
                break;
            }
        }
        arr[j + gap] = tmp;
    }
}
void Shell_Sort(int *arr, int len)
{
    int drr[] = { 5,3,1 };//素数数组
    int lend = sizeof(drr) / sizeof(drr[0]);
    for (int i = 0; i < lend; i++)
    {
        Shell(arr, len, drr[i]);
    }
}

主函数及测试:

void Show(int *arr,int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int arr[] = {12,45,68,76,24,5};
    int len = sizeof(arr) / sizeof(arr[0]);
    //Select_Sort(arr, len);
    //Bubble_Sort(arr, len);
    Bubble_Sort2(arr,len);
    //Insert_Sort(arr,len);
    Show(arr, len);
    /*int arr[] = { 12,45,68,76,24,5,85,65,2,4,78,95 };
    int len = sizeof(arr) / sizeof(arr[0]);
    Shell_Sort(arr, len);
    Show(arr, len);*/
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值