常用的排序和查找算法

空间复杂度:算法执行过程中额外开辟的空间随数据量n的变化关系。

时间复杂度:执行这个算法所花时间的度量。

时间复杂度的计算规则:

1,用常数1 取代运行时间中的所有加法常数

2,在修改后的运行函数中,只保留最高阶项。

3,如果最高阶存在且系数不是1,则去除这个项相乘的常数。

排序算法的稳定性:在一个待排序列中出现了两个相同的数据,经过排序之后,这两个相同数据的

相对位置没有发生变化,则该排序算法为稳定的排序算法;假如这两个相同数据的相对位置发生了

变化,则该排序算法是一个不稳定的排序算法。

一、排序算法

1.选择排序

思想:将待排位置的数据和后面的数据依次进行比较,按照升序要求,将较小值存储在待排位置。

时间复杂度(效率):O(n^2)

空间复杂度(空间/内存):O(1)

选择排序:不稳定

int a[10] = {1,2,-3,-4,-5,6,7,8,-9,0};
int len = sizeof(a) / sizeof(a[0]);
int i = 0;
int j = 0;
int tmp = 0;
for (i = 0; i < len-1; ++i)
{
    for (j = i+1; j < len; ++j)
    {
        if (a[i] > a[j])
        {
            tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
        }
    }
}

2.冒泡排序

思想:相邻两两数据进行比较,按照升序要求,将较大值交换到两两中的后者位置,经过一趟排

           序,优先确定最大值。

时间复杂度:On^2

空间复杂度:O1

稳定性:稳定

int a[10] = {1,-2,-3,4,5,6,7,8,-9,0};
int len = sizeof(a) / sizeof(a[0]);
int i = 0;
int j = 0;
int tmp = 0;
for (j = 0; j < len-1; ++j)
{
    for (i = 0; i < len-1-j; ++i)
    {
        if (a[i] < a[i+1])
        {
            tmp = a[i];
            a[i] = a[i+1];
            a[i+1] = tmp;
        }
    }
}

3.插入排序

思想:将待排的数据插入到一个已有序的序列中,确保每次插入之后该序列仍然有序。

时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性:稳定

   
 12     int num[10] = {1,88,5,4,3,6,7,8,9,100};
 13     int tmp = 0;
 14     int len = sizeof(num) / sizeof(num[0]);
 15     int j = 0;
 16          
 17     for(int i = 1; i < len ; ++i)
 18     {
 19         tmp = num[i];
 20         j = i;
 21         while(j>0 && tmp < num[j - 1])
 22         {
 23             num[j] = num[j-1];
 24             --j;
 25         }
 26         num[j] = tmp;
 27     }
~                    

4.希尔排序

思想:将待排序列根据增量划分成若干个子序列,分别对这些子序列进行插入排序。

时间复杂度:O(nlongn)~O(n^2)

空间复杂度:O1

稳定性:不稳定

    int tmp = 0;
    int icn = 0;
    int j = 0;
    int i = 0;
    
    for(icn = len / 2 ; icn > 0 ; icn /= 2)
    {
        for(i = icn ; i < len ; ++i )
        {
            tmp = a[i];
            j = i;
            while(j >= icn && tmp < a[j - icn])
            {
                a[j] = a[j - icn];
                j -=icn;
            }
            a[j] = tmp;
        }
    }

5.快速排序

思想:选取基准值,从两端向中间比较,比基准值大的放在序列的右边;比基准小的放在序列的左边;经过一趟排序,优先排好基准值。

时间复杂度:Onlogn

空间复杂度:Ologn

稳定性:不稳定

void quick_sort(int *a, int begin, int end)
{
    if (begin >= end)
    {
        return ;
    }
    int i = begin;
    int j = end;
    int key = a[i];

    while (i < j)
    {
        while (i < j && key <= a[j])
        {
            --j;
        }
        a[i] = a[j];
        while (i < j && key >= a[i])
        {
            ++i;
        }
        a[j] = a[i];
    }
    a[i] = key;

    quick_sort(a, i+1, end);
    quick_sort(a, begin, i-1);
}

二、查找算法

1.二分查找(折半查找)

思想(升序):将要查找的值和序列的中间位置值比较,比中间位置值大,则在后半序列中继续折

半查找,如果比中间值小,则从前半个序列中继续折半查找,如果恰好相等,则找到。

前提条件:序列必须有序

时间复杂度:Ologn

i = 0;
j = len-1;
while (i <= j)
{
    mid = (i + j) / 2;
    if (num > a[mid])
    {
        i = mid + 1;
    }
    else if (num < a[mid])
    {
        j = mid - 1;
    }
    else
    {
    printf("find %d\n", a[mid]);
    break;
    }
}

if (i > j)
{
printf("Not find\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值