排序算法

本文详细介绍了排序的概念,包括内部排序和外部排序,稳定性分析,以及算法的时间复杂度和空间复杂度。重点讨论了时间复杂度的大O表示法,常见的时间复杂度阶,并列举了一些常见的排序算法如冒泡排序、选择排序和插入排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序的概念

概念

排序是计算机内经常进行的一种操作,其目的是将一组无序的数据元素调整为有序的数据元素的过程。

操作

比较:任意两个数据元素通过比较操作确定先后次序。

//比较数组中两个数据
if (arr[i] > arr[j])
	//arr[i]大于arr[j]
else
	//arr[i]小于arr[j]

交换:数据元素之间需要交换才能得到预期结果。

//数据交换函数
void swap(int *a, int *b)
{
     int tmp = *a;
     *a = *b;
     *b = tmp;
}

数据量分析

内部排序:

若整个排序过程不需要访问外存,仅在内存中完成数据的调整,则称此类排序问题为内部排序。

外部排序:

若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。

稳定性分析

前提:一组数据中出现多个相同的数据

//一组数据中出现多个相同的数据
int arr[]={9,1,5,6,4,10,5,8,7,3};

若在原始记录序列中, ai 和 aj 的关键字相同, ai 出现在 aj 之前,经过某种方法排序后,ai的位置仍在 aj之前,则称这种排序方法是稳定的;

反之,若经过该方法排序后, ai的位置在 aj 之后,即相同关键字记录的领先关系发生变化,则称这种排序方法是不稳定的。

算法复杂度

算法复杂度

指算法在编写成可执行程序后,运行时所需要的资源,资源包括时间资源和内存资源。应用于数学和计算机导论。

同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法。

一个算法的评价主要从[时间复杂度]和[空间复杂度]来考虑。

时间复杂度

一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。

算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O(f(n)),它称为算法的渐进时间复杂度,简称时间复杂度

大O表示法

用O( )来体现算法时间复杂度的记法,称为大O表示法。

算法复杂度可以从最理想情况、平均情况和最坏情况三个角度来评估。

由于平均情况大多和最坏情况持平,而且评估最坏情况也可以避免后顾之忧,因此一般情况下,设计算法时都要直接估算最坏情况的复杂度。

复杂度的阶

常数阶

void test()
{
     //算法的时间复杂度是O(1),称为常数阶。
     printf("hello");//执行1次
}

线性阶

void test(int n)
{
 for(int i = 0;i < n; i++)
 {
		//时间复杂度为O(n)的算法,称为线性阶
	 	printf("hello");//执行n次
	}
}

对数阶

void test(int n)
{
	int num = 1;
	while(num < n)
 	{
     	//假设循环的次数为X,则由2^x=n得出x=log₂n,因此得出算法的时间复杂度为O(logn)
		num = num * 2;
		//时间复杂度为O(logn)的算法,称为对数阶
		printf("hello");//执行logn次
	}
}

平方阶

void test(int n)
{
    //嵌套循环,外层控制行,内层控制列,执行次数为 外层*内层(n*n)次
   for(int i = 0; i < n; i++)
   {   
       for(int j = 0; j < n; i++)
       {
           //时间复杂度为O(n^2)的算法,称为平方阶
          printf("hello");//执行n^2次
    }
}
}
算法效率的度量

只关注最高次项

时间复杂度是指最坏时间复杂度

只有常数项记做1

常见的时间复杂度

O(1) < O(logn) < O(n) < O(nlogn) <O(n²) < O(n³) < O(2ⁿ) < O(n!) < O(nⁿ)

执行次数函数非正式术语
12O(1)常数阶
2n+3O(n)线性阶
3n^2+2n+1O(n²)平方阶
5log2n+20O(logn)对数阶
2n+3nlog2^n+19O(nlogn)nlogn阶
6n3+2n2+3n+1O(n³)立方阶
2^nO(2ⁿ)指数阶

空间复杂度

空间复杂度是度量算法所需存储空间的大小。

算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数。记做S(n)=O(f(n))。

空间复杂度比较常用的有:O(1)、O(n)、O(n²)。

空间复杂度 O(1)

void test()
{
    //创建一个数据大小的空间
    //所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
    int a = 1;
}

空间复杂度 O(n)

void test(int n)
{
    //开辟n个数据的堆空间,因此它的空间复杂度 S(n) = O(n)
    int* p = (int*)malloc(sizeof(int) * n);
}

空间复杂度 O(n²)

void test(int n)
{
    //开辟二级指针对应的堆空间
    int** p = (int**)malloc(sizeof(int*) * n);
    //开辟一级指针对应的堆空间
    for(int i = 0;i<n;i++)
    {
        p[i] = (int*)malloc(sizeof(int) * n);
    }
    //开辟堆空间的数据为n*n,因此它的空间复杂度 S(n) = O(n²)
}

排序算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值