【数据结构初阶】九、排序的讲解和实现(直接插入 \ 希尔 \ 直接选择 \ 堆 \ 冒泡 -- C语言)

=========================================================================

相关代码gitee自取

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

【数据结构初阶】八、非线性表里的二叉树(二叉树的实现 -- C语言链式结构)-CSDN博客

 =========================================================================

                     

排序

排序的概念

所谓排序,就是使一串记录
按照其中的某个或某些关键字的大小递增或递减排列起来的操作
                 

稳定性

假定在待排序的记录序列中存在多个具有相同关键字的记录
经过排序这些记录的相对次序保持不变
即在原序列中 r [ i ] = r [ j ] , r [ i ] r [ j ] 之前
在排序后的序列中r [ i ] 仍在 r [ j ] 之前
称这种排序算法是稳定的否则称为不稳定的

                 

内部排序

数据元素全部放在内存中的排序

                 

外部排序

数据元素太多不能同时放在内存中

根据排序过程的要求不能在内外存之间移动数据的排序

                

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                 

常见排序算法的实现

(详细解释在图片的注释中,代码分文件放下一标题处)

                   

一、插入排序

                        

插入排序 -- 直接插入排序

直接插入排序是一种简单的插入排序法

                 

该算法基本思想:

待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中

直到所有的记录插入完为止得到一个新的有序序列
(想象我们玩扑克牌时给扑克牌大小排序就用了插入排序的思想

                      

实现思路:

插入第 i(i>=1) 个元素时
前面的 array[0]array[1],…,array[i-1] 已经排好序
此时 array[i] 的排序码 array[i-1]array[i-2],… 的排序码顺序进行比较
找到插入位置后 array[i] 插入原来位置上的元素顺序后移覆盖

                     

直接插入排序的特性总结:
  • 元素越接近有序直接插入排序算法时间效率越高 -- 最高可达O(N)
                            
  • 该算法时间复杂度O(N^2) -- 最坏的情况下(逆序)
                                
  • 该算法空间复杂度O(1)
                          
  • 该算法稳定性稳定
                      

---------------------------------------------------------------------------------------------

                       

InsertSort函数 -- 直接插入排序实现函数

  • 使用for循环进行循环插入排序
    设置前元素” 和 “后元素
                           
  • for循环中
    使用while循环后元素寻找合适位置
    找到后再将后元素插入
    之后再次进行for循环让下个后元素插入合适位置
图示:

该函数执行逻辑图:

对应函数测试:

            

            

---------------------------------------------------------------------------------------------

            

插入排序 -- 希尔排序(缩小增量排序)

希尔排序又称缩小增量法

             

该算法基本思想:

先选定一个整数gap值待排序文件中所有记录分成gap个组

所有距离为gap的记录分在同一组内,并对每一组内的记录进行直接插入排序

然后换个整数gap值再取gap组重复上述分组和排序的工作

gap=1 所有记录在同一组内时已经排好序了

               

希尔排序的特性总结:
  • 希尔排序直接插入排序的优化
                  
  • gap>1 时都是在进行预排序,目的是让数组更接近于有序
    gap==1 数组已经接近有序的了,这样再进行直接插入排序就会很快
    这样整体而言,可以达到优化的效果
                                  
  • 希尔排序的时间复杂度不好计算,因为gap的取值方法很多导致很难去计算
    因此在一些书中给出的希尔排序的时间复杂度也不固定,
    该函数大概的时间复杂度为:O(N^1.3)
                           
  • 该算法稳定性不稳定
                             

---------------------------------------------------------------------------------------------

                       

ShellSort函数 -- 希尔排序实现函数

  • 核心实现操作还是直接插入排序
    但是在对所有值进行直接插入排序先进行多次预排序操作
    预排序也是用直接插入排序完成)
    让数组达到尽量有序的状态
                  
  • 定义gap值变量,使用while循环控制多次预排序
    (当gap==1时,就相当于直接插入排序
                    
  • while循环中内嵌for循环完成当前gap组”的预排序
                     
  • 再内嵌for循环完成当前gap组其中一组的预排序
    (通过直接插入排序的方式实现)
                    
    • 最后再内嵌while循环配合完成直接插入排序
图示:

该函数执行逻辑图:

对应函数测试:

                     

                     


                    

二、选择排序

基本思想:

每一趟排序从待排序的数组元素中分别选择出最小最大的一个元素
再分别存放在数组的起始位置尾部位置
直到全部待排序的数组元素排序完成

                

                

选择排序 -- 直接选择排序

                    

该算法基本思想:

元素集合 array[i] -- array[n-1] 选择获取当前最小值元素当前最大值元素
当前最小值元素交换后放到当前数组起始位置
当前最大值元素交换后放到当前数组尾部位置

在剩余的 array[i+1] -- array[n-2] 集合中,重复上述操作直到集合剩余1个元素
               

直接选择排序的特性总结:
  • 直接选择排序比较好理解,但是效率不高实际很少使用
                      
  • 该算法时间复杂度O(N^2)
                         
  • 该算法空间复杂度O(1)
                       
  • 该算法稳定性不稳定
                         

---------------------------------------------------------------------------------------------

                       

SelectSort函数 -- 直接选择排序实现函数

  • 定义 数组开始(初始)位置下标begin 数组尾部(结束)位置下标end 变量
    使用while循环控制多趟直接选择排序
                        
  • (在while循环中完成一趟直接选择排序
    定义 存放当前最小值下标mini 存放当前最大值下标maxi 变量
    内嵌for循环遍历一次当前数组找到当前最大值当前最小值
                       
  • while循环中for循环外:)
    将找到的当前数组最小值放入数组起始左边位置
    当前数组最大值放入数组尾部右边位置,
    完成两值的排序后调整 begin end 变量缩小数组范围准备下趟直接选择排序
图示:

该函数执行逻辑图:

对应函数测试:

            

            

---------------------------------------------------------------------------------------------

            

选择排序 -- 堆排序

是一种完全二叉树
可以使用堆中的向下调整操作对普通数组进行排序升序降序

                   

堆排序往期博客中已有详细描述:

【数据结构初阶】七、非线性表里的二叉树(堆的实现 -- C语言顺序结构)-CSDN博客

(包含堆排序实现函数图示对应函数执行逻辑图函数测试原代码

                     

                     


                    

三、交换排序

基本思想:

所谓交换,就是根据序列中两个记录键值的比较结果交换这两个记录在序列中的位置

             

交换排序的特点:

键值较大的记录序列的尾部移动键值较小的记录序列的前部移动

                      

                      

交换排序 -- 冒泡排序

                     

该算法基本思想:

数组中的元素1元素2进行比较,如果元素1大于元素2,则交换两者位置

比较此时的元素2元素3,如果元素2大于元素3,则交换两者位置

再比较此时的元素3元素4……

一趟冒泡排序完成后,就能完成当前数组中最大值的排序排在尾部),
再进行下一趟冒泡排序前缩小数组排序范围排除已经排序好的最大值),

