新闻资讯  快讯  焦点  财经  政策  社会
互 联 网   电商  金融  数据  计算  技巧
生活百科  科技  职场  健康  法律  汽车
手机百科  知识  软件  修理  测评  微信
软件技术  应用  系统  图像  视频  经验
硬件技术  知识  技术  测评  选购  维修
网络技术  硬件  软件  设置  安全  技术
程序开发  语言  移动  数据  开源  百科
安全防护  资讯  黑客  木马  病毒  移动
站长技术  搜索  SEO  推广  媒体  移动
财经百科  股票  知识  理财  财务  金融
教育考试  育儿  小学  高考  考研  留学
您当前的位置:首页 > IT百科 > 程序开发 > 算法

七大排序算法详细介绍

时间:2019-06-11 10:07:55  来源:  作者:

排序的相关概念

排序的分类

  • 根据在排序过程中带排序的记录是否全部被放置在内存中,排序分为:
  • 内排序
  • 外排序

1.内排序

内排序是在排序整个过程中,带排序的所有记录全部放置在内存中

影响内排序的主要因素

  • 时间性能。
  • (主要受比较移动两种操作的影响)
  • 辅助空间。
  • 算法的复杂性。

内排序的分类

根据排序过程中借助的主要操作,内排序分为:

  • 插入排序
  • 交换排序
  • 选择排序
  • 归并排序

2.外排序

外排序是由于排序的记录个数太多,不能同时放置在内存中,整个排序过程需要在内外存之间多次交换数据才能进行

按照算法的复杂度分类

  • 简单算法:
  • 冒泡排序、简单选择排序、直接插入排序。
  • 复杂排序:
  • 希尔排序、堆排序、归并排序、快速排序。

 


 

一、冒泡排序算法

因为在冒泡排序中要用到顺序表结构数组两元素的交换,先把这些写成函数

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
typedef struct {
 
 int r[MAXSIZE + 1];
 int length;
}SqList;
void swap(SqList *L, int i, int j){
 int temp = L->r[i];
 L->r[i] = L->r[j];
 L->r[j] = temp;
}

1.1 冒泡排序的初级版实现

冒泡排序(Bubble Sort)是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止

  •  
void BubblSort0(SqList *L){
 int i,j;
 
 for (i = 1; i < L->length; i++)
 for (j = i+1; j <= L->length; j++)
 if (L->r[i] > L->r[j])
 swap(L, i, j);
}

对于这段代码,是最简单的冒泡,其实就是最简单的交换排序而已。它的思路就是让每一个关键字,都和它后面的每一个关键字比较,如果大则交换,这样第一位置的关键字在第一次循环后一定变成最小值

假设我们待排序的关键字序列是{9,1,5,8,3,7,4,6,2}

  • 当i = 1时,9与1交换后,在第一位置的1与后面的关键字比较都小,因此它就只最小值。
  • 当i = 2时,第二位置先后由9换成5,换成3,换成2,完成了第二小的数字交换。
  • 后面数字依次比较和交换,得到最终结果。

 

算法 - 七大排序算法详细介绍

 

 

1.2 冒泡排序的实现

对于上面的算法,代码虽然简单易懂,但是效率非常低。可以改进成接下来的代码

  •  
void BubbleSort(SqList *L){
 int i,j;
 for (i = 1; i < L->length; i++)
 for (j = L->length - 1; j >= i; j--)
 if (L->r[j] > L->r[j+1])
 swap(L, j, j+1);
}

代码解释

假设我们待排序的关键字序列是{9,1,5,8,3,7,4,6,2}

  • 当i = 1时,变量j由8反向循环到1,逐个比较,将较小值交换到前面,直到最后找到最小值放置在了第1的位置。
  • 当i = 1、 j = 8时,6 > 2 ,因此交换了它们的位置,j = 7时,4 > 2, 所以交换......直到j = 2时,因为 1 < 2, 所以不交换。
  • j = 1 时,9 > 1,交换,最终得到最小值1放置第一的位置。
  • 在不断循环的过程中,除了将关键字1放到第一的位置,还将关键字2从第九位置提到了第三的位置,显然比前面的算法有进步。
  • 当i = 2时,变量j由8反向循环到2,逐个比较,在将关键字2交换到第二位置的同时,也将关键字4和3有所提升

