总结一些排序算法的原理和实现

部分排序算法的原理和实现 文章目录冒泡排序选择排序 本篇博客主要讲解一下,冒泡排序,插入排序,选择排序,快速排序,归并排序,桶排序,计数排序,基数排序。我会讲解一下实现原理,以及时间复杂度,空间复杂度,并贴出来我实现的核心代码。其他的排序算法,我会以后慢慢加上去。 冒泡排序 冒泡排序只会比较相邻的两个数据,每次冒泡都会对相邻的两个元素比较,看是否满足大小条件,如果不满足条件,就交换元素。一个数组长度为n,n次操作,就完成n... 阅读详情

这两天看了一下常用的排序算法,并进行了简单的实现。

其原理和实现总结如下:

 

简介:

    排序是数据处理中经常使用的一种重要运算,并且排序本身对推动算法分析的发展也起很大作用。

    1、插入排序(直接插入排序、折半插入排序、希尔排序);
    2、交换排序(起泡排序、快速排序);
    3、选择排序(直接选择排序、堆排序);
    4、归并排序;
    5、基数排序;

 

一.直接插入排序

    1.直接插入排序的基本思想 
            直接插入排序(Straight Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。

    2.算法实现:

  1. #include<iostream>
  2. using namespace std;
  3. void insertSort(int a[], int n)
  4. {
  5.     int i, j;
  6.     int t;  
  7.     for(i = 1; i < n; i++)
  8.     {
  9.         t = a[i];
  10.         j = i - 1;
  11.         while((j >= 0)&&(t < a[j])) 
  12.         {
  13.             a[j + 1] = a[j];
  14.             j--;    
  15.         }
  16.         a[j + 1] = t;
  17.     }
  18. }
  19. int main()
  20. {
  21.     int a[5] = {5,4,2,8,6}; 
  22.     insertSort(a, 5);
  23.     for(int k = 0; k < 5; k++)
  24.     {
  25.         cout<<a[k]<<" "<<endl;  
  26.     }
  27.     return 0;
  28. }

    3.效率

        (1).直接插入排序的时间复杂度为O(n2)。

        (2).首先从空间来看,它只需要一个元素的辅助空间,用于元素的位置交换O(1)

        (3).插入排序是稳定的,因为具有同一值的元素必然插在具有同一值得前一个元素的后面,即相对次序不变.           

        (4).插入排序是一种简单的排序方法,他不仅适用于顺序存储结构(数组),而且适用于链接存储结构,不过在链接存储结构上进行直接插入排序时,不用移动元素的位置,而是修改相应的指针。

 

二.冒泡排序

 

    1.冒泡排序的基本思想

        设待排序n个元素存放在数组a[n]中,无序区范围初始为(a(0),a(1),a(2),...,a[n-1]),冒泡排序方法是在当前无序区内,从最上面的元素a[0]开始,对每两个相邻的元素a[i+1]和a[i](i=0,1,...,n-1)进行比较,且使值较小的元素换至值较大的元素之上(若a[i]>a[i+1],则a[i]和a[i+1]的值互换),这样经过一趟冒泡排序后,假设最后下移的元素为a[k],则无序区中值较大的几个元素到达下端并从小到大依次存放在a[k+1],a[k+2],...a[n-1]中,这样无序区范围变为(a[0],a[1],a[2],...,a[k])。在当前无序区内进行下一趟冒泡排序。这个过程一直到某一趟排序中不出现元素交换的动作,排序结束。整个排序过程最多执行n-1遍。这种排序方法是通过相邻元素之间的比较与交换,使值较小的元素逐渐从后部移向前部(从下标较大的单元移向下标较小的单元),就象水底下的气泡一样逐渐向上冒。

    2.排序方法

        将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
        (1)初始
         R[1..n]为无序区。

        (2)第一趟扫描
         从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key<R[j].key,则交换R[j+1]和R[j]的内容。
         第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。

        (3)第二趟扫描

         扫描R[2..n]。扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……
         最后,经过n-1 趟扫描可得到有序区R[1..n]
          注意:
         第i趟扫描时,R[1..i-1]和R[i..n]分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时,该区中最轻气泡飘浮到顶部位置R[i]上,结果是R[1..i]变为新的有序区。

     

    3.算法实现

  1. #include<iostream>
  2. using namespace std;
  3. void BubbleSort(int a[], int n)
  4. {
  5.     int i, j;
  6.     bool exchange;
  7.     for(i = 0; i < n; i++)
  8.     {       
  9.         for(j = n - 1; j >= i; j--)//对当前无序区域R[i...n]自下向上扫描
  10.         {
  11.             if(a[j + 1] < a[j])
  12.             {
  13.                 int tem;
  14.                 tem = a[j + 1];
  15.                 a[j + 1] = a[j];
  16.                 a[j] = tem;         
  17.             }   
  18.         }   
  19.     }   
  20. }
  21. int main()
  22. {
  23.     int a[10] = {10,2,36,12,1,25,42,13,21,11};
  24.     BubbleSort(a, 10);
  25.     for(int k = 0; k < 10; k++)
  26.     {
  27.         cout<<a[k]<<" ";    
  28.     }   
  29.     cout<<endl;
  30.     return 0;
  31. }

    4.算法分析

        (1)算法的最好时间复杂度
         若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:
            Cmin=n-1
            Mmin=0。
         冒泡排序最好的时间复杂度为O(n)。

        (2)算法的最坏时间复杂度

         若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
            Cmax=n(n-1)/2=O(n2)
            Mmax=3n(n-1)/2=O(n2)
         冒泡排序的最坏时间复杂度为O(n2)。

        (3)算法的平均时间复杂度为O(n2)

         虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。

        (4)算法稳定性

         冒泡排序是就地排序,且它是稳定的。

 

三.直接选择排序

    1、直接选择排序的基本思想
     n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
         ①初始状态:无序区为R[1..n],有序区为空。
         ②第1趟排序
         在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
      ……
         ③第i趟排序
      第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录R[k],将它与无序区的第1个记录R[i]交换,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
         这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。

    2.算法实现      

  1. #include<iostream>
  2. using namespace std;
  3. void SelectionSort(int R[], int n)
  4. {
  5.     int i, j, k;
  6.     for(i = 0; i < n; i++)
  7.     {
  8.         k =i;
  9.         for(j = i + 1; j < n; j++)  
  10.         {
  11.             if(R[j] < R[k])
  12.             {
  13.                 k = j;  
  14.             }           
  15.         }
  16.         if(k != i)
  17.         {
  18.             int tem = R[i];
  19.             R[i] = R[k];
  20.             R[k] = tem; 
  21.         }
  22.     }
  23. }
  24. int main()
  25. {
  26.     int a[10] = {10,2,36,12,1,25,42,13,21,11};
  27.     SelectionSort(a, 10);
  28.     for(int m = 0; m < 10; m++)
  29.     {
  30.         cout<<a[m]<<" ";    
  31.     }   
  32.     cout<<endl;
  33.     return 0;
  34. }

    3.算法分析
        (1)关键字比较次数
         无论文件初始状态如何,在第i趟排序中选出最小关键字的记录,需做n-i次比较,因此,总的比较次数为:
             n(n-1)/2=0(n2)

        (2)记录的移动次数
         当初始文件为正序时,移动次数为0
         文件初态为反序时,每趟排序均要执行交换操作,总的移动次数取最大值3(n-1)。
         直接选择排序的平均时间复杂度为O(n2)。

        (3)直接选择排序是一个就地排序

        (4)稳定性分析
         直接选择排序是不稳定的
     
四.快速排序

 

 

    1.算法思想

        采用了一种分治的策略,通常称其为分治法

        (1) 分治法的基本思想
         分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

        (2)快速排序的基本思想
         设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:
            ①分解:
   
         在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
                 注意:
             划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
             R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
                  其中low≤pivotpos≤high。
            ②求解:
     
        通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
            ③组合:
   
         因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
    2、快速排序算法

  1. #include<iostream>
  2. using namespace std;
  3. int Partition(int R[], int i, int j)
  4. {
  5.     int pivot = R[i];
  6.     while(i < j)
  7.     {
  8.         while(i < j && R[j] >= pivot)
  9.         {
  10.             j--;    
  11.         }
  12.         if(i < j)
  13.         {
  14.             R[i++] = R[j];  
  15.         }
  16.         while(i < j && R[i] <= pivot)
  17.         {
  18.             i++;    
  19.         }
  20.         if(i < j)
  21.         {
  22.             R[j--] = R[i];  
  23.         }
  24.     }
  25.     R[i] = pivot;
  26.     return i;
  27. }
  28. void QuickSort(int R[], int low, int high)
  29. {
  30.     int pivotpos;//划分后的基准记录的位置
  31.     if(low < high)
  32.     {
  33.         pivotpos = Partition(R, low, high);//对R[low..high]做划分
  34.         QuickSort(R, low, pivotpos - 1);
  35.         QuickSort(R, pivotpos + 1, high);
  36.     }
  37. }
  38. int main()
  39. {
  40.     int a[10] = {10,2,36,12,1,25,42,13,21,11};
  41.     QuickSort(a, 0, 9);
  42.     for(int m = 0; m < 10; m++)
  43.     {
  44.         cout<<a[m]<<" ";    
  45.     }   
  46.     cout<<endl;
  47.     return 0;
  48. }

    3.算法分析
     快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。

        (1)最坏时间复杂度
         最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。
         因此,快速排序必须做n-1次划分,第i次划分开始时区间长度为n-i+1,所需的比较次数为n-i(1≤i≤n-1),故总的比较次数达到最大值:
               Cmax = n(n-1)/2=O(n2)
         如果按上面给出的划分算法,每次取当前无序区的第1个记录为基准,那么当文件的记录已按递增序(或递减序)排列时,每次划分所取的基准就是当前无序区中关键字最小(或最大)的记录,则快速排序所需的比较次数反而最多。

        (2) 最好时间复杂度
         在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:
            0(nlgn)
        注意:
         用递归树来分析最好情况下的比较次数更简单。因为每次划分后左、右子区间长度大致相等,故递归树的高度为O(lgn),而递归树每一层上各结点所对应的划分过程中所需要的关键字比较次数总和不超过n,故整个排序过程所需要的关键字比较总次数C(n)=O(nlgn)。
         因为快速排序的记录移动次数不大于比较的次数,所以快速排序的最坏时间复杂度应为0(n2),最好时间复杂度为O(nlgn)。

        (3)基准关键字的选取
         在当前无序区中选取划分的基准关键字是决定算法性能的关键。
      ①"三者取中"的规则
         "三者取中"规则,即在当前区间里,将该区间首、尾和中间位置上的关键字比较,取三者之中值所对应的记录作为基准,在划分开始前将该基准记录和该区伺的第1个记录进行交换,此后的划分过程与上面所给的Partition算法完全相同。

      
②取位于low和high之间的随机数k(low≤k≤high),用R[k]作为基准
         选取基准最好的方法是用一个随机函数产生一个取位于low和high之间的随机数k(low≤k≤high),用R[k]作为基准,这相当于强迫R[low..high]中的记录是随机分布的。用此方法所得到的快速排序一般称为随机的快速排序。具体算法【参见教材】
        注意:
         随机化的快速排序与一般的快速排序算法差别很小。但随机化后,算法的性能大大地提高了,尤其是对初始有序的文件,一般不可能导致最坏情况的发生。算法的随机化不仅仅适用于快速排序,也适用于其它需要数据随机分布的算法。

        (4)平均时间复杂度
         尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。

        (5)空间复杂度
         快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为O(lgn),故递归后需栈空间为O(lgn)。最坏情况下,递归树的高度为O(n),所需的栈空间为O(n)。

        (6)稳定性
         快速排序是非稳定的

 

 

五.希尔排序

 

    希尔排序(Shell Sort)是插入排序的一种

    1.基本思想 
        希尔排序(Shell Sort)又称为“缩小增量排序”。是1959年由D.L.Shell提出来的。该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
具体做法:首先确定一组增量d0,d1,d2,d3,...,dt-1()其中n>d0>d1>...>dt-1=1),对于i=0,1,2,...,t-1,依次进行下面的各趟处理:根据当前增量di将n个元素分成di个组,每组中元素的下标相隔为di;再对各组中元素进行直接插入排序.
        2、下面给出希尔排序算法的执行过程。

            (1)采用希尔排序法排序的各趟的结果如下:
                初始:503,17,512,908,170,897,275,653,426,154,509,612,677,765,703,94
                第1趟{d1=8}:426,17,509,612,170,765,275,94,503,154,512,908,677,897,703,653
                第2趟(d2=4):170,17,275,94,426,154,509,612,503,765,512,653,677,897,703,908
                  第3趟(d3=2):170,17,275,94,426,154,503,612,509,653,512,765,677,897,703,908
                第4趟(d1=1):17,94,154,170,275,426,503,509,512,612,653,677,703,765,897,908

    2.希尔排序算法实现

  1.  

 

    3.希尔排序的算法分析
        1.增量序列的选择
         Shell排序的执行时间依赖于增量序列。
         好的增量序列的共同特征:
      ① 最后一个增量必须为1;
      ② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
         有人通过大量的实验,给出了目前较好的结果:当n较大时,比较和移动的次数约在nl.25到1.6n1.25之间。

        2.Shell排序的时间性能优于直接插入排序
         希尔排序的时间性能优于直接插入排序的原因:
      ①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
      ②当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。
      ③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。
         因此,希尔排序在效率上较直接插人排序有较大的改进。

        3.稳定性
         希尔排序是不稳定的。参见上述实例,该例中两个相同关键字49在排序前后的相对次序发生了变化。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

 

 

 

 

 

