当前位置: 首页 > wzjs >正文

学做网站看书会了吗广州网站建设骏域网站

学做网站看书会了吗,广州网站建设骏域网站,怎样建设好网站,设计方案格式模板选择排序 选择排序的基本思路&#xff1a;从待排序元素中选取最大&#xff08;或最小&#xff09;的一个元素加入到已完成排序的末尾。 #include <stdio.h>#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0])) #define SWAP(arr, i, j ) { \ int tmp arr[i]; …

选择排序

选择排序的基本思路:从待排序元素中选取最大(或最小)的一个元素加入到已完成排序的末尾。

#include <stdio.h>#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
#define SWAP(arr, i, j ) {      \
int tmp = arr[i];           \
arr[i] = arr[j];            \
arr[j] = tmp;               \
}void print_arr(int arr[], int len) {for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");
}// 选择排序
void selection_sort(int arr[], int len) {/*
* i表示未排序序列的开头元素
* 最后一轮选择排序时, 未排序序列的开头元素是数组倒数第二个元素
* i的每个取值都表示一轮选择排序
* 也就是选择排序一共执行9趟
*/for (int i = 0; i < len - 1; i++) {// 不妨直接假设未排序序列的开头i位置元素就是最小值int min_index = i;// 遍历未排序数组序列,找出真正的最小值下标,此时应遍历最后一个元素for (int j = i + 1; j < len; j++) {if (arr[j] < arr[min_index]) {min_index = j;  // 记录较小值的下标}}   // for循环结束时,未排序序列的最小值下标就是min_index// 交换min_index和下标i的元素SWAP(arr, min_index, i);// 选择排序一趟打印一次数组print_arr(arr, len);}
}int main(void) {// 测试选择排序int arr[] = { 1,10,2,5,3,4,5,6,3,2 };int len = ARR_LEN(arr);selection_sort(arr, len);return 0;
}

时间复杂度分析:选择排序的时间复杂度是O(n2),任何情况下都一样。

空间复杂度分析:选择排序是一种原地排序算法,不需要占用额外内存空间。空间复杂度是O(1)

稳定性分析:选择排序在每一轮中选择最小元素,并与未排序部分的第一个元素交换。如果存在相等的元素,选择排序可能会改变它们的相对顺序。所以选择排序不是一个稳定的排序算法。

冒泡排序

基本思路:将未排序算法中的元素,从头到尾两两比较,将最大的元素不断后移到已经排序元素的头部(按从小到大排序)。

工作原理如下(按照从小到大排序):

  1. 第一轮冒泡排序:从数组的第一个元素开始,比较相邻的元素。如果第一个元素比第二个元素大,则交换它们的位置。然后,移动到下一对相邻元素,重复这个过程,直到比较最后一对元素。每一轮冒泡排序都会使当前比较序列的最大值到达数组末尾,随后第二轮排序过程中,需要比较的元素就减1。(将尾部最大的元素减去不再排序)
  2. 第二轮冒泡排序:重复第一轮的过程,但这次只比较和交换直到倒数第二个元素(因为最后一个元素已经是最大的了)。在这一轮结束时,倒数第二大的元素会被“冒泡”到倒数第二的位置。
  3. ...
  4. 结束条件:

    1. 在不设置任何额外结束条件的前提下,冒泡排序每一轮都会将未排序序列的最大值"冒泡"到末尾。冒泡排序需要进行固定的(n - 1)轮!
    2. 但实际上在这(n - 1)轮冒泡排序的过程中,只要某一轮完全不存在元素的交换,就说明数组已经完全有序了,排序就可以结束了。
    3. 所以我们可以设定一个布尔值来标记此轮冒泡排序是否存在元素交换,如果没有元素交换,直接结束整个排序。这种做法可以优化冒泡排序的性能,尤其是当原数组已基本有序时。
#include <stdio.h>
#include <stdbool.h>#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0]))#define SWAP(arr, i, j ) {      \int tmp = arr[i];           \arr[i] = arr[j];            \arr[j] = tmp;               \
}void print_arr(int arr[], int len) {for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");
}void bubble_sort(int arr[], int len) {// 外层for的i表示第几轮冒泡排序,最多需要进行len-1轮for (int i = 1; i < len; i++) {// 标记在这一次冒泡排序中有没有交换,false表示没有交换bool swapped = false;/** j表示两两比较元素中的第一个元素的下标* 第一轮j的最大取值是数组倒数第二个元素,并且逐步减小* 所以j的条件是小于 (len - i)*/for (int j = 0; j < len - i; j++) {if (arr[j] > arr[j + 1]) {SWAP(arr, j, j + 1);// 发生了交换改变标记swapped = true;}}// 在一轮冒泡排序中没有任何交换,则排序已经完成,终止循环if (!swapped) {break;}// 打印一轮冒泡排序后数组的元素排列print_arr(arr, len);}
}int main(void) {// 测试冒泡排序int arr[] = { 16, 1, 45, 23, 99, 2, 18, 67, 42, 10 };int len = ARR_LEN(arr);bubble_sort(arr, len);return 0;
}

