寒假训练 第六节 基础算法 总结

文章介绍了两种排序算法——计数排序和冒泡排序。计数排序是一种稳定的线性时间复杂度排序,适合于已知最大值且元素范围不大的情况,而冒泡排序则是一种基础的排序算法,虽然时间复杂度较高,但实现简单且空间复杂度低。
摘要由CSDN通过智能技术生成

计数排序

定义:计数排序是一种稳定的线性时间排序算法,原理是使用一个额外的数组,其中第i个元素是待排序数组中值等于i的元素的个数。

实现步骤:

1)找出待排序的数组中最大和最小的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

图引用自菜鸟教程:
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
 
#define MAXNUM 10
 
void main()
{
    void CountSort(int data[],int n);
    int i,data[MAXNUM];
    for(i=0;i<MAXNUM;i++)
        scanf("%d",&data[i]);
    CountSort(data,MAXNUM);
    for(i=0;i<MAXNUM;i++)
        printf("%d ",data[i]);
    printf("\n");
}
 
void CountSort(int data[],int n)
{
    int i,j,count,*data_p,temp;
    data_p=(int*)malloc(sizeof(int)*n);
    for(i=0;i<n;i++)//初始化data_p
        data_p[i]=0;
    for(i=0;i<n;i++)
    {
        count=0;
        for(j=0;j<n;j++)//扫描待排序数组
            if(data[j]<data[i])//统计比data[i]值小的值的个数
                count++;
        while(data_p[count]!=0)//对于相等非0的数据,应向后措一位。数据为0时,因数组data_p被初始化为0,故不受影响。
        /* 注意此处应使用while循环进行判断,若用if条件则超过三个重复值后有0出现 */    
                count++;
        data_p[count]=data[i];//存放到data_p中的对应位置
    }
        //用于检查当有多个数相同时的情况
    i=0,j=n;
    while(i<j)
        {
        if(data_p[i]==0)
                {
            temp=i-1;
            data_p[i]=data_p[temp];
        }//of if
        i++;
    }//of  while
    for(i=0;i<n;i++)//把排序完的数据复制到data中
        data[i]=data_p[i];
    free(data_p);//释放data_p
}

时间复杂度

计数排序的时间复杂度为O(n+k)。其中n为待排序元素个数,k为待排序元素最大值

空间复杂度

计数排序的空间复杂度为n+O(k)。其中n为待排序元素个数,k为待排序元素最大值

优缺点

优点:速度快。
缺点:需要提前知道待排序元素最大值,需要大量内存消耗。

冒泡排序

定义:是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

实现步骤:

1)比较相邻元素,若前一个元素比后一个元素大,则交换位置
(2)将每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数
(3)、针对所有的元素重复以上的步骤,除了最后一个
(4)、重复以上三个步骤,知道排序完成

在这里插入图片描述

#include<iostream>
#include <stdio.h>
#define ARR_LEN 255 /*数组长度上限*/

 
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
    int temp;
    int i, j;
    for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
        for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
            if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
}
 
int main (void) {
    int arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
    int len = 10;
    int i;
     
    bubbleSort (arr, len);
    for (i=0; i<len; i++)
        cout<<arr[i];
    putchar ('\n');
     
    return 0;
}

时间复杂度

最优的时间复杂度为:O( n^2 ) ;

最差的时间复杂度为:O( n^2 );

平均的时间复杂度为:O( n^2 );

空间复杂度

空间复杂度就是在交换元素时那个临时变量所占的内存空间;

最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0;

最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n);

平均的空间复杂度为:O(1);

最优时间复杂度 n;

优点:比较简单,空间复杂度较低,是稳定的;

缺点:时间复杂度太高,效率慢;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值