这样多趟冒泡排序完成后就能完成数组的排序

                     

冒泡排序的特性总结:
  • 冒泡排序是一种非常容易理解的排序
                      
  • 该算法时间复杂度O(N^2)
                  
  • 该算法空间复杂度O(1)
                          
  • 该算法稳定性稳定
                           

---------------------------------------------------------------------------------------------

                       

BubbleSort函数 -- 冒泡排序实现函数

  • 定义嵌套for循环完成冒泡排序
    外层for循环控制当前数组范围数组范围慢慢减小
    减到变成1时排序完成至少有两个数才能比较
                            
  • 内层for循环循环一趟完成当前数组范围内的最值的排序
                        
  • 当前冒泡排序过程中
    设置一个变量exchange记录当前一趟冒泡排序过程中是否有发生元素的交换
    趟冒泡排序后,如果没有任何元素发生交换
    说明目前已经排好序了,那就直接终止之后的冒泡排序
图示:

该函数执行逻辑图:

对应函数测试:

                 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                      

对应代码:

Sort.h -- 排序头文件

#pragma once//包含之后所需头文件:
#include <stdio.h>//打印数组函数:
void PrintArray(int* a, int n);//直接插入排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void InsertSort(int* a, int n);//希尔排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void ShellSort(int* a, int n);
//1、预排序:分组排,间隔为gap(间距间隔)分为一组
//				预排序意义:
// 让大的数更快的到数组后面,小的数更快的到数组前面,
// gap值越大“跳”得越快,但是越不接近有序
// gap值越小“跳”得越慢,但是越接近有序
// 当gap==1时,就相当于直接插入排序
//2、直接插入排序//冒泡排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void BubbleSort(int* a, int n);	//直接选择排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void SelectSort(int* a, int n);

            

            