1.3 冒泡排序的优化

  • 在排序的过程中,增加一个标记变量flag来记录位置是否发生了变化
  • 如果没有发生交换,说明数组已经有序了。
  •  
void BubbleSort1(SqList *L){
 int i,j;
 
 int flag = TRUE;
 for (i = 1; i < L->length && flag; i++) {
 flag = FALSE;
 for (j = L->length - 1; j >= i; j--) {
 if (L->r[j] > L->r[j+1]) {
 swap(L, j, j+1);
 flag = TRUE;
 }
 }
 }
}

测试

#define N 9
int main(int argc, const char * argv[]) {
 
 int i;
 int d[N] = {9,1,5,8,3,7,4,6,2};
 
 SqList l0;
 for (i = 0; i < N; i++)
 l0.r[i+1] = d[i];
 l0.length = N;
 
 printf("排序前:
");
 for (i = 0; i < l0.length; i++) {
 printf("%d ", l0.r[i+1]);
 }
 printf("
");
 
 printf("1.0 初级冒泡排序结果:
");
 BubblSort0(&l0);
 for (i = 0; i < l0.length; i++) {
 printf("%d ", l0.r[i+1]);
 }
 printf("
");
 
 printf("1.1 冒泡排序结果:
");
 BubbleSort(&l0);
 for (i = 0; i < l0.length; i++) {
 printf("%d ", l0.r[i+1]);
 }
 printf("
");
 printf("1.2 优化后冒泡排序结果:
");
 BubbleSort1(&l0);
 for (i = 0; i < l0.length; i++) {
 printf("%d ", l0.r[i+1]);
 }
 printf("
");
 return 0;
}

测试结果

算法 - 七大排序算法详细介绍

 

 


 

二、简单选择排序

简单选择排序法(Simple Selection Sort)是通过n-i次关键字间的比较从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换

简单选择排序法的工作原理是:每一次从无序组的数据元素中选出最小(或最大)的一个元素,存放在无序组的起始位置,无序组元素减少,有序组元素增加,直到全部待排序的数据元素排完

  •  
void SelectSort(SqList *L){
 int i, j, min;
 for (i = 1; i < L->length; i++) {
 min = i;
 for (j = i + 1; j <= L->length; j++) {
 if (L->r[min] > L->r[j])
 min = j;
 }
 
 if (i != min) 
 swap(L, i, min);
 }
}

代码说明

  • 简单选择排序相对简单,交换移动数据的次数相当少,节约时间。
  • 简单选择排序的时间复杂度为O(n^2)。

 

三、直接插入排序

直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录增1的有序表。

直接插入排序的核心思想:将一个记录插入到一个已经排序好的表中,以得到一个记录增加1的有序表。并且它把当前元素大的记录都往后移动,用以腾出“自己”该插入的位置。当n-1趟插入完成后该记录就是有序序列。

void InsertSort(SqList *L){
 int i, j;
 for (i = 2; i < L->length; i++) {
 
 if (L->r[i] < L->r[i-1]) {
 
 L->r[0] = L->r[i];
 for (j = i-1; L->r[j] > L->r[0]; j++)
 L->r[j+1] = L->r[i];
 
 L->r[j+1] = L->r[0];
 }
 }
}

代码说明

  • 直接插入排序的时间复杂度为O(n^2)。
  • 直接插入排序比冒泡和简单选择排序的性能要好一些。

 

四、希尔排序

希尔排序是对直接插入排序的改进:

  • 将原本有大量记录数的记录进行分组。分割成若干个子序列
  • 对子序列分别进行直接插入排序
  • 当整个序列都基本有序时注意是基本有序),再对全体记录进行一次直接插入排序。
  • 所谓的基本有序就是小的关键字基本在前,大的基本在后面,不大不小的基本在中间,如{9,1,5,8,3,7,5,6,2},变成{2,1,3,6,4,7,8,9}这样就是基本有序,但是像{1,5,9,7,8,2,4,6}这样9在第三位,2在倒数第三位就不是基本有序。
  • 对于分割子序列,采取跳跃分割的策略
  • 将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。
  • 增量的选取非常关键,但是现在还是一个数学难题(迄今没有找到一种最好的增量序列),大量研究表明,增量序列为dlta[k] = 2^(t-k+1) - 1时,可以获得不错的效果。

希尔排序的核心思想:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止

  •  
void ShellSort(SqList *L){
 
 int i,j;
 
 int increment = L->length;
 
 do {
 increment = increment /3 +1;
 
 for (i = increment + 1; i < L->length; i++) {
 
 if (L->r[i] < L->r[i-increment]) {
 
 L->r[0] = L->r[i];
 
 for (j = i - increment; i >0 && L->r[0] < L->r[j]; j -= increment)
 L->r[j+increment] = L->r[j];
 
 L->r[j+increment] = L->r[0];
 }
 }
 } while (increment > 1);
}

代码说明

  • 希尔排序的时间复杂度为O(n^(3/2)),要好于直接插入排序的O(n^2);
  • 增量的最后一个增量之必须等于1才行
  • 由于记录是跳跃式的移动,所以希尔排序不是一种稳定的排序算法

 

五、堆排序

堆的概念

堆是具有如下性质的完全二叉树

  • 每个结点的值都大于或等于其其左右孩子结点的值,为大顶堆
  • 或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
  • 因此根节点一定是堆中所有结点最大(小)者
  • 如图左边为大顶堆,右边为小顶堆:
算法 - 七大排序算法详细介绍

 

  •  
  • 左边为大顶堆,右边为小顶堆

 

堆排序算法

堆排序(Heap Sort)是利用堆(假设是大顶堆)进行排序。

堆排序的核心思想:

  • 将待排序的序列构造成一个大顶堆。
  • 此时,整个序列的最大值就是堆顶的根节点。
  • 将根节点移走(其实就是将它与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素的次小值。
  • 重复上诉操作,便能得到一个有序序列。

 

算法 - 七大排序算法详细介绍

 

 

堆排序算法核心

  • 如何由一个无序序列构建成一个堆
  • 如何在输出堆顶元素后,调整剩余元素成一个新的堆

堆排序算法代码实现

  •  
void HeadAdjust(SqList *L, int s, int m){
 int temp, j;
 temp = L->r[s];
 
 for (j = 2 *s; j <= m; j *= 2) {
 
 if (j < m && L->r[j] < L->r[j+1])
 j++;
 
 if (temp >= L->r[j])
 break;
 
 L->r[s] = L->r[j];
 s = j;
 }
 
 L->r[s] = temp;
}
void Heapsort(SqList *L){
 int i;
 
 for (i = L->length / 2; i>0; i--)
 HeadAdjust(L, i, L->length);
 
 for (i = L->length; i > 1; i--) {
 swap(L, 1, i);
 HeadAdjust(L, 1, i-1);
 }
}

堆排序算法代码说明

  • 堆排序方法HeapSort中有两个for循环:
  • 第一个for循环完成将现在的待排序序列构建成一个大顶堆;
  • 第二个for循环完成逐渐将每个最大值的根节点与末尾元素交换,并且再调整其成为大顶堆。
  • 第一个for循环中的i = L->length / 2,i从[9/2]=4开始,4->3->2->1的变化量。
  • (这里赋值的原因是这些都是有孩子的结点)
  • 构建好有孩子的结点之后,就可以从上到下、从左到右,将每个将每个非终端结点(非叶子结点)当做根节点,将其和子树调整成大顶堆。
  • 函数HeadAdjust的作用是将数组构建成一个大顶堆,在构建的时候利用了二叉树的性质。
  • 构建堆的时间复杂度为O(n),重建堆的时间复杂度为O(nlogn),所以总体来说堆排序的时间复杂度为O(nlogn),性能上远好于冒泡、简单选择、直接插入的时间复杂度。
  • 在空间复杂度上,由于记录的交换和比较是跳跃式进行的,所以堆排序是一种不稳定的排序方法

 

六、归并排序

归并排序(Merging Sort)是利用归并的思想实现的。2路归并排序的核心思想如下:

  • 假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的有序子序列
  • 再两两归并...如此重复,直至得到一个长度为n的有序序列为止。

6.1归并排序的实现思路(递归实现)

  • 将序列平均分成两部分
  • 分别对这两部分用递归来归并
  • 将这两部分归并到一起

归并排序的代码实现(递归实现)

  •  
#pragma - 6.归并排序(递归实现)
void Merge(int SR[], int TR[], int i, int m, int n){
 
 int j, k, l;
 
 for (j = m+1, k = i; i <= m && j <= n; k++) {
 
 if (SR[i] < SR[j])
 TR[k] = SR[i++];
 else
 TR[k] = SR[j++];
 }
 
 if (i <= m) {
 for (l=0; l <= m-i; l++)
 TR[k+l] = SR[i+l];
 }
 
 if (j <= n) {
 for (l=0; l <= n-j; l++)
 TR[k+l] = SR[j+l];
 }
}
void MSort(int SR[], int TR1[], int s, int t){
 int m;
 int TR2[MAXSIZE+1];
 
 if (s == t) {
 TR1[s] = SR[s];
 }else{
 m = (s+t)/2;
 MSort(SR, TR2, s, m);
 MSort(SR, TR2, m+1, t);
 Merge(TR2, TR1, s, m, t);
 }
}
void MergeSort(SqList *L){
 MSort(L->r, L->r, 1, L->length);
}

 

归并排序的总结(递归实现)

  • 归并排序总的时间复杂度为O(nlogn),并且这是归并排序算法中最好、最坏、平均的时间性能。
  • 归并排序的空间复杂度为O(n+logn)
  • 归并排序是一种比较占内存,但是效率高且稳定的算法。

6.2归并排序的实现(迭代非递归实现)

用迭代实现的话,可以从最小的序列开始归并直到完成

  •  
#pragma - 7.归并排序(迭代实现)
void MergePass(int SR[], int TR[], int s, int n){
 
 int i = 1;
 int j;
 
 while (i <= n-2*s+1) {
 Merge(SR, TR, i, i+s-1, i+2*s-1);
 i = i+2*s;
 }
 
 if (i < n-s+1)
 Merge(SR, TR, i, i+s-1, n);
 else
 for (j = i; j <= n; j++)
 TR[j] = SR[j];
}
void MergeSort2(SqList *L){
 
 int * TR = (int *)malloc(sizeof(L->length*sizeof(int)));
 int k = 1;
 
 while (k < L->length) {
 MergePass(L->r, TR, k, L->length);
 k = 2*k;
 
 MergePass(TR, L->r, k, L->length);
 k = 2*k;
 }
}

 

归并的迭代实现总结

  • 非递归的迭代方法,避免了递归时深度为log2n的栈空间,空间只是用到申请归并临时用的TR数组,因此空间复杂度为O(n).
  • 并且相对于递归,在时间性能上也有一定的提升,所以使用归并时,尽量使用非递归实现。

 

七、快速排序

快速排序(Quick Sort)的基本思想是:

  • 通过一趟排序将待排序记录分割成独立的两部分
  • 其中一部分记录的关键字均比另一部分记录的关键字小;
  • 则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

快速排序的实现思路

  • 选取一个关键字,放到一个位置,使得它的左边的值都比它小,右边的值都比它大,这个关键字叫做枢轴(pivot)
  • 然后分别对左边和右边进行排序。

快速排序的代码实现

  •  
#pragma - 8.快速排序
int Partition(SqList * L, int low, int high){
 
 int pivotkey;
 pivotkey = L->r[low];
 
 while (low < high) {
 while (low < high && L->r[high] >= pivotkey)
 high --;
 swap(L, low, high);
 
 while (low < high && L->r[low] <= pivotkey)
 high++;
 swap(L, low, high);
 }
 
 return low;
}
void QSort(SqList *L, int low, int high){
 
 int pivot;
 if (low < high) {
 pivot = Partition(L, low, high);
 QSort(L, low, pivot-1);
 QSort(L, pivot+1, high);
 }
}
void QuickSort(SqList *L){
 QSort(L, 1, L->length);
}

 

快速排序的代码说明

  • Partition函数就是将选取的pivotkey不断交换,将比它小的换到它的左边,比它大的交换到它的右边,它也在交换中不断更改自己的位置,直到完全满足这个要求为止。
  • 快速排序的时间性能取决于快速递归的深度,快排的时间复杂度为O(nlogn)
  • 快速排序的空间复杂度主要是递归造成的栈空间的使用,平均情况下空间复杂度为O(nlogn)。
  • 由于关键字的比较和交换是跳跃进行的,因此,快排是一种不稳定的排序算法

快速排序的优化

  1. 优化选取枢轴
  2. 在上面的代码中,选取枢轴的方式为:
  3. pivotkey = L->r[low],即用序列的第一个元素作为枢轴,这是理想情况下 L->r[low]是中间数。
  4. 但是对于其他情况,这种固定选取第一个关键子作为首个枢轴的方法就不是很合理。
  5. 于是可以用下面的方法优化:
  • 三数取中(median-of-three)法
  • 取三个关键子进行排序,将中间数作为枢轴,一般取左端、右端和中间三个数,也可以随机选取。
  • 九数取中(median-of-nine)法
  • 先从数组中分三次取样,每次取三个数,三个样品各取中数,然后从这三个数当中再取出一个中数作为枢轴

三数取中(median-of-three)法代码:

  •  
 int pivotkey;
 
 int m = low + (high - low)/2;
 
 if (L->r[low] > L->r[high])
 swap(L, low, high);
 
 if (L->r[m] > L->r[high])
 swap(L, high, m);
 if (L->r[m] > L->r[low])
 swap(L, m, low);
 
 pivotkey = L->r[low];
  1. 优化不必要的交换
  2. 优化小数组时的排序方案
  3. 优化递归操作

快速排序优化后的代码

  •  
int Partition1(SqList * L, int low, int high){
 
 int pivotkey;
 
 int m = low + (high - low)/2;
 
 if (L->r[low] > L->r[high])
 swap(L, low, high);
 
 if (L->r[m] > L->r[high])
 swap(L, high, m);
 if (L->r[m] > L->r[low])
 swap(L, m, low);
 
 pivotkey = L->r[low];
 L->r[0] = pivotkey;
 
 while (low < high) {
 while (low < high && L->r[high] >= pivotkey)
 high--;
 L->r[low] = L->r[high];
 
 while (low < high && L->r[low] <= pivotkey)
 low++;
 L->r[high] = L->r[low];
 }
 
 L->r[low] = L->r[0];
 
 return low;
}
void QSort1(SqList *L, int low, int high){
 
 int pivot;
 if ((high -low) > MAX_LINEGIH_INSERT_SORT) {
 while (low < high) {
 pivot = Partition1(L, low, high);
 QSort1(L, low, pivot-1);
 
 low = pivot+1;
 }
 }else
 InsertSort(L);
}
void QuickSort1(SqList *L){
 QSort1(L, 1, L->length);
}
  • 希尔排序相当于直接插入排序的升级,同属于插入排序类
  • 堆排序相当于简单选择排序的升级,同属于选择排序类
  • 快速排序相当于冒泡排序的升级,同属于交换排序类
  •  


Tags:算法   点击:()  评论:()
声明:本站部分内容来自互联网,内容观点仅代表作者本人,如有任何版权侵犯请与我们联系,我们将立即删除。
▌相关评论
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
▌相关推荐
DHT 算法:在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。(百度百科)结构式拓扑:1.无中央服务器,各结点的功能...【详细内容】
2019-11-27   算法  点击:(0)  评论:(0)  加入收藏
通过本篇文章可以对ML的常用算法有个常识性的认识,没有代码,没有复杂的理论推导,就是图解一下,知道这些算法是什么,它们是怎么应用的,例子主要是分类问题。每个算法都看了好几个视...【详细内容】
2019-11-25   算法  点击:(4)  评论:(0)  加入收藏
批处理系统中采用的调度算法重要指标(吞吐量,周转时间,CPU利用率,公平平衡)非抢占式的先来先服务算法(FCFS):按照进程就绪的先后顺序使用CPU特点:公平,实现简单,但是长进程后面的短进程...【详细内容】
2019-11-25   算法  点击:(2)  评论:(0)  加入收藏
算法是程序员手中的利剑,所到之处,刀起头落。四大类(七把宝剑)排序算法交换排序: 包括冒泡排序,快速排序。选择排序: 包括直接选择排序,堆排序。插入排序: 包括直接插入排序,希尔排序...【详细内容】
2019-11-25   算法  点击:(2)  评论:(0)  加入收藏
短视频创业选好平台是关键,不同的短视频在不同的平台上会得到不一样的结果。如何正确选择合适的平台,需要先搞清楚各家短视频平台的用户特征。今天我们就以头部平台抖音与快手...【详细内容】
2019-11-22   算法  点击:(4)  评论:(0)  加入收藏
笔试面试经常涉及各种算法,本文简要介绍常用的一些算法,并用JavaScript实现。1、插入排序1)算法简介插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原...【详细内容】
2019-11-22   算法  点击:(4)  评论:(0)  加入收藏
算法一:分治法基本概念1.把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题&hellip;&hellip;直到最后子问题可以简单的直接求解,原问题的解即...【详细内容】
2019-11-21   算法  点击:(5)  评论:(0)  加入收藏
一、前言什么是算法?算法是某种集合,是简单指令的集合,是被指定的简单指令集合。确定该算法重要的指标: 第一是否能解决问题; 第二算法运行时间,即解决问题出结果需要多少时间; 还...【详细内容】
2019-11-21   算法  点击:(3)  评论:(0)  加入收藏
导读:说到滴滴的派单算法,大家可能感觉到既神秘又好奇,从出租车扬召到司机在滴滴平台抢单最后到平台派单,大家今天的出行体验已经发生了翻天覆地的变化,面对着每天数千万的呼叫,...【详细内容】
2019-11-21   算法  点击:(5)  评论:(0)  加入收藏
diff算法的作用计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面。传统diff算法通过循环递归对节点进行依次对比,算法复杂度达到 O(n^3...【详细内容】
2019-11-20   算法  点击:(2)  评论:(0)  加入收藏
在实现算法的时候,通常会从两方面考虑算法的复杂度,即时间复杂度和空间复杂度。顾名思义,时间复杂度用于度量算法的计算工作量,空间复杂度用于度量算法占用的内存空间。本文将从...【详细内容】
2019-11-18   算法  点击:(3)  评论:(0)  加入收藏
国际权威的学术组织the IEEE International Conference on Data Mining (ICDM) 评选出了数据挖掘领域的十大经典算法:C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost,...【详细内容】
2019-11-14   算法  点击:(10)  评论:(0)  加入收藏
摘 要 共识算法是区块链技术的核心要素, 也是近年来分布式系统研究的热点. 本文系统性地梳理和讨论了区块链发展过程中的 32 种重要共识算法, 介绍了传统分布式一致性算法...【详细内容】
2019-11-14   算法  点击:(7)  评论:(0)  加入收藏
携程作为国内领先的OTA,每天向上千万用户提供全方位的旅行服务,如何为如此众多的用户发现适合自己的旅游产品与服务,挖掘潜在的兴趣,缓解信息过载,个性化推荐系统与算法在其中发...【详细内容】
2019-11-14   算法  点击:(12)  评论:(0)  加入收藏
这段时间刚好正在做软件安全的实验和课设,学习了各种加密算法,比如对称加密算法的DES,AES;非对称加密算法的RSA;再如今天要讲的主角-单向加密算法的MD5。为什么这么多算法,MD5成...【详细内容】
2019-11-14   算法  点击:(8)  评论:(0)  加入收藏
Hash也称散列、哈希,对应的英文都是Hash。基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。活动开发中经常使用的MD5和SHA都是...【详细内容】
2019-11-14   算法  点击:(8)  评论:(0)  加入收藏
域名价值算法是怎样的?如何了解?新手米农出来的时候一定要了解域名价值算法,因为只有明白域名价值的算法才知道囤积那些域名,投资啥样的域名,关于域名价值算法每个平台意见不一,今...【详细内容】
2019-11-13   算法  点击:(4)  评论:(0)  加入收藏
一、基本描述 类似于回溯算法也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的...【详细内容】
2019-11-13   算法  点击:(6)  评论:(0)  加入收藏
今年国庆后国内大批做百度网站优化收录和排名直线下降,很多人都以为是被降权,但是也没有违规操作,纷纷向官网反馈,但是官网给出的结果就是符合预期搜索排名要求,我们很多苏州seo...【详细内容】
2019-11-11   算法  点击:(20)  评论:(0)  加入收藏
这个虽然是闲扯淡的,但是看的时候请抓牢: 我们一切以业务方案为目的, 一些关键名词和概念还是很认真。加密签名一个故事这是从别人那边听来的故事,作为安全知识的入门非常有意...【详细内容】
2019-11-11   算法  点击:(8)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条