需要注意的是:

在上述参考代码中使用了"swapped"标记来使得冒泡排序可以在"一轮冒泡没有任何交换时结束"。这在某些场景下,可以提升算法的效率,尤其是最佳情况——输入的数组已经是有序的情况下。

 时间复杂度分析:最佳情况下的时间复杂度是 O(n)。最坏情况下的时间复杂度是 O(n2)。平均情况下,时间复杂度也是 O(n2)。

空间复杂度分析:

冒泡排序是一种原地排序算法,不需要占用额外内存空间。空间复杂度是O(1)

稳定性分析:

冒泡排序显然是一种稳定的排序算法,因为交换的过程中不会交换任何两个相同的元素。

插入排序

工作原理是(将数组从小到大排序):

  1. 以数组的首元素为初始状态:这个初始状态相当于抓到的第一张牌,它默认就是有序的。
  2. 从数组的第二个元素开始遍历:相当于抓一张牌,然后从小到大整理手牌。
  3. 比较与交换:将新插入的元素和前面的元素逐一比较,如果新插入元素较小,则交换两个元素,直到完全不可交换,则完成一轮排序。
  4. 重复步骤2和3,直到步骤2遍历到最后一个元素。
#include <stdio.h>#define SWAP(arr, i, j ) {      \int tmp = arr[i];           \arr[i] = arr[j];            \arr[j] = tmp;               \
}
#define ARR_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))void print_arr(int arr[], int len) {for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");
}// 通过交换元素的方式实现插入排序
void insertion_sort(int arr[], int len) {// 外层for循环中的i表示每轮选择排序新插入元素的下标,也就是"新摸手牌"的下标// 从数组第二个元素开始,后面的每一个元素都相当于"你要摸的手牌"for (int i = 1; i < len; i++) {// 内层for循环的j表示新插入元素需要比较元素的下标,也就是每一张"老手牌"的下标// j从i的前一个位置开始,递减,但不可能成为负数for (int j = i - 1; j >= 0; j--) {if (arr[j] > arr[j + 1]) {  // 注意:这里如果加等号就不是稳定的排序算法了// 前面的元素比后面的元素大,交换SWAP(arr, j, j + 1);}else {// 只需要在某一次比较中,发现前一个元素小于等于后一个元素// 那么前面的元素就一定都是排序好的,此时这一轮选择排序结束break;}}// 打印每一轮选择排序后,数组的元素序列print_arr(arr, len);}
}int main(void) {int arr[] = { 1, 21, 45, 231, 99, 2, 18, 7, 4, 9 };int len = ARR_SIZE(arr);insertion_sort(arr, len);return 0;
}

 上面的实现是通过交换元素取值实现排序的,交换是一个比较"重量级"的操作,需要连续三次赋值来完成。所以我们可以用移动元素来取代交换元素,这样可以轻微提升一些性能。思路是:

先使用一个temp临时存储新插入元素,然后和前面的元素逐一比较,若前面的元素较大就向后移动一位,直到比较完前面所有元素或者比较到一个元素比新插入元素小。

