数据结构入门:时间复杂度与排序和查找 - 详解
一、时间复杂度
1.1定义
时间复杂度是算法执行次数(y)和数据总量(n)的关系,反映算法 “效率趋势”(不是具体执行时间)。
例:
y = a————>y=1————>O(1) 算法的执行次数与数据总量无关
y = an+b————>y=n————>O(n)
y = logan————>y=logn————>O(logn)
y = an²+bn+c————>y=n²————>O(n²)
效率排序:O(1)<O(logn)<O(n)<O(nlogn)<O(n2)
1.2真题练手
例题1:
int sum=0;
for(int i=1;i
分析:
外层循环:i从 1 开始,每次 ×2,直到i≥n,执行次数是 log2n(比如 n=8 时,i=1、2、4,共 3 次);
内层循环:每次执行i次(i=1 时执行 1 次,i=2 时执行 2 次,…,i=2^k 时执行 2^k 次);
总执行次数:1+2+4+…+2log2n−1=2log2n−1=n−1;
时间复杂度:O(n)。
例题2:
int i=0;
while(i*i <=n)
i++;
分析:
循环结束条件是i² >n,即i>√n,执行次数约为 ;
时间复杂度:O(√n)
例题3:
count=0;
for(k=1;k<=n;k*=2)
for(j=1;j<=n;j++)
count++;
分析:
外层循环:k从 1 开始,每次 ×2,直到k>n,执行次数是 log2n(比如 n=8 时,k=1、2、4、8,共 4 次);
内层循环:每次固定执行n次;
总执行次数:log2n×n=nlog2n;
时间复杂度:O(nlogn)(对应选项 C)。
二、查找算法:从 “暴力” 到 “高效”
计算机 80% 的操作是 “查找”,两种常见方式对比:
2.1无序数组查找(暴力遍历)
比如数组[5,7,4,2,0,3,1,6]找 “4”:
只能从头到尾遍历,最坏情况执行 n 次;
时间复杂度:O(n)。

2.2折半查找(二分查找,仅适用于有序数组)
比如有序数组[0,1,2,3,4,5,6,7]找 “4”:
步骤:先查中间位mid=3(对应值 3),比 4 小,再查右半部分的中间位mid=5(对应值 5),比 4 大,最后查中间位 4(找到目标);
执行次数:log2n(n=8 时执行 3 次);
时间复杂度:O(logn)。

三、排序算法:不同算法的效率差异
要想用折半查找,得先把数组排序 —— 看几个经典排序的逻辑和复杂度。
3.1冒泡排序(O(n2))
核心逻辑:前后元素对比,大的往后 “冒泡”。比如数组[4,2,0,3,1,5,6,7]:
第 1 轮:对比 (4,2)→交换,(4,0)→交换,…,最大的 “7” 移到末尾;
第 2 轮:对比剩下的元素,第二大的 “6” 移到倒数第二位;
最坏情况执行次数:1+2+…+(n−1)=n(n−1)/2;
时间复杂度:O(n2)。

3.2简单选择排序(O(n2))
核心逻辑:每轮找最小值,和待排序部分的第一个元素交换。比如数组[0,1,2,3,5,4,7,6]:
第 1 轮:找最小的 “0”,和第一个元素交换(已在正确位置);
第 2 轮:找剩下的最小 “1”,和第二个元素交换;
无论数组是否有序,都要遍历找最小值,执行次数约n2/2;
时间复杂度:O(n2)。

3.3新增:插入排序(O(n2))
核心逻辑:把数组分成 “已排序部分” 和 “未排序部分”,每次从未排序部分取第一个元素,插入到已排序部分的合适位置(类似打扑克时整理手牌)。
举个例子,数组[4,2,0,3,1,5,6,7]:
第 1 轮:已排序部分是[4],取未排序的2,插入后变成[2,4];
第 2 轮:已排序部分是[2,4],取未排序的0,插入后变成[0,2,4];
第 3 轮:取未排序的3,插入到2和4之间,变成[0,2,3,4];
…… 直到所有元素插入完成。
最好情况:数组已经有序,每次插入只需要比较 1 次,总执行次数是n,时间复杂度O(n);
最坏情况:数组逆序,第i个元素需要比较i次(比如第 2 个元素比较 2 次,第 3 个比较 3 次…),总执行次数是1+2+…+(n−1)=n(n−1)/2,时间复杂度O(n2);
平均情况:时间复杂度也是O(n2)。

3.4 希尔排序(介于O(nlogn)和O(n2))
核心逻辑:按 “间隔” 分组排序,逐步缩小间隔,最后用直接插入排序收尾。比如数组[5,7,4,2,0,3,1,6](长度 8):
第 1 轮:间隔 = 4,分成 4 组(5,0)、(7,3)、(4,1)、(2,6),组内排序后得到[0,3,1,2,5,7,4,6];
第 2 轮:间隔 = 2,分成 2 组(0,1,5,4)、(3,2,7,6),组内排序后得到[0,2,1,3,4,6,5,7];
第 3 轮:间隔 = 1,直接插入排序得到有序数组;
时间复杂度:和间隔选择有关,通常介于O(nlogn)和O(n2)之间。


浙公网安备 33010602011771号