排序算法(插入排序+希尔排序)

目录

 

一、插入排序

 二、希尔排序

三、代码汇总

1.sort.h

2.sort.c

3.test.c


一、插入排序

插入排序就是 遍历我们数组中的每一个元素,然后寻找我们当前的数组应该插入的位置,寻找到插入位置后,将我们的数组中的每一个大于当前插入数的元素后移,腾出一个位置,再将我们的插入数插入到我们当前腾出来的位置。即完成一次排序,遍历整个数组以完成全部元素的排序。

//插入排序(从小到大升序排序)
void InsertSort1(ElemType *a,int n)
{
//创建两个指针用于遍历
    int i,j;
//这里我们的ElemType已经指定为int,指定为ElementType的方法在修改具体得到数据类型的时候比较方便
    ElemType temp;
//从0-n-1遍历我们整个数组中的每一个元素(数组的下标就是0-n-1)
    for(i=0;i<n;i++)
    {
//如果我们的后面的元素小于前面的元素
        if(a[i]<a[i-1])
        {
//用一个临时变量保存我们的a[i]的数据,再将我们整个数组中小于a[i]的数据的全部元素都依次往后移
            temp=a[i];
            for(j=i-1;j>=0&&a[j]>temp;--j)
            {
                a[j+1]=a[j];
            }
//此时移动完成之后,空出来的位置就是我们a[i]应该插入的位置。
//从上面的for循环中跳出来的时候a[j]<temp,所以我们的temp应该插入在我们的a[j+1]的位置
            a[j+1]=temp;
        }
    }
}

使用while循环的写法 

//插入排序
void InsertSort2(ElemType *a,int n)
{
    for(int i=0;i<n-1;++i)
    {
//end等于我们当前的i
        int end=i;
//当前我们需要排序的元素为我们的end后面的那个元素
        ElemType tmp=a[end+1];
//从后向前寻找我们tmp元素应该插入的位置的同时,将我们数组中道德元素依次后移,给我们tmp腾出位置。
        while(end>=0)
        {
            if(tmp<a[end])
            {
                a[end+1]=a[end];
                end--;
            }
            else
            {
                break;
            }
        }
        a[end+1]=tmp;
    }
}

 二、希尔排序

我们发现在上面的插入排序的时间复杂度较高,并且排序比较繁琐,所以我们可以采用类似于预排序的方法,来降低我们的时间复杂度。

希尔排序的算法旨在先设定一个gap值,将整个数组中,每间隔gap的元素进行插入排序,再将gap的值逐渐缩小,从而完成整个数组的排序(当我们gap为1的时候,我们的希尔排序即是我们的插入排序)

希尔排序的算法(升序)能够让我们数组中大的元素尽快的沉到数组的末尾,小的元素尽快上浮到数组的前部

//希尔排序的写法
void ShellSort1(ElemType *a,int n)
{
    int gap=n;
    while(gap>1)
    {
        //gap>1是预排序
        //gap=1的时候是保证排序的完成。
        //这里我们设置的是将我们的gap每次都除以3+1来将我们的间隔缩小。
        gap=gap/3+1;
//遍历我们数组中下表为0到n-gap的元素
        for(int i=0;i<n-gap;++i)
        {
            int end=I;
//我们待排序的希尔排序的元素为我们的a[end+gap]
            ElemType tmp=a[end+gap];
//寻找我们的排序元素的同时将我们前面的比我们排序元素小的元素后移。
            while(end>=0)
            {
                if(tmp<a[end])
                {
                    a[end+gap]=a[end];
                    end-=gap;
                }
                else
                {
                    break;
                }
            }
//将我们的gap放入我们的空出来的位置。
            a[end+gap]=tmp;
        }
    }

}

三、代码汇总

1.sort.h

#pragma once
#include<stdio.h>
#include <stdlib.h>
typedef int ElemType;
//打印数组
void print(int*a);
//以下是两种插入排序的写法
void InsertSort1(int *a,int n);
void InsertSort2(int *a,int n);
//希尔排序的写法
void ShellSort1(ElemType *a,int n );

2.sort.c

#include "sort.h"
//两种插入排序的写法

void InsertSort1(ElemType *a,int n)
{
    int i,j;
    ElemType temp;
    for(i=0;i<n;i++)
    {
        if(a[i]<a[i-1])
        {
            temp=a[i];
            for(j=i-1;j>=0&&a[j]>temp;--j)
            {
                a[j+1]=a[j];
            }
            a[j+1]=temp;
        }
    }
}
void InsertSort2(ElemType *a,int n)
{
    for(int i=0;i<n-1;++i)
    {
        int end=i;
        ElemType tmp=a[end+1];
        while(end>=0)
        {
            if(tmp<a[end])
            {
                a[end+1]=a[end];
                end--;
            }
            else
            {
                break;
            }
        }
        a[end+1]=tmp;
    }
}

void print(ElemType *a)
{
    for(int i=0;i<10;i++)
    {
        printf("%d->",a[i]);
    }
}

//希尔排序的写法
void ShellSort1(ElemType *a,int n)
{
    int gap=n;
    while(gap>1)
    {
        //gap>1是预排序
        //gap=1的时候是保证排序的完成。
        gap=gap/3+1;
        for(int i=0;i<n-gap;++i)
        {
            int end=i;
            ElemType tmp=a[end+gap];
            while(end>=0)
            {
                if(tmp<a[end])
                {
                    a[end+gap]=a[end];
                    end-=gap;
                }
                else
                {
                    break;
                }
            }
            a[end+gap]=tmp;
        }
    }

}

3.test.c

这里的ShellSort可以用其他的排序算法替换

#include "sort.h"
int main() {
    int a[10]={9,7,4,2,3,6,1,8,10,5};
    ShellSort1(&a,10 );
    print(a);
    printf("\n");
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桜キャンドル淵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值