#include <stdio.h>#define SWAP(arr, i, j ) {      \int tmp = arr[i];           \arr[i] = arr[j];            \arr[j] = tmp;               \
}
#define ARR_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))void print_arr(int arr[], int len) {for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");
}// 插入排序 优化: 用向后移动腾出插入位置,然后插入实现插入排序
void insertion_sort(int arr[], int len) {// 现在第一个元素就是第一张手牌,从第二个元素开始就是每一次要摸的牌// 外层for循环代表每一轮摸到的新手牌, 也就是每一轮插入排序for (int i = 1; i < len; i++) {// 先记录一下新手牌的值, 便于后续的插入操作int tmp = arr[i];int j = i - 1;for (; j >= 0; j--) {if (arr[j] > tmp) { // 注意:不能加=,加了就不是稳定排序算法了arr[j + 1] = arr[j];    // 将旧手牌中大于新手牌的所有牌都向后移}else{break;  // 只要发现一张旧手牌更小或相等, 就说明已经找到新手牌的插入位置了}}/*现在还有一件事情没做:新手牌要插入,需要确定插入位置分析: for循环什么时候结束?两种情况:1.j=-1时,循环结束,说明新手牌是最小的,所以插入到0这个位置,也就是j+12.arr[j] <= tmp 也就是旧手牌更小或相等,此时新手牌放在j+1的位置*/arr[j + 1] = tmp;print_arr(arr, len);    // 每一轮摸牌后查看排序后的数组}
}int main(void) {int arr[] = { 1, 21, 45, 231, 99, 2, 18, 7, 4, 9 };int len = ARR_SIZE(arr);insertion_sort(arr, len);return 0;
}

时间复杂度分析:最佳情况下的时间复杂度是 O(n)。最坏情况下的时间复杂度是 O(n2)。平均情况下,时间复杂度也是 O(n2)。

空间复杂度分析:

插入排序是一种原地排序算法,不需要占用额外内存空间。空间复杂度是O(1)

稳定性分析:

插入排序显然也是一种稳定的排序算法,因为对于两个相同的元素,我们始终都不会交换它们的相对位置。

注意:如果判断的条件改成arr[j] >= arr[j + 1],即在前后元素相等时也交换/移动元素,算法就会变成不稳定的。

http://www.dtcms.com/wzjs/800534.html

相关文章:

  • 腾讯云网站安全认证如何建立wordpress商城
  • 重庆网站制作公司黄金网站
  • 弹幕怎么做视频网站厦门建模培训
  • 新加坡的网站域名wordpress装百度联盟广告
  • 地方门户网站设计新公司注册详细流程
  • 做网站在线在西部数码做的企业网站不能与阿里巴巴网站相连接
  • 技术支持:佛山网站建设汕头高端网站开发
  • 做的烂的网站网站图片倒计时怎么做的
  • 免费个人网站怎么制作国外seo网站
  • 前端和网站部署做网站的户外旅游网站排名
  • 网站制作公司南宁长沙楼市最新消息
  • wordpress 仿站 主题常州网站优化
  • 企业网站建设义乌能建网站的app
  • 注册网站会员需要详细手机网站底部广告代码
  • 网站免费建站众享星球sem优化案例
  • 建立主题网站的知识点做网站的得多少钱
  • 海淀石家庄网站建设外国平面设计网站有哪些
  • 网站开发公司的职责用h5做简易网站代码
  • 个人网站命名的要求wordpress手动上传图片
  • 网站管理运营安什么网站建设
  • 电商网站建设工具百度非企渠道开户
  • 免费1级做爰片观看网站在线视频郑州网站建设中国建设建设银行
  • 网站左侧分类导航菜单网站建设一站式服务
  • 网站建设对接流程湖南住建云
  • 网站建设维护单选题申请企业邮箱需要什么
  • 做网站先得注册域名吗nodejs做后端的网站
  • 扬中网站制作帝国cms 做的博客网站
  • 电子商务网站开发岗位职责网站js代码不显示
  • 东莞中小企业网站建设esp8266做网站
  • 营销型网站建设优势假如电脑的服务器关闭后做的网站还能打开吗