【数据结构基础应用】【查找和排序算法】

代码参考《妙趣横生的算法.C语言实现》

文章目录

  • 前言
  • 1、顺序查找
  • 2、折半查找
  • 3、直接插入排序
  • 4、选择排序
  • 5、冒泡排序
  • 6、希尔排序
  • 7、快速排序
  • 8、堆排序
  • 9、排序算法性能比较
  • 10、所有算法的code(C语言)


前言

本章总结查找和排序算法:顺序查找、折半查找、直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序以及排序算法性能比较。


1、顺序查找

顺序查找就是在文件的关键字结合key[1,2,…n]中找出与给定的关键字key相等的文件记录。

步骤描述:

1、从文件的第一个记录开始,将每个记录的关键字与给定的关键字key进行比较

2、如果查找到某个记录的关键字等于key,则查找成功,返回该记录的地址。如果所有记录的关键字都与key进行了比较,但都未匹配,则本次查找失败,返回失败标记-1

//顺序查找:n表示记录个数、key表示要查找记录的关键字、key[]为存放所有记录关键字顺序表。
int sq_search(keytyped key[],int n,keytype key)
{int i;for (i=0;i<n;i++){if (key[i] == key){return i;}}return -1;
}

用结构体描述:

typedef struct {keytype key;		//keytype类型的关键字keydatatype data;		//记录其中信息
}RecordType;
int sq_search(RecordType r[], int n, keytype key)
{int i;for (i = 0;i < n;i++){if (r[i].key == key)		//查找成功{return i;}}return -1;
}
//缺点:平均查找长度过大,查找效率较低

2、折半查找

只有在关键字的排序是有序的(递增或递减)情况下,才能应用折半查找的算法描述。

基本思想:

减少查找序列的长度,分而治之进行关键字的查找。

查找过程:先去定待查找记录的所在反胃,然后逐渐缩小查找的范围,直到找到为止(也可能查找失败)

//基于递增序列的折半查找
//n表示记录个数、k表示要查找到的关键字、key[]关键字顺序表
int bin_search(keytype key[], int n, keytype k)
{int low = 0, high = n - 1, mid;while (low <= high){mid = (low+high) / 2;if (key[mid] == k)return mid;if (k > key[mid])low = mid + 1;		//在后半序列中查找elsehigh = mid - 1;}return -1;					//查找失败,返回-1
}

用结构体描述:

typedef struct {keytype key;			//关键字datatype data;			//记录的信息
}RecordType;int bin_search(RecordType r[], int n, keytype key)
{int low = 0, high = n - 1, mid;while (low <= high){mid = (low + high) / 2;if (r[mid].key == key)return mid;if (key > r[mid].key)low = mid + 1;		//在后半序列中查找elsehigh = mid - 1;}return -1;					//查找失败,返回-1
}

3、直接插入排序

排序可以理解为:
根据文件记录的关键字值得递增或者递减关系将文件记录的次序进行重新排列的过程。
或者是:将一个按值无序的数据序列转换成为一个按值有序的数据序列的过程

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。

在日常生活中,经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。例如:一组从小到大排好顺序的数据列{1,2,3,4,5,6,7,9,10},通常称之为有序列,我们用序号1,2,3,…表示数据的位置,欲把一个新的数据8插入到上述序列中。

完成这个工作的步骤:
①确定数据“8”在原有序列中应该占有的位置序号。数据“8”所处的位置应满足小于或等于该位置右边所有的数据,大于其左边位置上所有的数据。

②将这个位置空出来,将数据“8”插进去。
直接插入排序(straight insertion sort)的做法是:
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

#include<iostream>
using namespace std;
void Insertsort(int a[],int k)
{int i, j;for (i = 1;i < k;i++)//循环从第2个元素开始{if (a[i] < a[i - 1]){int temp = a[i];for (j = i - 1;j >= 0 && a[j] > temp;j--){a[j + 1] = a[j];}a[j + 1] = temp;//此处就是a[j+1]=temp;}}
}
int main()
{int a[] = { 98,76,109,34,67,190,80,12,14,89,1 };int k = sizeof(a) / sizeof(a[0]);Insertsort(a,k);for (int f = 0;f < k;f++){cout << a[f] << "  ";}return 0;
}

4、选择排序

基本思想:第i趟排序从序列后n-i+1个元素中选择一个最小的元素,与该n-i+1个元素的最前面那个元素进行位置交换,也就是与第i个位置上的元素进行交换,直道n=i-1;

直观讲,每一趟的选择排序就是从序列中未排好顺序的元素中选择一个最小的元素,将钙元素与这些未排好的元素中的第一个元素交换位置。

void Selectsort(int a[], int k)
{int i, j,min;int tmp;for (i = 0;i < k;i++){min = i;for (j = i + 1;j < k;i++){if (a[j] <= a[min]){min = j;}}if (min != i)      //如果找到比a[min]还要小的值就进行交换位置,否则不交换{tmp = a[min];a[min] = a[i];a[i] = tmp;}}
}

5、冒泡排序

基本思想描述:

1、将序列中的第一个元素和第二个元素进行比较,若前者大于后者,则将第一个元素与第二个元素进行位置交换,否则不交换

2、将第2个元素与第3个元素进行比较,同样若前者大于后者,则将第2个元素与第3个元素进行位置交换,否则不交换。

3、以此类推,直到将第n-1个元素与第n个元素进行比较为止。此过程称为第1趟冒泡排序,进过第21趟冒泡排序后,将长度为n的序列中最大的元素置于序列的尾部,即第n个位置上。

4、之后再进行第2趟…第n-1趟排序。冒泡排序完成。

改进思路:

以序列3 6 4 2 11 10 6为例:

第一趟bubblesort之后:

3 4 2 6 10 6 11

第二趟bubblesort之后:

3 2 4 6 6 10 11

第三趟bubblesort之后:

2 3 4 6 6 10 11

这时再进行冒泡排序就会发现,序列本身不会再发生变化,只有相邻元素的比较,而没有相邻元素的交换,也就是说此时排序已经完成了。

所以可以这样改进:

如果某一趟排序过程中只有元素之间的比较而没有元素之间的位置交换,说明排序完成。

void ImprovedBubblesort(int a[], int n)
{int i, j;int tmp;int flag = 1;               //flag=1,说明本趟排序中仍有元素交换动作for (i = 0;i < n && flag==1;i++)       //趟次,一共n-1次{flag = 0;for (j = 0;j < n - 1;j++)  //元素交换{if (a[j] > a[i]){flag = 1;tmp = a[j];a[j] = a[i];a[i] = tmp;}}}
}

6、希尔排序

基本思路:

1、设定一个元素间隔增量gap,将参加排序的序列按照这个间隔数gap从第1个元素开始依次分成若干个子序列。

2、在子序列中可以采用其他的排序方法,例如冒泡排序。

3、缩小增量gap,重新将整个序列按照新的间隔数gap进行划分,再分别对每个子序列排序。过程描述:缩小增量gap–>划分序列–>将子序列排序

4、直到间隔数gap=1为止。

希尔排序过程:
在这里插入图片描述
思考:如何确定间隔数gap?
数学上仍然是一个尚未解决的难题,但是经验告诉我们一种比较常用且效果好的方法:
1、首先gap取值为序列长度的一半
2、后续排序过程中,后一趟排序的gap取值为前一趟排序gap的一半取值
算法描述:

void Shellsort(int a[], int n)
{int i, j;int tmp;int flag = 1;              int gap = n;            //第一次gap为nwhile (gap > 1){//确定gapgap = gap / 2;//以gap划分子序列,每一次迭代都是一组子序列的一趟自排序(冒泡)do {flag = 0;for (i = 0;i < n - gap;i++){j = i + gap;if (a[j] < a[i]){flag = 1;tmp = a[j];a[j] = a[i];a[i] = tmp;}}} while (flag==1);}
}

7、快速排序

基本思想:
1、在当前的排序序列中任意选取一个元素,把该元素称为基准元素或支点,把下雨等于基准元素的所有元素都移动到基准元素的前面,把大于基准元素的所有元素都移到基准元素的后面,这样使得基准元素所处的位置 恰好就是排序的最终位置,并且把当前参加排序的序列分为前后两个序列。
2、上述的过程称为一趟快速排序,即快速排序的一次划分
3、接下来分别对这两个子序列重复上述的排序操作(如果子序列长度大于1的话),直到所有元素都被移动到排序后他们应处的最终位置上。
效率之所以高:每一次元素的移动都是跳跃的,不会像冒泡排序只能在相邻元素之间进行,元素移动的间隔较大,因此总的比较和移动次数减少

具体步骤:

1、假设序列a,设置两个变量i、j.分别指向首元素和尾元素,设定i指向的首元素为基准元素

2、反复执行i++,直到i指向的元素>=基准元素,或者i指向尾部

3、反复执行j–,直到指向的元素<基准元素,或者j指向头部

4、若此时i<j,将i和j指向的元素进行交换。(大的元素在后面)

5、完成第一次交换后,重复执行步骤1、2,直到i>=j位置

6、此时i>=j,然后将基准元素与j指向的元素交换位置,至此完成了原序列的第一次划分

7、接下来分别对基准元素前后的子序列中长度大于1的子序列重复执行上述操作。

步骤分析:

对于每个子序列的操作又是一次划分,因此这个算法具有递归性质。

每次划分过程的基准元素仍可设定为子序列的第一个元素

//快速排序
void Quicksort(int a[], int s,int t)
{int i, j;if (s < t){//【1】设置两个变量i、j.分别指向首元素和尾元素,设定i指向的首元素为基准元素i = s;j = t + 1;while (1){do i++;while(!(a[s]<=a[i] || i==t));               //【2】重复i++操作,直到i指向的元素>=基准元素,或者i指向尾部do j--;while (!(a[s]>=a[j] || j==s));              //【3】反复执行j--,直到指向的元素<基准元素,或者j指向头部if (i < j)                                  //【5】若此时i<j,将i和j指向的元素进行交换。(大的元素在后面){swap(a[j], a[i]);}else break;                                  //【5】完成第一次交换后,重复执行步骤1、2,直到i>=j位置}//【6】此时i>=j,然后将基准元素与j指向的元素交换位置,至此完成了原序列的第一次划分swap(a[s],a[j]);//【7】接下来分别对基准元素前后的子序列中长度大于1的子序列重复执行上述操作。Quicksort(a,s,j-1);                             //前半序列Quicksort(a,j+1,t);                             //后半序列}
}

快速排序只适用于顺序表线性结构或者数组序列的排序,不适合在链表上实现

8、堆排序

heapsort是选择排序的改进。

首先了解一下堆的概念:

堆通常是一个可以被看做一棵完全二叉树的数组对象。

堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。

(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4…n/2)

堆总是满足下列性质:

1、 堆中某个节点的值总是不大于或不小于其父节点的值;

2、 堆总是一棵完全二叉树。

了解一下完全二叉树的概念:

https://blog.csdn.net/judgejames/article/details/87868602

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆

举例:

序列{49,22,40,20,18,36,6,12,17}
在这里插入图片描述
基于大顶堆的完全二叉树表示的堆排序的核心思想可描述如下:

1、将原始序列构成一个堆(建立初始堆)

2、交换堆的第一个元素和堆的最后一个元素

3、将交换最大值元素之后的剩余元素所构成的序列再转换成一个堆

4、重复上述2、3步骤n-1次

经过上述操作,就可以将一个无序的序列从小到大进行排序。

关键问题:

1、如何原始序列构成一个堆

2、如何将交换最大值元素之后的剩余元素所构成的序列再转换成一个堆

第二个问题:

该二叉树虽然不是一个堆,但是除了根结点外,其余任何一棵子树仍然满足堆的特性。

自上而下调整:将序号为i的结点与其左右孩子(2i 、2i+1)三个值中的最大值替换到序号为i的结点的位置上。

只要彻底地完成一次自上而下的调整,该二叉树就会变成一个堆。

最后一步:交换第一个元素和新堆的最后一个元素的位置,也就是将最大的元素移至新堆的最后。

第一个问题:

如果原序列对应的完全二叉树有n个结点,则:

1、初始化时,令序列号为i= Floor (n/2),它对应于而擦函数中第 Floor (n/2)个结点(二叉树中的结点按照层次编号,从1开始,从左到右,从上到下编号)

2、调用函数adjust调整

3、每执行完一次调整都执行一次i=i-1操作

4、重复步骤2、3,直到i==1时执行步骤5

5、最后再调用adjust函数调整一次。

这样就完成调整了。

示例:初始序列为:{23,6,77,2,60,10,58,16,48,20}
在这里插入图片描述
code:

//堆排序
//【1】将二叉树调整为一个堆的函数:
//函数作用:将以第i个元素作为根结点的子树调整为一个新的堆序列,前提是该子树中除了根结点外其余的任何一个子树仍然满足堆的特性,如果该子树除了根结点外其他子树也不完全是
//堆结构的话,则不能仅通过依次调用adjust函数就将其调整为堆
//输入:序列a   i:序列a中的元素下标
void BiTreeAdjustToHeap(int a[],int i,int n)
{int j;int tmp;tmp = a[i];j = 2 * i;      //j为i的左孩子结点序号while (j <= n){if (j < n && a[j] < a[j + 1]){j++;                //j为i的左右孩子中较大孩子的序号}if (tmp >= a[j])        //如果父结点值比孩子值还大就不需要调整了{break;}a[j / 2] = a[j];       //较大的子节点与父节点交换位置j = 2 * j;             //继续向下调整}a[j / 2] = tmp;
}//【2】原始序列初始化函数
void InitHeap(int a[],int n)
{for(int i=n/2;i>=0;i--){BiTreeAdjustToHeap(a,i,n);}
}
//堆排序函数
void Heapsort(int a[], int n)
{int i = 0;//【1】原始序列初始化函数InitHeap(a,n);//【2】交换第1个和第n个元素,再将根结点向下调整for (i = n - 1;i >= 0;i--){swap(a[i+1],a[0]);BiTreeAdjustToHeap(a,0,i);      //将根结点向下调整}
}

需要把握的要点:

1、堆排序是针对线性序列的排序,之所以要采用完全二叉树的形式解释堆排序的过程,是出于方便解释的需要

2、堆排序的第一步是将原序列变成一个对序列

3、一系列的交换调整操作。所谓交换就是将堆中第一个元素与本次调整范围内的新堆的最后一个元素交换位置,使得较大的元素能够置于序列的最后面,所谓调整就是将交换后的剩余元素从上至下调整为为一个新堆的过程。

4、通过2、3操作可以将一个无序序列从小到大偶爱徐

5、如果基于大顶堆进行堆排序,则排序后的序列从小到大。若是基于小顶堆,则从大到小。

9、排序算法性能比较

排序算法平均时间最坏情况空间需求
直接插入排序O(n^2)O(n^2)O(1)
冒泡排序O(n^2)O(n^2)O(1)
简单选择排序O(n^2)O(n^2)O(1)
希尔排序O(nlog2n)O(nlog2n)O(1)
快速排序O(nlog2n)O(n^2)O(nlog2n)
堆排序O(nlog2n)O(nlog2n)O(1)

总结:

1、如果参加排序的序列最开始就是基本有序或者局部有序的,使用这直接插入排序和冒泡排序的效果较好,排序速度较快,最好的情况下(原序列按值有序),时间复杂度O(n)

2、快速排序最快,堆排序空间消耗最小

3、序列中元素个数越小,采用冒泡排序排序算法、直接插入排序、简单选择排序较合适

当序列规模变大时,采用希尔排序、快速排序和堆排序比较合适

4、从稳定性来讲:直接插入、冒泡是稳定的排序方法。简单选择排序、希尔排序、快速排序、堆排序是不稳定的排序算法

10、所有算法的code(C语言)

#include<iostream>
using namespace std;
void swap(int& a, int& b)
{//方法一:   int tmp = 0;tmp = b;b = a;a = tmp;//方法二:   //a = a+b;   //b = a-b;   //a = a -b;   //方法三:   //a ^= b ^= a ^= b;   //方法四:    冒泡和希尔和改进冒泡,使用这个方法不成功         //a = a+b-(b=a);   
}
//参考:https://blog.csdn.net/shangguanyunlan/article/details/51778378         //
void Insertsort(int a[],int k)
{int i, j;for (i = 1;i < k;i++)//循环从第2个元素开始{if (a[i] < a[i - 1]){int temp = a[i];for (j = i - 1;j >= 0 && a[j] > temp;j--){a[j + 1] = a[j];}a[j + 1] = temp;//此处就是a[j+1]=temp;}}
}
//选择排序
void Selectsort(int a[], int k)
{int i, j,min;int tmp;for (i = 0;i < k;i++){min = i;for (j = i + 1;j < k;i++){if (a[j] <= a[min]){min = j;}}if (min != i)      //如果找到比a[min]还要小的值就进行交换位置,否则不交换{swap(a[min],a[i]);}}
}
//冒泡排序
void Bubblesort(int a[], int n)
{int i, j;int tmp;for (i=0;i<n;i++)       //趟次,一共n-1次{for (j = 0;j < n - 1;j++)  //元素交换{if (a[j] > a[i]){swap(a[j], a[i]);}}}
}
//改进的冒泡排序
void ImprovedBubblesort(int a[], int n)
{int i, j;int tmp;int flag = 1;               //flag=1,说明本趟排序中仍有元素交换动作for (i = 0;i < n && flag==1;i++)       //趟次,一共n-1次{flag = 0;for (j = 0;j < n - 1;j++)  //元素交换{if (a[j] > a[i]){flag = 1;swap(a[j], a[i]);}}}
}
//希尔排序
void Shellsort(int a[], int n)
{int i, j;int tmp;int flag = 1;              int gap = n;            //第一次gap为nwhile (gap > 1){//确定gapgap = gap / 2;//以gap划分子序列,每一次迭代都是一组子序列的一趟自排序(冒泡)do {flag = 0;for (i = 0;i < n - gap;i++){j = i + gap;if (a[j] < a[i]){flag = 1;swap(a[j], a[i]);}}} while (flag==1);}
}
//快速排序
void Quicksort(int a[], int s,int t)
{int i, j;if (s < t){//【1】设置两个变量i、j.分别指向首元素和尾元素,设定i指向的首元素为基准元素i = s;j = t + 1;while (1){do i++;while(!(a[s]<=a[i] || i==t));               //【2】重复i++操作,直到i指向的元素>=基准元素,或者i指向尾部do j--;while (!(a[s]>=a[j] || j==s));              //【3】反复执行j--,直到指向的元素<基准元素,或者j指向头部if (i < j)                                  //【5】若此时i<j,将i和j指向的元素进行交换。(大的元素在后面){swap(a[j], a[i]);}else break;                                  //【5】完成第一次交换后,重复执行步骤1、2,直到i>=j位置}//【6】此时i>=j,然后将基准元素与j指向的元素交换位置,至此完成了原序列的第一次划分swap(a[s],a[j]);//【7】接下来分别对基准元素前后的子序列中长度大于1的子序列重复执行上述操作。Quicksort(a,s,j-1);                             //前半序列Quicksort(a,j+1,t);                             //后半序列}
}//堆排序
//【1】将二叉树调整为一个堆的函数:
//函数作用:将以第i个元素作为根结点的子树调整为一个新的堆序列,前提是该子树中除了根结点外其余的任何一个子树仍然满足堆的特性,如果该子树除了根结点外其他子树也不完全是
//堆结构的话,则不能仅通过依次调用adjust函数就将其调整为堆
//输入:序列a   i:序列a中的元素下标
void BiTreeAdjustToHeap(int a[],int i,int n)
{int j;int tmp;tmp = a[i];j = 2 * i;      //j为i的左孩子结点序号while (j <= n){if (j < n && a[j] < a[j + 1]){j++;                //j为i的左右孩子中较大孩子的序号}if (tmp >= a[j])        //如果父结点值比孩子值还大就不需要调整了{break;}a[j / 2] = a[j];       //较大的子节点与父节点交换位置j = 2 * j;             //继续向下调整}a[j / 2] = tmp;
}//【2】原始序列初始化函数
void InitHeap(int a[],int n)
{for(int i=n/2;i>=0;i--){BiTreeAdjustToHeap(a,i,n);}
}
//堆排序函数
void Heapsort(int a[], int n)
{int i = 0;//【1】原始序列初始化函数InitHeap(a,n);//【2】交换第1个和第n个元素,再将根结点向下调整for (i = n - 1;i >= 0;i--){swap(a[i+1],a[0]);BiTreeAdjustToHeap(a,0,i);      //将根结点向下调整}
}
void show_sort_result(int a[],int k)
{for (int f = 0;f < k;f++){cout << a[f] << "  ";}printf("\n");
}
int main()
{int a[] = { 98,76,109,34,67,190,80,12,14,89,1 };int k = sizeof(a) / sizeof(a[0]);//printf("直接插入排序\n");//Insertsort(a,k);//show_sort_result(a,k);//printf("选择排序\n");//Insertsort(a, k);//show_sort_result(a,k);//printf("冒泡排序\n");//Bubblesort(a, k);//show_sort_result(a, k);//printf("改进后的冒泡排序\n");//ImprovedBubblesort(a, k);//show_sort_result(a, k);//printf("希尔排序\n");//Shellsort(a, k);//show_sort_result(a, k);//printf("快速排序\n");//Quicksort(a,0,k-1);//show_sort_result(a, k);//printf("堆排序\n");//Heapsort(a,k-1);//show_sort_result(a, k);return 0;
}

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

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

相关文章

爬虫项目(三)---采集最近一日全国各省疫情数据

该内容出自黑马程序员教程 采集最近一日全国各省疫情数据 当然&#xff0c;数据来源仍然是丁香园新型冠状病毒肺炎疫情实时动态首页 url&#xff1a;https://ncov.dxy.cn/ncovh5/view/pneumonia 思路&#xff1a;首先需要先确定全国各省疫情数据的位置 全国各省份的疫情数据…

计算机专业博士后排名,排名丨计算机专业领域TOP10,性价比超高!

原标题&#xff1a;排名丨计算机专业领域TOP10&#xff0c;性价比超高&#xff01;相信各位家长、同学已经看过太多专业的排名&#xff0c;我问过很多理科生将来想学什么专业&#xff0c;听到频率最高的还是计算机专业。似乎大家都知道&#xff0c;学计算机是比较挣钱的&#x…

js 命名规范

转载于:https://www.cnblogs.com/zjx2011/p/3165043.html

爬虫项目(四)---采集从01月22日以来全国各省疫情数据

采集从03月02日以来全国各省疫情数据 当然&#xff0c;数据来源仍然是丁香园新型冠状病毒肺炎疫情实时动态首页 url&#xff1a;https://ncov.dxy.cn/ncovh5/view/pneumonia 分析 确定01月22日以来全国各省疫情数据的URL 由项目(三)可以获取全国各省疫情数据点击可下载&…

纠错码trick和数据压缩trick

纠错码和压缩算法是同一枚硬币的两面。 两者都来自于对冗余的想法。 纠错码被视为向消息或文件中添加冗余的原则性方法。而压缩算法正好相反&#xff0c;他们会从消息或文件中移除冗余。 压缩和纠错并不是彼此抵消的&#xff0c;相反&#xff0c;好的压缩算法会移除抵消冗余&am…

常用算法总结(穷举法、贪心算法、递归与分治算法、回溯算法、数值概率算法)

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 目录1、穷举法2、贪心算法3、递归与分治算法4、回溯算法5、数值概率算法1、穷举法…

工程师英语和计算机证书查询,点击进入国家硬件维修工程师证书查询网站

工程师证书查询网站人力资源社会保障部指定查询国家职业资格证书的唯一官方网站。涵盖全国各省市、各行业、各央企颁发的证书。电脑硬件维修工程师网上能查看国家工信部硬件维修工程师证书查询网址&#xff1a;http://www.ceiaec.org/index.htm工程师证书编号在网上怎么查询如果…

敏捷开发“松结对编程”系列之七:问题集之一

本文是“松结对编程”系列的第七篇。&#xff08;之一&#xff0c;之二&#xff0c;之三&#xff0c;之四&#xff0c;之五&#xff0c;之六&#xff0c;之七&#xff0c;之八&#xff09;刚刚参加完MPD 2011深圳站&#xff0c;在演讲中间及后来媒体采访&#xff0c;被问到了一…

C++中的sort函数对二维数组排序是按照什么准则?

遇到的一个疑惑&#xff0c;现记录如下&#xff1a; int main() {vector<vector<int>> envelopes { {5, 8},{6, 7},{6, 4},{2, 3},{8,9} };sort(envelopes.begin(), envelopes.end());for (int i 0;i < envelopes.size();i)cout << envelopes[i][0]<…

数学专业学计算机哪一行,计算数学

计算数学(一个理科专业)语音编辑锁定讨论上传视频计算数学是由数学、物理学、计算机科学、运筹学与控制科学等学科交叉渗透而形成的一个理科专业。中文名计算数学外文名Computational Mathematics所 属数学计算数学专业定义编辑语音计算数学也叫做数值计算方法或数值分析。主…

图片透视变换操作

由于照相机硬件设备本身的误差&#xff0c;可能会导致镜头畸变&#xff0c;从而导致照相机拍摄到的照片产生失真现象&#xff0c;此时可以通过透视变换去适当的校正。 大概的思路&#xff1a;在原图像上确定四个点&#xff0c;然后再新图像上也确定四个点&#xff0c;通过warp…

dp笔记:关于DP算法和滚动数组优化的思考

从网上总结了一些dp的套路以及对滚动数组的一些思考&#xff0c;现记录如下&#xff0c;希望以后回顾此类算法时会有所帮助。 目录1、DP算法经验1、DP算法核心&#xff1a;2、DP算法类别以及例题例1&#xff1a;三步问题例2&#xff1a;最小路径和例3&#xff1a;乘积最大子数组…

【C++ grammar】引用

1、引用就是另一个变量的别名 2、通过引用所做的读写操作实际上是作用与原变量上 引用方式&#xff1a; int x; int & rxx; or int x, &rxx;在C中&是取地址&#xff0c;在C中&放在一个变量的定义前&#xff0c;那就是引用 注意&#xff1a; 这种引用是错误的…

flash安全策略的理解

flash安全策略的理解 2011-06-25 01:48 11人阅读 评论(0) 收藏 举报 一直以来对flash的安全策略是一头雾水&#xff0c;什么安全沙箱&#xff0c;跨域策略文件一堆东西乱七八糟&#xff0c;搞不清楚。不过纠结到现在已经基本上理解了。 flash的安全问题在官方手册上有足够的解…

【C++ grammar】nullptr and Dynamic Memory Allocation (空指针和动态内存分配)

空指针 1.1. 0带来的二义性问题 C03中&#xff0c;空指针使用“0”来表示。0既是一个常量整数&#xff0c;也是一个常量空指针。C语言中&#xff0c;空指针使用(void *)0来表示有时候&#xff0c;用“NULL”来表示空指针(一种可能的实现方式是#define NULL 0) 1.2. C标准化委…

No module named ‘skimage.metrics‘在Anaconda3中的解决方法

1&#xff0c;进入Anaconda Prompt 2&#xff0c;进行安装&#xff1a; pip install scikit-image 3&#xff0c;若还是报错&#xff0c;尝试进行更新一下 pip install scikit-image --upgrade

【C++ grammar】数据类型转换、列表初始化

布尔类型 C语言在其标准化过程中引入了bool、true和false关键字&#xff0c;增加了原生数据类型来支持布尔数据。 布尔类型的大小&#xff08;所占的存储空间&#xff09;依赖于具体的编译器实现。也可以用 sizeof运算符得到其占用的空间 Conversion between bool and int 0…

Python对自定义离散点进行指定多项式函数拟合

自定义离散点进行指定多项式函数拟合 用户自己自己输入坐标点&#xff0c;拟合函数可根据用户输入的多项式的最高次方进行自动拟合函数&#xff0c;拟合方法采用最小二乘法进行函数拟合。 (1,2),(2,5),(3,10),(4,17),(5,26),(6,37)(7,50),(8,65),(9,82) 很显然是函数为二次函…

【C++ grammar】C++简化内存模型

1、stack&#xff08;栈&#xff09; 编译器自动分配内存&#xff08;函数内部定义得局部变量、形参&#xff09; 2、堆&#xff08;Heap&#xff09; 一般由程序员分配释放&#xff0c;若程序员不释放&#xff0c;程序结束时可能由OS回收&#xff08;new和delete&#xff09; …

Effect of Diethylene Glycol on the Inkjet Printability of Reactive Dye Solution for Cotton Fabrics.

Effect of Diethylene Glycol on the Inkjet Printability of Reactive Dye Solution for Cotton Fabrics 二乙二醇对棉织物活性染料溶液喷墨印刷性能的影响 Diethylene Glycol 二乙二醇 Inkjet Printability 喷墨印刷性能 Reactive Dye Solution 活性染料溶液 Cotton Fabric…