c语言log_C语言基础知识(三)

本篇介绍一些C语言算法相关内容.

1. 算法的基本概念和评价

1.1 基本概念

算法(Algorithm) 就是指对解题方案准确而又完整的描述, 是一系列解决问题的清晰指令.

1.2 评定标准

(1)时间复杂度(重点关注)

-主要用于描述算法的时间消耗和问题规模的函数关系, 常数级的时间复杂度、 线性关系的时间复杂度、 平方级的时间复杂度...

(2)空间复杂度

-主要用于描述算法的空间消耗和问题规模的函数关系

(3)正确性

-主要用于描述算法的执行结果是否满足要求

(4)可读性

-主要用于描述算法本身是否便于人们的阅读

(5)健壮性

-主要用于描述算法对非正常输入的处理能力

1.3 算法的描述方式

目前主要的算法描述方式有: 自然语言、 伪代码、 流程控制图、 PAD 图... ...

2. 常用的查找算法

2.1 线性查找算法( 顺序查找算法)

(1)算法流程

使用目标元素与样本数列中的第一个元素起依次进行比较, 如果找到与目标元素相等的元素则表示查找成功, 或者所有样本元素与目标元素都比较完毕, 也没有相等的元素, 则表示查找失败

int Sequence_Search(int *array, int length, int key){ for(int i=0; i

(2)算法评价

平均时间复杂度 O(N), 不要求样本数列中的元素有序

2.2 二分查找算法( 折半查找算法)

(1)算法流程

假定样本中的所有数列元素按照从小到大依次排列, 使用目标元素与样本数列中的中间元素进行比较, 如果相等则查找成功, 如果目标元素小于样本数列中的中间元素, 则在中间元素的左边进行查找, 如果目标元素大于样本数列中的之间元素, 则在中间元素的右边进行查找, 直到目标元素与可以比较的所有元素比较完毕, 也没有找到相等的元素, 则表示查找失败, 可以使用递归处理

int Binary_Search(int *sorted_array, int length, int key){ int low = 0, high = length-1, mid; while(low <= high) { mid = low + (high - low) / 2; if(key < sorted_array[mid]) { high = mid - 1; } else if(key > sorted_array[mid]) { low = mid + 1; } else { return mid; } }  return -1; }

(2)算法评级

平均时间复杂度 O(logN), 要求样本元素有序

2.3 插值查找算法( 二分法升级版)

(1)算法流程

基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率

int Insert_Search(int *sorted_array, int length, int key)

{

int low = 0, high = length-1, mid;

while(low <= high){

mid = low + (key - sorted_array[low]) / (sorted_array[high] - sorted_array[low]);

if(key < sorted_array[mid])

{

high = mid - 1;

}

else if(key > sorted_array[mid])

{

low = mid + 1;

}

else

{

return mid;

}

}

return -1;

}

(2)算法评级

平均时间复杂度 O(log(logN)), 要求样本元素有序

3. 常用的排序算法

3.1 冒泡排序算法

(1) 算法流程

a. 比较相邻位置的两个元素, 如果第一个元素的值比第二个元素大, 则交换位置

b. 对每一对相邻的元素做相同的操作, 从开始的第一对到结尾的最后一对, 经过这一步, 最后的元素将是这组元素中的最大值

c. 对除了最后一个元素以外的所有元素重复以上步骤

d. 持续对越来越少的元素重复以上步骤, 直到没有元素交换为止

106d8e25b8ffcdee438025d0fe15c133.gif
void Bubble_Sort(int *array, int length){ int tmp = 0; for(int i=0; i array[j+1]) { tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; } } } }

(2) 算法评价

平均时间复杂度 O(N^2),稳定, 对样本的有序性非常敏感

3.2 插入排序方法

(1) 算法流程

a. 首先认为第一个元素有序,

b. 取出一个元素, 让取出的元素与已经有序的元素从后向前依次进行比较

c. 如果左边的元素大于取出的元素, 则将左边的元素值赋值到下一个元素的位置上

d. 如果左边的元素小于等于取出的元素, 则将取出的元素赋值到左边元素的右边

e. 重复步骤 b, 直到处理完毕所有元素为止

c16eca3bbbfe994bd9707c9c6a6d791b.gif
void Insert_Sort(int *array, int length){ int preIndex, current; for(int i=1; i= 0 && array[preIndex] > current) { array[preIndex + 1] = array[preIndex]; preIndex--; } array[preIndex + 1] = current; } }

(2) 算法评价

平均时间复杂度 O(N^2), 稳定, 对样本的有序性非常敏感, 但是赋值的次数比冒泡排序少, 因此一般情况下略优于冒泡排序算法

3.3 选择排序法

(1) 算法流程

a. 从第一个元素起依次取出, 并且假定取出的元素是最小值, 使用临时变量min 记录该元素的下标

b. 使用 min 记录的元素与后续的元素依次进行比较

c. 如果后续元素中由比 min 记录的元素还小的元素, 则重新记录下标, 也就是后续元素变成了 min 记录的最小值

d. 直到 min 记录的最小值与后续所有元素比较完毕, 交换 min 记录的元素与最开始假定的最小值

e. 重复上述步骤, 直到处理完毕左右元素为止

152d9f6c978d9d246530122be79c389f.gif
void Select_Sort(int *array, int length){ int minIndex, tmp; for(int i=0; i

(2) 算法评估

平均时间复杂度 O(N^2), 不稳定, 对样本的有序不敏感, 虽然比较的次数比较多, 但是交换的次数比较少, 因此一般情况下也是略优于冒泡排序法

3.4 快速排序算法

(1) 算法流程

a. 选择中间元素作为基准值, 单独保存起来

b. 分别使用左右两边的元素依次和基准值进行比较, 将所有比基准值小的元素放在基准值的左边, 将所有大于基准值的放在基准值的右边, 等于基准值的元素可以放在任意一边, 这个过程叫做分组

c. 以递归的方式对小于基准值的分组和大于基准值的分组分别进行再次分组,直到处理完毕所有元素为止

c6c08d8867258611cd64691ee63738a4.gif
void Quick_Sort(int *array, int left, int right){ if(left < right) { int i = left, j = right, tmp = array[left]; while(i < j) { while(i < j && array[j] >= tmp) //从右到左找到第一个小于tmp的数 j--; if(i < j) array[i++] = array[j]; while(i < j && array[i] <= tmp) //从左往右找到第一个大于tmp的数 i++; if(i < j) array[j--] = array[i]; } array[i] = tmp; Quick_Sort(array, left, i-1); Quick_Sort(array, i+1, right); }}

( 2) 算法评价

平均时间复杂度 O(NlogN),不稳定, 对样本的有序性不敏感

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值