【数据结构与算法篇】八种排序 (C++实现)

多种排序算法的Cpp实现

    • 一. 排序的概念及其运用
      • 排序的概念
    • 二. 一图速览常见排序
    • 三. 排序的C++实现
      • 1> 直接插入排序
      • 2> 希尔排序
        • 希尔排序代码实现(希尔所实现)
        • 希尔排序代码实现(优化版)
      • 3> 选择排序
        • 选择排序的代码实现(同时选出最大和最小的元素)
      • 4> 堆排序
        • 堆排序的代码实现
      • 5> 冒泡排序
      • 6> 快速排序
        • 快速排序(递归版)
        • 快速排序(迭代版)
      • 7> 归并排序
        • 归并排序(递归版)
        • 归并排序(迭代版)
      • 8> 基数排序

一. 排序的概念及其运用

排序的概念

  • 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,将其递增或递减的排列起来的操作。
  • 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变的程度被称为排序的稳定性。
    • 比如,在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
  • 内部排序:数据元素全部放在内存中的排序。(内存中读取数据, 排序的结果依旧可以写入到内存中)
  • 外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。(内存中读取数据, 排序的结果最终写入到磁盘中)

二. 一图速览常见排序

在这里插入图片描述

三. 排序的C++实现

1> 直接插入排序

插入排序, 又叫直接插入排序, 简称插排。
基本思想 :

  • 一组待排序的元素, 我们要使其变得有序,例如升序。 此时我们认为前 i 个元素是有序的 (i从1开始), 要将第i+1个元素插入到这前i个元素中。
  • 具体的插入过程是, 将第 i+1个元素与前面的元素依次进行比较(从第i个元素开始), 直至找到某个元素小于 第i+1个元素(或者前i个元素均大于第i+1个元素),
  • 此时 , 我们找到该元素小于第i+1个元素, 那么我们将第i+1个元素插入到该元素的后面, 最终使得这共i+1个元素变得有序
  • 重复上述过程对数组中的所有元素依次进行排序, 最终使得该数组中的元素全部变得有序
// 直接插入排序 (升序排列)
void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++)          // n-1 防止 temp = a[end+1] 越界 , 也可以在数组中只有一个元素或是空数组时不进入循环{int end = i;int temp = a[end + 1];while (end >= 0){if (temp < a[end]){a[end + 1] = a[end];--end;}else{break;}}a[end + 1] = temp;  // 代码执行到该位置有两种情况, (1) 前i个元素均 > 待排序元素, 此时待排序元素插入到数组首元素位置, 其他元素后移//                          (2) 待排序元素在前i个元素中找到了插入位置, 此位置不为 数组中首元素位置。 原位置的元素及其之后元素后移}   
}
时间复杂度: O(N^2)    // 逆序下最坏为0(N^2) , 有序时为O(N)
空间复杂度: O(1)      // 原数组中进行排序

2> 希尔排序

希尔排序是按其设计者希尔的名字命名的, 希尔排序又称为 缩小增量排序。
基本思想:

  • 对待排序序列进行多次预排序, 通过这多次预排序最终使得待排序序列极为接近有序, 从而降低排序算法的时间消耗(也就是降低了其时间复杂度)
    1. 设置一个int类型的变量, 假设该变量名为 grep (一般grep=n/2)。
    1. 将待排序系列中间隔为 grep的元素划分为同组元素
    1. 如此一来, 待排序元素也就被分为了grep组, 对于这grep组中的元素, 在同组元素之间进行直接插入排序, 使得其在同组中变得有序
    1. 不断缩小grep的值, 循环往复进行上述过程(一般 grep = grep/2)
    1. grep不断缩小的过程被称为缩小增量
    1. 最终grep = 1时, 待排序序列中的元素变得接近有序, 此时在对其进行直接插入排序(相当于对新序列进行直接插入排序), 最终使得整个序列变得有序

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的
    希尔排序的时间复杂度都不固定