C语言实现直接选择排序 直接选择排序是一种简单的排序算法。它的工作原理是每一次从未排序部分选出最小(或最大)的一个元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。这种算法的时间复杂度为O(n^2),其中n是待排序元素的数量,因此在处理大数据集时效率较低。然而,它的实现简单,对于小规模的数据排序是一个不错的选择。直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用时间复杂度:O(N^2)空间复杂度:O(1) 阅读详情

相关推荐

Unity半透明物体景深失效?教你用双材质球方案完美解决(附完整Shader代码)

本文深入剖析了Unity中半透明物体导致景深效果失效的根本原因,即半透明物体默认不写入摄像机深度图。针对此问题,文章详细介绍了稳定高效的“双材质球”解决方案,通过为物体附加一个仅写入深度信息的不可见材质,完美修复景深效果,并提供了完整的Shader代码与实现脚本。

weixin_29010003的博客 383

选择排序的实现

直接选择排序的思想非常简单,就是在一组数据中先遍历一边数组选出最大的然后往后排,再遍历一边数组,选出次大的,再往后排,以此类推,最后只剩下最小的,排到第一个。这是直接选择排序的思想。堆排是利用了二叉树的数据结构思想来进行排序的,首先要建立一个堆,这样才能实现排序。1. 直接选择排序思考非常好理解,但是效率不是很好。选择排序分为两种,分别为直接选择排序和堆排序。2. 时间复杂度:O(N*logN)2. 时间复杂度:O(N^2)3. 空间复杂度:O(1)3. 空间复杂度:O(1)4. 稳定性:不稳定。