---------------------------------------------------------------------------------------------

            

Sort.c -- 排序函数实现文件

#define _CRT_SECURE_NO_WARNINGS 1//包含排序头文件:
#include "Sort.h"//打印数组函数:
void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("");
}//直接插入排序函数(升序):
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void InsertSort(int* a, int n)
{//使用for循环进行循环插入排序:/*要取“前后元素”,“后元素”要依次和“前面所有元素”进行比较,直到“后元素”找到合适位置并插入,而“后元素”下标最大为[n-1],所以“前元素”下标最大为[n-2]*/for (int i = 0; i < n - 1; i++)//循环到 i = n-2  --  “前元素”下标最大为[n-2]:{//遍历下标的起始位置从 0 开始,到 n-2 结束:int end = i; //“前元素”//保存end下标元素的后一个元素:int tmp = a[end + 1]; //“后元素”//使用while循环为“后元素”寻找合适位置://(“后元素”循环和其前面所有元素进行比较,直到找到合适位置)while (end >= 0)//“前面所有元素”:下标 >=0 时就还有 “前元素”,//那“后元素”就需要继续进行比较:{if (tmp < a[end])//“后元素” 小于 “前元素”:{//那就将“前元素(较大)”往后插入(覆盖):a[end + 1] = a[end];//a[end + 1],被覆盖的元素还保留在tmp中,//所以不用担心覆盖后找不到“后元素”}else//"后元素" 大于等于 "前元素":{//说明“后元素”的“前面较大元素”都已经往后覆盖完成了,//找到了"后元素"的恰当位置,//break退出循环将“后元素”tmp插入该位置break;}end--;//当前end--,下次循环判断“前前元素”需不需要再往前覆盖,//end减到-1退出while循环的话,说明“后元素”是数组中最小的元素,//导致其前面所有元素都需要往后覆盖挪出位置}//注意,合适的位置是[end + 1],//因为"后元素" 大于等于 "前元素"的话,//那“后元素”就理应排在“前元素”后面,即[end + 1],a[end + 1] = tmp;//如果是end减到-1退出的while循环,//那[end + 1]就等于0,即数组首元素位置,//让“后元素”排在数组首元素位置}
}
//时间复杂度:
//O(N^2) -- 逆序(最坏情况)
//O(N) -- 顺序有序
//冒泡排序和插入排序论时间复杂度它们是同一档次,
//但在细节上,如局部有序,插入排序会更优//希尔排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)·
void ShellSort(int* a, int n)
{//定义分组间隔和分组个数:int gap = n;//只要当前预排序gap值还没到1,//while循环就继续循环进行预排序:while (gap > 1){//变化gap值进行多次预排序,//让数组越来越接近有序:gap = gap / 2;//当 gap > 1 时就是预排序//当 gap == 1 时就是插入排序//这个for循环控制 “当前gap组” 的排序://(一组“gap分”组排完再排另一组gap分组)for (int j = 0; j < gap; j++)/** 假设gap取3,* 就在数组中以3(gap)为间隔取数为一组(gap分组)* 总共取3(gap)组*/{//这个for循环控制gap组中其中一组的排序:for (int i = 0; i < n - gap; i += gap)/**					循环条件:n - gap  *控制“前元素end”范围,保证“后元素tmp”通过end取值时不出界*					迭代条件:i += gap*i每次迭代时就+gap,实现以gap为间隔取数为一组(gap分组)*/{//保存当前分组的“前元素”(记录):int end = i;//保存当前分组的“后元素”(记录):int tmp = a[end + gap];//使用while循环为“后元素”寻找合适位置://(“后元素”循环和其前面所有元素进行比较,直到找到合适位置)//(和直接插入类似,只是值与值间隔不同)while (end >= 0)//“前面所有元素”:下标 >=0 时就还有 “前元素”,//那“后元素”就需要继续进行比较:{if (tmp < a[end])//“后元素” 小于 “前元素”:{//(gap分组中:)//那就将“前元素(较大)”往后插入(覆盖):a[end + gap] = a[end];//a[end + gap],被覆盖的元素还保留在tmp中,//所以不用担心覆盖后找不到“后元素”end -= gap;//(gap分组中:)//当前end-=gap,下次循环判断“前前元素”需不需要再往前覆盖,//end减到<0时,退出while循环的话,说明“后元素”是数组中最小的元素,//导致其前面所有元素都需要往后覆盖挪出位置}else//"后元素" 大于等于 "前元素":{//说明“后元素”的“前面较大元素”都已经往后覆盖完成了,//找到了"后元素"的恰当位置,//break退出循环将“后元素”tmp插入该位置break;}}//注意,合适的位置是[end + gap],//因为"后元素" 大于等于 "前元素"的话,//那“后元素”就理应排在“前元素”后面,即[end + gap],a[end + gap] = tmp;//如果是 end减到<0 退出的while循环,//那[end + gap]就找到当前gap组首元素位置,//让“后元素”排在当前gap组首元素位置}}}
}//两值交换函数:
void Swap(int* x, int* y)
{//创建中间值进行值的交换:int tmp = *x;*x = *y;*y = tmp;
}//冒泡排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void BubbleSort(int* a, int n)
{/** 定义嵌套for循环完成冒泡排序:* 内层for循环一趟完成当前数组范围内的最值的排序* 外层for循环则控制当前数组范围* 数组范围慢慢减小,减到变成1时排序完成* (至少有两个数才能比较)*///这个for循环控制内嵌for循环的数组范围:for (int j = 0; j < n; j++){int exchange = 0; //如果没发生交换该变量就为0//内嵌for循环进行循环比较交换:for (int i = 1; i < n-j; i++)/**n-j :通过判断条件控制数组范围*因为一趟下来就完成一个当前最值的排序,*下次再排序的数组范围就要排除这个已经排好序的最值,*通过外部for循环的j来控制数组范围:*/{if (a[i - 1] > a[i])//如果“前元素” 大于 “当前元素”://( i 从1开始){//进行交换:Swap(&a[i - 1], &a[i]);exchange = 1;//如果发生了变化该变量就为1}}/** 内嵌for循环整个执行完就是一趟,* 当遇到最大值后,因为最大所以会一直被交换* 直到被交换至数组尾部,* 这就完成了当前数组最大值的排序*/if (exchange == 0)//一趟冒泡排序后,如果没有发生交换:{//说明目前已经排好序了,//就没必要再进行之后的冒泡排序了:break;} }
}//直接选择排序函数:
//第一个参数:接收要排序的数组首元素地址(a)
//第二个参数:接收该数组的长度(n)
void SelectSort(int* a, int n)
{/** 思路:* 排序一趟选出当前最小值下标和当前最大值下标,* 通过对应下标将最小值放“左边”,最大值放“右边”*///数组开始位置下标 -- 0int begin = 0;//数组尾部(结束)位置下标 -- n-1int end = n - 1;//使用while循环控制多趟直接选择排序:while (begin < end)/** 只要 begin 还小于 end,左右下标就还没重合* begin 和 end 之间就还有元素要被排序*/{//对当前数组范围进行一趟直接选择排序://存放当前最小值下标:int mini = begin; //默认为下标0//存放当前最大值下标:int maxi = begin; //默认为下标0//使用for循环遍历一次当前数组,//找到当前最大值和当前最小值:for (int i = begin+1; i <= end; i++)/** mini 和 maxi 默认下标都是0* 所以循环时下标从[begin+1]开始,等于[n-1]结束*/{//选出当前最大值下标:if (a[i] > a[maxi])//如果“i下标元素”大于“maxi下标元素”:{//将较大值下标i赋给maxi下标:maxi = i;}//选出当前最小值下标:if (a[i] < a[mini])//如果“i下标元素”小于“mini下标元素”:{//将较小值下标i赋给mini下标:mini = i;}} //(for循环中)//将找到的当前数组最小值放入数组起始(左边)位置:Swap(&a[begin], &a[mini]);/** 注:如果begin下标元素为最大值,* 那么maxi下标也会指向该元素,即begin == maxi,* 当begin元素和mini交换后(只是值交换),* begin 和 maxi下标还是重叠在原位置,指向交换后的mini元素* 此时如果再执行 Swap(&a[end], &a[maxi]);* 就反而会将最小值移到数组尾部去,* 所以要调整 begin==maxi 重叠的情况:*/if (maxi == begin)//排除maxi和begin下标重叠的情况:{//maxi==begin等于当前最大值下标,上面交换后,//当前最大值就在mini下标处,//那就把maxi最大值下标指向mini下标处即可:maxi = mini;}//将找到的当前数组最大值放入数组尾部(右边)位置:Swap(&a[end], &a[maxi]);/** 执行到这就选出了两个最值并放到了合适位置(一趟直接选择排序),* 调整 begin 和 end 下标(调整数组范围),数组范围往中间缩小,* 再开始新一趟直接选择排序:*/++begin;--end;} //(while循环中)
}
//时间复杂度:O(N^2)

            

            