希尔排序代码实现(希尔所实现)
void ShellSort(int* a, int n)
{int gap = n;      // 设置变量 gap while(gap>1){gap = gap / 2;    // 每次循环缩小增量for (int j = 0; j < gap; j++)   // 同组元素依次进行插排{for (int i = j; i < n - gap; i += gap)  // 某个元素进行一次完整的插入排序{int end = i;int temp = a[end + gap];while (end >= 0)     // while循环遍历 前 i个元素, 直至某个元素 小于 temp{if (temp < a[end]){a[end + gap] = a[end];  // 比 待排序元素大的元素向后移动gap位end -= grep;}else{break;}}a[end + gap] = temp;// 待排序元素插入到正确的位置}}}
}时间复杂度: O(N^1.3)   //(这是平均时间复杂度)
空间复杂度: O(1)
希尔排序代码实现(优化版)
// 希尔排序代码优化
void ShellSort(int* a, int n)
{int gap = n;                               // 是同组元素与元素之间的间隔while (gap > 1)  //  这个while循环是控制预排序的次数 // 如果while循环可以运行, 那么当grep = 1时, 一定会运行一次插入排序。 因为是先更新grep的值, 在进行希尔排序。                               {gap = gap / 2;                         // 将n个元素分成了grep组, 分组依据是所有间隔为 grep 的元素位于同一组//gap = gap / 3 + 1;//  也可以改变gap每次缩小的规模,从而减少排序次数, +1是为了最终使得gap =1 ; 因为 for (int i = 0; i < n - gap; i++) // 这个for循环是控制同组中的元素依次进行插入排序, 不过是多组并排     // 采取多组并排的方式进行排序, 一共grep个组, 每次将靠前组中的一个元素排完后, 去排后面的组; 后面的组都排完后, 再次循环排// 前一个组中的下一个元素(按顺序排列)  (按组序, 按组中元素序列){                                       int end = i;int temp = a[end + gap];while (end >= 0){if (temp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = temp;}}
}时间复杂度: O(N^1.3) //(这是平均时间复杂度)
空间复杂度: O(1)

3> 选择排序

选择排序顾名思义, 从待排序序列中选出指定元素, 最后将其放到指定位置
基本思路:

  • 遍历待排序序列, 从其中选出最大(或最小)的元素, 将其放置在数组中的最前面(降序)或者最后面(升序),
  • 第二次遍历待排序序列, 从其中选出次大(或次小)的元素, 将其放置在数组中的最前面 – 降序(升序)或者最后面 – 升序(降序),
  • 如此循环往复, 直至数组中的元素全部有序。
  • 也可以同时从数组中选出最大和最小的元素, 放在数组的两侧。
选择排序的代码实现(同时选出最大和最小的元素)
// 选择排序
void SelectSort(int* a, int n)
{ int begin = 0, end = n - 1;while (begin <= end){int min = begin, max = end;          // a[min]默认为数组中第一个元素, a[max]默认为数组中最后一个元素for (int i = begin; i <= end; i++)   // 因此 a[min] 需要和 [begin+1, end] 中的元素比较{                                    //      a[max]   需要和 [begin, end-1] 中的元素比较if (a[i] < a[min])               // 取两者并集, 因此 区间为[begin, end]{min = i;}if (a[i] > a[max]){max = i;}}Swap(&a[begin], &a[min]);if (max == begin)              // 如果 最大值a[max]恰好在索引为begin的位置,那么会将最大值交换至 索引为min的位置{max = min;}Swap(&a[end], &a[max]);++begin;--end;}
}时间复杂度: O(N^2)    // 最坏和最好下均为O(N^2)
空间复杂度: O(1)      // 原数组中进行排序

4> 堆排序

数据结构 - 堆, 通过堆进行的排序被称为堆排序
基本思路:

  • 将待排序序列通过多次向下调整, 最终建立一个堆的结构
  • 按升序排序 :
    • 建大堆,
    • 堆中的父节点 >= 子节点
    • 每次排序, 将堆顶的元素(最大的元素)与堆末尾的元素交换位置,
    • (末尾所得末尾元素不计入)然后向下调整, 得到新堆
    • 如此循环往复最终使得待排序序列变为升序序列
  • 按降序排列:
    • 建小堆
    • 堆中的父节点 <= 子节点
    • 每次排序, 将堆顶的元素(最小的元素)与堆末尾的元素交换位置,
    • (末尾所得末尾元素不计入)然后向下调整, 得到新堆
    • 如此循环往复最终使得待排序序列变为降序序列
堆排序的代码实现
// 堆的向下调整
void AdjustDown(int* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] < a[child + 1]){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}// 建堆且排序
void HeapSort(int* a, int n)
{for (int i = (n - 1) / 2; i >= 0; i--) //  for循环建堆 //  建堆时间复杂度为 O(N)        {AdjustDown(a, n, i); // 向下调整时间复杂度为O(logN)}int end = n - 1;while (end > 0)// while循环进行堆排序, 时间复杂度为 O(NlogN){  // O(logN)Swap(&a[0], &a[end]);                        // 将堆顶元素换至堆末尾  , 在这里end代表堆中最后一个元素的索引--end;// 每次交换完, 进行--end, 原堆中最后一个元素不计入新堆AdjustDown(a, end + 1, 0);                      // 向下调整排序 , 在这里end+1代表新堆中元素的个数// 向下调整 时间复杂度为O(logN)}
}时间复杂度: O(NlogN)     
// 使用该种方法 从最后一个父节点开始向下调整建堆的时间复杂度为O(3n) ,也就是O(N)
// 从根节点开始 向下调整建堆的时间复杂度为 O(NlogN)
空间复杂度: O(1)