weixin_66828150的博客 475

2026 最新实战教程:AI 重构开发全流程(从需求→上线→运维)

1)做什么系统2)技术栈3)功能模块4)部署要求plaintext我要做一个:待办事项(Todo)全栈应用技术栈:前端:React + TypeScript + Tailwind后端:Node.js + Express + MongoDB部署:Docker + 本地运行(后续可上云)功能:- 增删改查任务- 任务状态切换(完成/未完成)- 简单错误处理请按企业级标准生成:架构设计 + 全部代码 + 接口文档 + 启动命令。

qq_35779316的博客 1703

选择排序

public class 选择排序 { /** * 选择排序的思想非常直接,不是要排序么?那好,我就从所有序列中先找到最小的,然后放到第一个位置。 * 之后再看剩余元素中最小的,放到第二个位置……以此类推,就可以完成整个的排序工作了。可以很清楚的发现,选择排序是固定位置,找元素。 * 相比于插入排序的固定元素找位置,是两种思维方式。不过条条大路通罗马,两者的目的是一样的。 * @

mantantan的博客 541

宇树G1开发实践--PPT汇报(基础版)

本文介绍了一套基于宇树G1人形机器人的PPT自动演示系统,可实现"一键启动、自动演讲"功能。系统通过多线程同步技术,将音频播放与机器人动作完美结合,支持12种预设社交互动动作。硬件依赖宇树G1机器人、外接音响和网络连接,软件采用Python SDK和ALSA音频工具。核心功能包括音频文件自动排序、外接音响播放控制、机器人动作执行及音画同步。使用时需配置网络接口和音频设备号,运行后自动按顺序播放音频并执行随机动作。系统特别强调了安全注意事项,并提供了常见问题解决方案,适用于展会、汇报等需要

m0_47999117的博客 510

实战:批量抓取免费代理IP全流程(附自动验证+失效剔除,爬虫抗封必备)

本文分享了一套从免费代理IP中筛选可用高匿代理的实用方案。作者通过半年实践,总结出"批量抓取+精准验证+动态维护"的方法,能从2000条免费IP中筛选出30-50条可用代理,满足中小规模爬虫需求。 方案包含四个核心环节: 多源代理抓取:针对快代理、西刺代理等不同网站定制解析规则 三层验证机制:检查有效性、匿名度和响应速度 代理池自动维护:实时淘汰失效IP Scrapy整合实战:提供可直接复用的代码 文章特别指出免费代理的三大痛点:存活率低(80%10分钟内失效)、匿名性差(仅5%是高匿代

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1602

直接选择排序算法

它的基本思想是第一次从待排序的序列中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。使用直接选择排序算法将数组{36,80,45,66,22,9,16,36}进行升序排序。在直接选择排序的过程中,只需要一个元素大小的辅助空间用于存放待插入的元素,因此空间复杂度为。每一次循环都选出未排序号序列中最小(大)元素,然后放在已排序好的末尾。次交换,即移动次数最多。...

Vinjcent 4354

linux系统宝塔服务器temp文件夹里总是被上传病毒php脚本

服务器时不时的会发送短信说你服务器有病毒,找到了这个tmp文件,删除了之后又有了。确实是有很多人就这么无聊,每天都攻击你的服务器。找了很久的原因,网上也提供了一大堆方法,但都是很简陋的答案,具体怎么操作并没有说。没办法只能自己去排查这个问题。从两个角度来考虑,第一是服务器系统问题,比如宝塔的漏洞。但一时半会看不出问题来。只能去排查自己的项目代码。最后了解到代码确实是存在漏洞的。但代码中也确实了很多的校验,为什么会存在漏洞了?这就不得不从上传的过程开始说起。

guiplan 1497

经典算法学习之-----直接选择排序

算法是如何解决一类问题的明确规范,可以执行计算、数据处理、自动推理和其他任务。插入排序的基本思路是每次插入一个元素,每一趟完成对一个待排元素的放置,直到全部插入完成。直接插入排序直接插入排序是一种最简单的排序方法,过程就是将每个待排元素逐个插入到已经排好的有序序列中。折半插入排序由于在插入排序的过程中,已经生成了一个(排好的元素组成的)有序数列。所以在插入待排元素时可以使用折半查找的方式更快速的确定新元素的位置,当元素个数较多时,折半插入排序优于直接插入排序。希尔排序。......

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 843

OpenClaw + Antigravity + 飞书完整部署教程

在 Linux 服务器上部署 OpenClaw,使用 Antigravity 本地代理 AI 模型,并接入飞书实现 24 小时在线 AI 助手。

Maynor的博客 1788

MATLAB代码实现了一个柱塞泵配流盘过流面积的计算和可视化功能

该MATLAB代码实现了一个柱塞泵配流盘过流面积的计算和可视化功能。输出曲线可直接用于验证设计的合理性(如是否存在过流面积突变或不足)。的不同范围,选择对应的几何模型计算过流面积。通过分段逻辑计算柱塞腔在不同旋转角度(过流面积在特定条件下会被限制(如。),确保结果符合物理实际。条件分支,根据旋转角度。

huanghm88的专栏 583

Python之十大经典排序算法的实现和原理

一、冒泡排序 冒泡排序(Bubble Sort)是一种比较简单的排序算法,它重复地走访过要排序的元素,依次比较相邻两个元素,如果它们的顺序错误就把它们调换过来,直到没有元素再需要交换,排序完成。 冒泡排序的原理如下所示,数字表示的是数据序列原始的索引号: 算法过程: 比较相邻的元素,如果前一个比后一个大,就把它们两个对调位置; 对排序数组中每一对相邻元素做同样的工作,直到全部完成,此时最后的元素将会是本轮排序中最大的数; 对剩下的元素继续重复以上的步骤,直到没有任何一个元素需要比

╰つ栺尖篴夢ゞ 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

经典的排序算法原理和实现

第七章 排序 包括插入排序、希尔排序、堆排序、归并排序和快速排序的设计与实现 7.1 基础知识 被排序的对象属于Comparable类型。在这种条件下的排序叫做基于比较的排序。在默认排序不能满足需要求的情况下,可以用Comparator来重写排序算法。 7.2 插入排序 插入排序由N-1趟排序组成,对于p=1到N-1趟,插入排序保证从位置0到位置p上的元素为已排序状态。插入排序利用了如下事实:0...

qq_23594799的博客 247

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

常见排序算法原理和代码实现小结

前言 这里总结一下一些常见的排序算法的原理和代码实现,主要有五种排序算法,分别如下:冒泡排序,插入排序,选择排序,归并排序和快速排序。规定排序后的数据都是从小到大。 冒泡排序(Bubble Sort) 原理: 冒泡排序只比较相邻的两个数据,如果左边的数据比右边的数据大,则交换两个数据的位置,否则不用处理。之后继续与后面相邻的数据比较,这样一次遍历之后,最大的数据就到了数组的最尾端。重复 n 次遍历...

qq_31436337的博客 355

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

各种排序算法原理、代码实现总结和比较

排序是程序员开发中经常用到的问题,也是面试过程中经常被问到的内容。不同的排序算法有不同的应用场景,排序算法可以说是一项基本功,解决实际问题中经常遇到,针对实际数据的特点选择合适的排序算法可以使程序获得更高的效率,有时候排序的稳定性还是实际问题中必须考虑的。 本文小编为大家搜集一篇关于排序算法比较的文章,对常见的排序算法进行整理,包括:插入排序、选择排序、冒泡排序、快速排序、堆排序、归并排序、希尔排...

沧海一粟的博客 832

排序算法 | 简单选择排序算法原理及实现和优化

选择排序是一种非常简单的排序算法,就是在序列中依次选择最大(或者最小)的数,并将其放到待排序的数列的起始位置。 简单选择排序的原理 简单选择排序的原理非常简单,即在待排序的数列中寻找最大(或者最小)的一个数,与第 1 个元素进行交换,接着在剩余的待排序的数列中继续找最大(最小)的一个数,与第 2 个元素交换。以此类推,一直到待排序的数列中只有一个元素时为止。 也就是说,简单选择排序可分为两部分,...

挖坑埋你 4146

排序算法原理总结和Python实现

1 排序算法分类 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 相关概念: 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。 空

OuDiShenmiss的博客 429

C语言-七大排序算法实现和原理简述

基本概念: 排序:把一堆记录,按照其中某个或某些关键字的大小,递增或递减的排列起来的操作 稳定性:即经过排序后,记录中相同的关键字是否或保持原来的位置不做调整,如果位置不变则稳定,反之。 内部排序:数据元素在内存中的排序。 外部排序:数据元素太多了,不能同时放在内存中,根据排序要求不能在内存之间移动数据的排序。 排序算法一: 插入排序:(减治算法) ...

被封印的橘猫的博客 2561

理解计数排序算法的原理和实现

计数排序(Counting sort)是一种稳定的线性时间排序算法,其平均时间复杂度和空间复杂度为O(n+k),其中n为数组元素的个数,k为待排序数组里面的最大值。同样具有线性时间排序的算法还有桶排序和基数排序,这一点不要搞混。 计数排序不是基于比较的排序,所以它的排序效率是线性的,在特定的场景下(已知数组的最大最小值,切数组元素整体量不是很大的情况下)排序效率极高,而基于比较排序的...

三劫散仙 2383

常见排序算法原理和实现(二)

5.快速排序 快速排序法介绍: 快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 示意图: 代码实现: /** * */ package com.matao.sort; im...

Piratesa的博客 313

php选择排序算法原理_选择排序算法的介绍和实现

摘要:​选择排序法是一种不稳定的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序法是一种不稳定的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未...

weixin_34638776的博客 175

八大常用排序算法详细分析 包括复杂度,原理和实现

八大常用排序算法详细分析 包括复杂度,原理和实现如下: 1. 冒泡排序 1.1 算法原理: S1:从待排序序列的起始位置开始,从前往后依次比较各个位置和其后一位置的大小并执行S2。  S2:如果当前位置的值大于其后一位置的值,就把他俩的值交换(完成一次全序列比较后,序列最后位置的值即此序列最大值,所以其不需要再参与冒泡)。  S3:将序列的最后位置从待排序序列中移除。若移除后的待排序序列不为空则继续执行S1,否则冒泡结束。 1.2 算法实

有志者事竟成 3万+

Python实现几大排序算法的原理和实现

目录 冒泡排序 选择排序 插入排序 快速排序 希尔排序 归并排序 堆排序     这里用Python实现了简单的7种排序,还有三种可以参考下面文章 https://www.cnblogs.com/onepixel/p/7674659.html  https://www.jianshu.com/p/7d037c332a9d https://blog.youkuaiyun.com/s...

Deft_MKJing的博客 1167

最常见的几种排序算法原理和C#实现类库

本文尽量用简单直白通俗易懂深入浅出详实通透的手法将常见的几种排序算法的原理和代码呈现给众位,欢迎批评指教! 为简单起见,本文所述排序默认都以升序排序为例。(当然最后给出的源代码是升序降序都有的) 冒泡排序(Bubble sort) 冒泡排序每轮都得到数列中的最大值,同时将其置于最后,然后对剩余部分进行排序。 Bubble sort 1 /// &lt;summary...

weixin_34409703的博客 172

排序算法的原理和实现:冒泡排序、插入排序等

冒泡排序是一种简单的比较排序算法,它重复地交换相邻的两个元素,直到整个数组排序完成。冒泡排序的时间复杂度为O(n^2),其中n是待排序数组的长度。插入排序的时间复杂度为O(n^2),其中n是待排序数组的长度。它逐个将待排序的元素插入到已排序序列中的正确位置。1. 从数组的第一个元素开始,比较相邻的两个元素。2. 如果已排序序列中的元素大于待排序元素,则将已排序元素后移一个位置,为待排序元素腾出插入位置。3. 重复以上步骤,每次将待排序的元素减少一个,直到没有任何一对元素需要比较。// 当前待排序元素。

m0_75198698的博客 189
上一篇: C++中extern “C”含义深层探索[转载]
下一篇: C++ 指针与引用的区别
General1982
博客等级 码龄19年 14粉丝 20原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值