---------------------------------------------------------------------------------------------

            

Test.c -- 排序测试文件

#define _CRT_SECURE_NO_WARNINGS 1//包含排序头文件:
#include "Sort.h"//插入排序测试:
void ISTest()
{//创建要进行插入排序的数组:int a[] = { 3,4,2,1,5 };//调用插入排序函数进行排序:InsertSort(a, 5);//循环打印排序后的数组:printf("使用直接插入排序后的数组:> ");for (int i = 0; i < 5; i++){printf("%d ", a[i]);}
}//希尔排序测试:
void SSTest()
{//创建要进行插入排序的数组:int a[] = { 9,1,2,5,7,4,8,6,3,5 };//调用希尔排序函数进行排序:ShellSort(a, sizeof(a) / sizeof(int));//使用自定义打印函数打印排序后数组:printf("使用希尔排序后的数组:> ");PrintArray(a, sizeof(a) / sizeof(int));
}//冒泡排序测试:
void BSTest()
{//创建要进行插入排序的数组:int a[] = { 9,1,2,5,7,4,8,6,3,5 };//调用冒泡排序函数进行排序:BubbleSort(a, sizeof(a) / sizeof(int));//使用自定义打印函数打印排序后数组:printf("使用冒泡排序后的数组:> ");PrintArray(a, sizeof(a) / sizeof(int));
}//直接选择排序测试:
void SlSTest()
{//创建要进行插入排序的数组:int a[] = { 9,1,2,5,7,4,8,6,3,5 };//调用直接选择排序函数进行排序:SelectSort(a, sizeof(a) / sizeof(int));//使用自定义打印函数打印排序后数组:printf("使用直接选择排序后的数组:> ");PrintArray(a, sizeof(a) / sizeof(int));
}int main()
{//ISTest();//SSTest();//BSTest();SlSTest();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/169176.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wps excel js编程

定义全局变量 const a "dota" function test() {Debug.Print(a) }获取表格中单元格内容 function test() {Debug.Print("第一行第二列",Cells(1,2).Text)Debug.Print("A1:",Range("A1").Text) }写单元格 Range("C1").Val…

iOS之某漫加密算法还原

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、抓包二、IDA反编译三、定位四、根据调用栈确定md5总结 前言 目标app:5ZKa5ryr 版本&#xff1a;2.8.0 工具&#xff1a;charles、frida 文章内容仅供参考学…

中国技术的对外输出:Telegram也开始搞小程序应用了

Telegram 宣布为其开发者提供了一项“能够在其中运行迷你应用”的新功能&#xff08; 迷你应用即 Mini App&#xff0c;下文中以“小程序”代替&#xff09;。 在 Telegram 的博客中&#xff0c;开发人员介绍可以使用 JavaScript 构建自己的迷你应用 在一篇博客文章中&#xf…

SpringBoot整合注解式mybatis

1. 创建Spring Boot项目&#xff1a; 创建一个Spring Boot项目&#xff0c;可以使用Spring Initializer或手动创建 2. 添加依赖&#xff1a; 在pom.xml文件中&#xff0c;添加Spring Boot、MyBatis和数据库驱动程序的依赖&#xff0c;就像之前所示。 <dependencies><…

Android JKS MD5 SHA1 公钥生成 私钥生成 APP备案 内容获取

1 查看 jks keytool -list -v -keystore /Users/lipengfei/Desktop/android/androidproject.jks密钥库类型: jks 密钥库提供方: SUN您的密钥库包含 1 个条目别名: ddgj 创建日期: 2018-11-16 条目类型: PrivateKeyEntry 证书链长度: 1 证书[1]: 所有者: CNcn, OUcn, Ocn, Lcn,…

智安网络|从区块链到社交网络:解析去中心化的意义与应用

在当今数字化的世界中&#xff0c;一个越来越常见的概念是“去中心化”。从区块链技术到金融系统&#xff0c;从社交网络到数据存储&#xff0c;去中心化被认为是一种前所未有的方式来重新定义和改变传统的中心化结构。那么&#xff0c;去中心化到底是什么&#xff1f; 首先&a…

Spring Cloud 之 Sentinel简介与GATEWAY整合实现

简介 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 熔断 …

MES生产管理系统与供应链协同管理

MES生产管理系统在制造业中发挥着越来越重要的作用&#xff0c;它与供应链管理密切相关&#xff0c;对于提高供应链的协同和优化有着重要的意义。本文将探讨MES管理系统与供应链管理之间的关系&#xff0c;包括实时数据共享、生产计划协调和供应链效率提升等方面。 MES系统能够…

LeetCode 11. 盛最多水的容器

盛水最多的容器 题目链接 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。…

Nginx Proxy代理

代理原理 反向代理产生的背景&#xff1a; 在计算机世界里&#xff0c;由于单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当用户的接入请求蜂拥而入时&#xff0c;会造成服务器忙不过来的局面&#xff0c;可以使用多个服务器来共同分担成…

【经典PageRank 】02/2 算法和线性代数

系列前文&#xff1a;【经典 PageRank 】01/2 PageRank的基本原理-CSDN博客 一、说明 并非所有连接都同样重要&#xff01; 该算法由 Sergey 和 Lawrence 开发&#xff0c;用于在 Google 搜索中对网页进行排名。基本原则是重要或值得信赖的网页更有可能链接到其他重要网页。例…

【小程序】实现一个定制的音乐播放器

应用地址&#xff1a;https://spacexcode.com/player 介绍 这是为自己制作的一个在线 Web 版的音乐播放器。众所周知&#xff0c;现在市面上的所有的音乐平台都是会员制。而免费的资源却分散在网络上的各个角落&#xff0c;为此&#xff0c;我收集了自己 喜欢的音乐&#xff0…

选购采购管理软件,首先考虑这5个功能

虽然采购已经达到了数字化的临界点&#xff0c;但企业在接受新的解决方案时却犹豫不决。德勤一份全球首席采购官调查显示&#xff0c;只有 18% 的组织制定了数字化采购战略。 自动化采购任务和优化采购到付款周期可以为企业节省大量金钱和时间。然而&#xff0c;通过过时的采购…

JVM、JRE、JDK

JVM JVM&#xff08;Java Virtual Machine&#xff09;是Java虚拟机的缩写&#xff0c;他是Java编程语言运行时环境&#xff0c;负责执行Java字节码。另外作为JVM虚拟机&#xff0c;它在各种操作系统上提供统一的平台&#xff0c;这帮助Java应用程序可以独立于操作系统底层运行…

v-for列表渲染

一、v-for迭代数组 <li v-for"(e,index) in emp" :key"e.id">编号{{index1}} 名字{{e.name}} 年龄{{e.age}} </li> e 是循环数组中的每个元素的别名index 是当前循环的下表&#xff0c;从0开始:key 的作用&#xff1a; 是为了给 Vue 一个提示…

【AI视野·今日Sound 声学论文速览 第二十九期】Thu, 19 Oct 2023

AI视野今日CS.Sound 声学论文速览 Thu, 19 Oct 2023 Totally 9 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Take the aTrain. Introducing an Interface for the Accessible Transcription of Interviews Authors Armin Haberl, J rgen Flei , Dom…

[C++] 类与对象(上)

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C和Linux &#x1f33c;博客专栏&#xff1a;C入门 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&#x1f3fb; …

设计模式篇---组合模式

文章目录 概念结构实例总结 概念 组合模式&#xff1a;组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。 当我们开发中遇到树形结构的业务时&#xff0c;可以考虑使用组合模式。&#xff08;我也没有想明白为啥…

前端如何直接上传文件夹

前面写了一篇仿写el-upload组件&#xff0c;彻底搞懂文件上传&#xff0c;实现了选择/拖拽文件上传&#xff0c;我们经常看到一些网站支持直接选择整个文件夹上传&#xff0c;例如&#xff1a;宝塔面板、cloudflare托管、对象存储网站等等需要模拟文件路径存储文件的场景。那是…

px4仿真实现无人机自主飞行

一,确定消息类型 无人机通过即在电脑是现自主飞行:思路如下。 通过Mavros功能包,将ROS消息转换为Mavlink消息。实现对无人机的控制。 几种消息之间的关系如下: 对于ROS数据,就是我们机载电脑执行ROS系统的数据。 对于Mavros消息,就是Mavros功能包内部的消息。查询网站…