5> 冒泡排序

冒泡排序的命名十分形象, 该种排序方式就像是 将待排序序列中的元素挑选出来, 使其像一个气泡从水中冒出水面一样冒到数组的最后面
基本思路:

  • 定义两个指针, 一前一后,使其指向相邻元素。 从数组首元素开始,对相邻元素进行比较
  • 每次比较依据的原则是 使得后指针始终指向较大的那个元素 – 升序(或较小)且不改变两个指针的相对位置
  • 做法便是, 对两个指针指向的元素进行比较, 如若前指针指向的元素小于后指针指向的元素, 那么同时使两个指针移动一个位置, 然后再次进行比较
  • 如果前指针指向的元素大于后指针指向的元素, 那么交换两个元素的位置, 使得后指针指向的位置存储的是较大的那个元素。
  • 当后指针指向空时循环结束,此时就将最大的那个元素冒到了数组的最后面
  • 如此循环往复, 最终使得待排序序列变为升序
// 冒泡排序
void BubbleSort(int* a, int n)
{for (int i = 0; i < n; i++){int count = 0;for (int j = 1; j < n - i; j++){if (a[j - 1] > a[j]){Swap(&a[j - 1], &a[j]);count = 1;}}if (count == 0)       // 对于本就按照升序排列的序列, 冒泡排序外循环运行一次, 没有发生交换, 那么代表该序列有序, 直接结束冒泡排序 此时时间复杂度为最好: O(N)break;}
}时间复杂度: O(N^2)   // 最坏: O(N^2) 数组有序时可为O(N)
空间复杂度: O(1)

6> 快速排序

快速排序在大多数情况下,其排序速度远快于其他排序算法, 因此叫做快速排序
基本思路:

  • 在待排序序列中, 选定一个元素作为 key值, (一般key值为数组中第一个元素)
  • 然后定义两个变量begin , end 分别指向数组的开头和结尾
  • 然后通过whille循环遍历整个数组, begin指针在指向小于等于key值的元素时就向后移动, end指针在指向大于等于key值的元素时就向前移动
  • 当begin指向的元素大于key值时, begin停止移动; 当end指向的元素小于key值时, end也停止移动, 当两个指针均停止移动时, 我们交换这两个元素的位置
  • 当 begin与end指针指向同一位置时, 循环结束
  • 当循环结束时, 我们将开始选定作为key值的那个元素与 begin指向的元素进行交换位置
  • 上述步骤的思想是 : 使得所有小于key值的元素都在 key值之前, 所有大于key值的元素都在key值之后 (其他等于key值的元素不改变其位置)
  • 经过上述步骤, 最终使得被选定为key值的这个元素放置在了未来有序序列的正确位置
  • 然后, 我们将这个待排序序列分为 排在key值前面的和排在key值后面的这两组
  • 我们在对这两组元素分别进行上述步骤
  • 最终待排序序列变为升序序列
快速排序(递归版)
// 快速排序的第一步优化 (三数取中)
int GetMidi(int* a, int left, int right)
{int midi = (left + right) / 2;if (a[left] < a[midi]){if (a[midi] < a[right])return midi;else if (a[left] < a[right])return right;elsereturn left;}else{if (a[midi] > a[right])return midi;else if (a[left] > a[right])return right;elsereturn left;}
}// 快速排序之单趟排序的实现(Hoare版 -- 霍尔所编写)
int PartSort1(int* a, int left, int right)
{int midi = GetMidi(a, left, right); // 调用函数 GetMidi(), 返回三个索引所指向的元素中位于中间的那个元素的索引Swap(&a[midi], &a[left]);                            // 将这个元素交换至数组首位置。 int keyi = left;                                      // keyi = left ,记录Left的初值,用于一趟排序完成后, 将数组首元素交换至正确位置while (left < right){while (a[right] >= a[keyi] && left<right)        // "<=" 避免 a[left] = a[right] = a[key] 带来的死循环// && left < right, 避免极端情况, left(或right)不动, right(或left)动而出现的数组越界情况{--right;                                      }while (a[left] <= a[keyi] && left < right)        // 先 ++right, 最终保证 a[left] < a[keyi]  {++left;}Swap(&a[left], &a[right]);}Swap(&a[keyi], &a[left]);return left;
}// 快速排序之单趟排序的实现(挖坑法)
int PartSort2(int* a, int left, int right)
{int midi = GetMidi(a, left, right);Swap(&a[midi], &a[left]);int key = a[left];while (left < right){while (a[right] >= key && left < right){--right;}a[left] = a[right];while (a[left] <= key && left < right){++left;}a[right] = a[left];}a[left] = key;return left;
}//  快速排序之单趟排序的实现(前后指针法)
int PartSort3(int* a, int left, int right)
{int midi = GetMidi(a, left, right);Swap(&a[midi], &a[left]);int keyi = left;int prev = left, cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != right)  // 在这里不会出现死循环, 因此不需要等号// 前置 ++ , 先++ 再使用prev的新值{                        Swap(&a[prev], &a[cur]);   }++cur;}Swap(&a[keyi], &a[prev]);return prev;
}// 完整的快速排序(升序 递归版)
void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;if(end-begin+1 > 10){//int keyi = PartSort1(a, begin, end);      // 快排 最初霍尔所写 //int keyi = PartSort2(a, begin, end);      // 快排 挖坑法 int keyi = PartSort3(a, begin, end);        // 前后指针法QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);}else      // 快速排序第二步优化 , 小区间元素进行直接采取插入排序{InsertSort(a + begin, end - begin + 1);}
}时间复杂度: O(NlogN)     // 极端情况下, 快排为线性划分区间时为 时间复杂度为O(N^2)
空间复杂度: O(logN)      // 极端情况下, 快排为线性划分区间时为 空间复杂度为O(N)
快速排序(迭代版)

通过利用数据结构 - 栈, 控制快速排序的区间
迭代版待优化 :

  • 三数取中
  • 小区间直接插排的优化
void QuickSortNonR(int* a, int begin, int end)
//  一般begin = 0, end = n-1 , 这是为了使得begin, end分别指向数组的首尾元素 
{std::stack<int> stk;   //  STL的stack容器, 声明一个stack对象stk stk.push(end);stk.push(begin);// 将用于控制快排第一趟的首元素位置和尾元素位置存入栈中while (!stk.empty()){int left = stk.top();stk.pop();int right = stk.top();stk.pop();int keyi = PartSort3(a, left, right);// 调用快排单趟排序的实现, 对区间[left, right]中的元素进行排序if (keyi + 1 < right){stk.push(right);stk.push(keyi + 1);// 将右区间元素的首尾存入栈中}if (left < keyi - 1){stk.push(keyi - 1);stk.push(begin);// 将左区间元素的首尾存入栈中}}
}

7> 归并排序

归并排序是对分治思想的一个典型运用 。 分治法 – 分而治之
基本思路:

  • 将待排序序列不断拆一分为二 (理想上是均等拆分)
  • 通过多次递归拆分, 最后所得序列中为 只含有一个元素的序列, 此时该序列一定为有序序列 (也就是 N 个有序序列),
  • 然后我们对已有序的序列进行两两归并(每相邻两个序列进行归并),
  • 归并之后得到新的有序序列(也就是 n/2个有序序列, 每个序列中含有两个元素)
  • 最后我们多次重复上述步骤,
  • 最后一次归并使得两个最大的有序子序列归并为完整有序序列
  • 此时 待排序序列变为有序
归并排序(递归版)
// 归并排序 -- 内层实现
void _MergeSort(int* a, int* temp, int begin, int end)
{if (begin >= end)                     // 递归至 空数组或是数组中只存在一个元素{return;                           // 函数返回}int midi = (begin + end) / 2;        // 将数组分隔_MergeSort(a, temp, begin, midi);      // 递归调用函数_MergeSort() , 传入左区间的序列_MergeSort(a, temp, midi + 1, end);    // 递归调用函数_MergeSort() , 传入右区间的序列int begin1 = begin, end1 = midi;      // 当递归函数开始返回时, 此时左右区间均为有序序列, 进行归并 (第一次归并是将 单个元素数组与单个元素数组(或空数组)进行归并)int begin2 = midi + 1, end2 = end;    int index = begin;                                 // 定义变量 分别确定左右区间 begin1, end1 确定左区间首尾元素的索引 变量index用于将元素归并插入动态数组 temp 时,可以有序的连续插入while (begin1 <= end1 && begin2 <= end2 ){    // 循环结束的条件是 其中一个数组遍历完, 也就是将其中一个区间数组中的元素完全插入temp指向的动态数组中if (a[begin1] < a[begin2])                       // 判断左右区间数组中首元素那个较小, 将较小的元素尾插入temp数组{temp[index++] = a[begin1++];}else{temp[index++] = a[begin2++];}}while (begin1 <= end1)                         // 判断两个区间数组中, 谁未被遍历完, 然后继续遍历元素并插入temp指向的数组中    {temp[index++] = a[begin1++];}while (begin2 <= end2){temp[index++] = a[begin2++];}for (int i = begin; i <= end; i++)               // 将temp数组中存储的元素拷贝至a数组中指定位置中。// 将变量 index 定义的值为 begin时, 在最后一步的拷贝时, 可以起到巧妙的作用(无需定义多个变量){a[i] = temp[i];}
}// 完整的归并排序(递归版)
void MergeSort(int* a, int n)
{int* temp = new int[n];       // 在堆区new一个int类型的数组, 大小为 4n个字节, 可存储n个元素, 用于后续元素归并if (!temp){perror("new is failed");exit(-1);}_MergeSort(a, temp, 0, n - 1);    // 调用实际归并排序函数
}时间复杂度: O(NlogN)
空间复杂度: O(N)
归并排序(迭代版)
// 归并排序非递归
void MergeSortNonR(int* a, int n)
{int grep = 1;int* temp = new int[n];while (grep < n){for (int i = 0; i < n; i += 2 * grep){int begin1 = i, end1 = i + grep - 1;int begin2 = i + grep, end2 = i + 2 * grep - 1;int index = i;if (begin2 >= n){break;}if (end2 >= n){end2 = n - 1;}while (begin1 <= end1 && begin2 <= end2)// 循环结束的条件是 其中一个数组遍历完, 也就是将其中一个区间数组中的元素完全插入temp指向的动态数组中{    if (a[begin1] <= a[begin2])     // 判断左右区间数组中首元素那个较小, 将较小的元素尾插入temp数组                                 {temp[index++] = a[begin1++];}else{temp[index++] = a[begin2++];}}while (begin1 <= end1)                         // 判断两个区间数组中, 谁未被遍历完, 然后继续遍历元素并插入temp指向的数组中    {temp[index++] = a[begin1++];}while (begin2 <= end2){temp[index++] = a[begin2++];}for (int j = i; j <= end2; j++)              // 将temp数组中存储的元素拷贝至a数组中指定位置中。{a[j] = temp[j];}}grep*=2;}delete[]temp;
}时间复杂度: O(NlogN)
空间复杂度: O(N)

8> 基数排序

基数排序,又叫非比较排序。 是通过不同的关键字对待排序序列中的元素进行计数并排序
基本思路:

  • 通过哈希映射的方式将待排序序列的各个元素映射到数组的下标中
  • 然后计算每个元素出现的次数, 出现一次就对其所映射的指定位置进行+1
  • 不断地遍历整个数组, 最终映射所得数组记录了待排序序列中的不同元素的位置与相同元素的个数
  • 最后遍历映射数组, 在通过映射的方式将映射数组中的记录写回到原数组中
  • 最终, 待排序序列变为有序
// 计数排序
void CountSort(int* a, int n)
{int min = a[0], max = a[0];for (int i = 0; i < n; i++){if (a[i] < min)min = a[i];if (a[i] > max)max = a[i];}int range = max - min + 1;int* temp = new int[range] {0};for (int i = 0; i < n; i++){int num = a[i] - min;temp[num]++;}int index = 0;for (int i = 0; i < range; i++){while (temp[i]){a[index++] = i + min;temp[i]--;}}delete[] temp;
}时间复杂度: O(N+range)
空间复杂度: O(range) 

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

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

相关文章

multipath

目录 文章目录 目录什么是multipathmultipath配置文件demo1(最小化配置)demo2demo3字段解析 命令**案例&#xff1a;查看多路径设备的信息。(常用)****案例&#xff1a;刷新multipath状态**案例&#xff1a;-v2/-v3 打印信息案例&#xff1a;查看当前活动路径的设备信息案例&am…

第17章 匿名函数

第17.1节 匿名函数的基本语法 [捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 { // 函数体 }语法规则&#xff1a;lambda表达式可以看成是一般函数的函数名被略去&#xff0c;返回值使用了一个 -> 的形式表示。唯一与普通函数不同的是增加了“捕获列表”。 …

羊大师讲解鲜羊奶的营养价值

羊大师讲解鲜羊奶的营养价值 鲜羊奶是一种天然、营养丰富的食品&#xff0c;拥有独特的健康价值。它不仅具备高蛋白、低脂肪的特点&#xff0c;还富含各种维生素和矿物质&#xff0c;对人体健康有着卓越的贡献。今天&#xff0c;我们就来一探鲜羊奶的营养奥秘。 鲜羊奶的营养…

Data Linked UI

DataLinkedUl是一个Unity框架,它允许您在为您的应用程序创建用户界面时实现专业的数据驱动方法。使用此资产,您可以创建灵活的基于瓦片的任意大小的复杂接口系统。 核心功能: 灵活性-允许适应和调整数据变化,允许各种结构和功能配置,而不需要对现有系统进行重大破坏。 可伸…

AI封测需求强劲, AMD、英伟达等巨头将助推产业链增长 | 百能云芯

近期&#xff0c;超微&#xff08;AMD&#xff09;和英伟达&#xff08;NVIDIA&#xff09;相继发布了新一轮AI芯片&#xff0c;为封测产业链注入了新的活力。据业内人士透露&#xff0c;客户端对AI封测的需求愈发强劲&#xff0c;整体量能超过原先的估计&#xff0c;其中日月光…

我有才满足于自媒体行业的知识付费平台课程

行业资讯 实时行业热点新闻、企业动态资讯、社区热门话题&#xff0c;一榜打尽 通过图文、音频、视频、动态在内的多元媒介形式&#xff0c;致力于为企业提供多元化的资讯内容展示方式。 自定义咨询专栏&#xff0c;归类资讯内容&#xff0c;建立结构化内容体系 可以把资讯归…

循环使用接口返回的多值老大难?看我教你使用jmeter掌握72变!

有同学在用jmeter做接口测试的时候&#xff0c;经常会遇到这样一种情况&#xff1a; 就是一个接口请求返回了多个值&#xff0c;然后下一个接口想循环使用前一个接口的返回值。 这种要怎么做呢&#xff1f; 有一定基础的人&#xff0c;可能第一反应就是先提取前一个接口返回…

公有云迁移研究——AWS Route53

大纲 1 什么是Route 532 Route 53能做些什么# 3 通过DNS托管来实现分流3.1 创建DNS托管3.2 对托管创建记录对流量进行分配 4 通过流量策略来对流量进行分流4.1 创建流量策略 5 对比两者的区别6 推荐 在给客户从本地机房往AWS迁移的过程中&#xff0c;我们接到如下需求&#xff…

mysql中year函数有什么用

YEAR()函数用于提取日期或日期时间值中的年份。可以用于提取DATE、DATETIME或TIMESTAMP列中的年份。 SELECT YEAR(date_column) FROM table;# 提取字符串中的数据SELECT YEAR(2023-07-19) FROM table_name;

华容道问题求解第一部分_思路即方案设计

一、前言 华容道是一种传统的益智游戏&#xff0c;通常由一个长方形木板和若干个方块组成。其中包括一个或多个不同颜色的方块&#xff08;也称为车块&#xff09;和其他大小相同的方块&#xff08;也称为障碍块&#xff09;。游戏的目标是将车块从木板的一个端点移动到另一个…

销售工作中如何满足客户的需求?

销售工作中如何满足客户的需求&#xff1f; 在销售工作中&#xff0c;如果想要满足客户需求&#xff0c;第一步是要搞清楚客户的需求是什么&#xff0c;不能仅仅听客户的表面需求&#xff0c;在表面需求下隐藏的潜在需求是什么&#xff0c;另外还有客户的核心需求是什么&#…

举个栗子!Alteryx 技巧(8):运用批处理宏,巧妙实现分析流程重复使用

分析用户在 Alteryx Designer 做了一个比较复杂的逻辑处理&#xff0c;因为它的使用频率比较高&#xff0c;如果可以复用就能事半功倍。那么&#xff0c;如何实现多次快速使用呢&#xff1f;方法很简单&#xff1a;运用批处理宏&#xff0c;巧妙实现分析流程重复使用&#xff0…

【Tomcat】java.net.BindException “Address already in use: NET_Bind“

问题 17:37 Error running Tomcat 7.0.76: Unable to open debugger port (127.0.0.1:14255): java.net.BindException "Address already in use: NET_Bind"调整 把14255 改成 49963就正常了 附件 netstat -aon|findstr "49963" taskkill -f -pid xxx…

Linux入门笔记

1 Linux概述 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议。它支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心…

【网络奇缘】- 如何自己动手做一个五类|以太网|RJ45|网络电缆

​ ​ &#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 本篇文章关于计算机网络的动手小实验---如何自己动手做一个网线&#xff0c; 也是为后面的物理层学习进…

旋转设备状态监测与预测性维护:提高设备可靠性的关键

在工业领域的各个行业中&#xff0c;旋转设备都扮演着重要的角色。为了确保设备的可靠运行和预防潜在的故障&#xff0c;旋转设备状态监测及预测性维护变得至关重要。本文将介绍一些常见的旋转设备状态监测方法&#xff0c;并探讨如何利用这些方法来实施预测性维护&#xff0c;…

我最喜欢的白版应用,AI加持的新功能开源!强烈推荐

Excalidraw 把他们的文本到图表的功能开源了 Excalidraw是一个虚拟白板应用&#xff0c;专门用于绘制类似手绘的图表。它提供了一个无限的、基于画布的白板&#xff0c;具有手绘风格&#xff0c;支持多种功能。 之前我分享的&#xff1a;72张PNG&#xff0c;图解机器学习 里面…

数电笔记之寄存器

数电 1 数字电路基础 1.2 二进制数据表达 1.2.1 二进制简介 1.2.2 用二进制表达文字 常用的中文字符集&#xff1a;GBK&#xff0c;UTF8 1.2.3 用二进制表达图片 图片像素化&#xff0c;像素数字化 1.2.4 用二进制表达声音 1.2.5 用二进制表达视频 1.3 数字电路 1.3…

harmony开发之image组件的使用

HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。 在传统的单设备系统能力基础上&#xff0c;HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念&#xff0c;能够支持手机、平板、智能穿戴、智慧屏、车机、PC、智能音箱、耳机、AR/VR眼镜等多种终端…

一位半加法器,一位全加器,四位全加器

我们这里的加法器只考虑一位的情况。 当我们两个一位相加的话&#xff0c;那么就有两个输入&#xff0c;两个输出&#xff0c;两个输入很好理解&#xff0c;就是两个个位上的数字&#xff0c;0或者是1&#xff0c;那么为什么需要有有个输出呢&#xff1f;难道不是输出一个数就…