【数据结构】08排序

08 排序

  • 1. 冒泡排序(BubbleSort)
    • 1.1 循环嵌套实现
    • 1.2 递归实现
  • 2. 选择排序
    • 2.1 嵌套循环实现
    • 2.2 递归实现
  • 3. 插入排序
  • 4. 希尔排序
    • 4.1 代码实现
  • 5. 快速排序
  • 5.1 代码实现
  • 6. 归并排序
    • 6.1 递归实现
    • 6.2 循环实现
  • 7. 堆排序
    • 7.1 构建大顶堆
    • 7.2 堆排序
    • 7.3 代码实现
  • 8. 计数排序
  • 9. 桶排序
  • 10. 基数排序
    • 10.1 代码实现

1. 冒泡排序(BubbleSort)

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

1.1 循环嵌套实现

// 循环嵌套实现
// len是元素个数
void BubbleSort1(int* arr, int len)
{for (int i = len - 1; i > 0; i--) // 比较len-1趟{// 每趟比较n-1个数据for (int j = 0; j < i; j++) // 只需要比较0,1,2,..,i之间的数据i之后的元素是已经排好序了{if (arr[j] > arr[j + 1]){int tmp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = tmp;}}}
}

1.2 递归实现

每层递归中比较前n-1个元素,一共递归n趟

// 递归实现
void BubbleSort2(int* arr, int len)
{if (len < 2) // 元素为1个或0个不需要排序{return;}for (int i = 0; i < len - 1; i++)// 每趟比较0,1,...,n-1{if (arr[i] > arr[i + 1]){int tmp = arr[i + 1];arr[i + 1] = arr[i];arr[i] = tmp;}}BubbleSort2(arr, --len); // 下一趟
}

2. 选择排序

从头到尾扫描序列,找出最小的一个元素,和第一个元素做交换,接着从剩下的元素中继续这种选择和交换的方式,最终得到一个有序序列。

2.1 嵌套循环实现

// 循环嵌套实现选择排序
void SelectSort1(int* arr, int len)
{int i ;for (i = 0; i < len - 1; i++) // 一共需要len-1趟比较{int index =i; for (int j = i + 1; j < len; j++) // 每趟需要比较i+1,i+2,....,len-1之间的元素,i之前的元素是排序好的{if (arr[j] < arr[index])  //记录最小值的位置{index = j;}}// 找到最小值,如不过不是第一个元素,则交换第一个元素和最小值if (index != i){int tmp = arr[index];arr[index] = arr[i];arr[i] = tmp;}}
}

2.2 递归实现

// 递归实现选择排序
void SelectSort2(int* arr, int len)
{if (len < 2) // 1个或两个元素不需要排序{return;}// 每趟循环需要找出最小值位置int index = 0;for (int i = 1; i < len; i++){if (arr[i] < arr[index]) // 记录最小值位置{index = i;}}if (index != 0) // 交换首个元素和最小值{int tmp = arr[index];arr[index] = arr[0];arr[0] = tmp;}SelectSort2(arr + 1, --len);
}

3. 插入排序

插入排序原理:通过构建有序序列,对未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

// 插入排序
void InsertSort(int* arr, int len)
{int i,j = 0;for (i = 1; i < len; i++)// 对第一个数不需要排序,从第二个数开始,从后向前比较{int tmp = arr[i]; // 待排序元素,已经排序元素为arr[0]~arr[i-1]for (j = i - 1; j >= 0; j--) // 从已经排序好的元素的最右边开始,从后向前遍历{if (arr[j] <=tmp) // 找到小于当前元素则不需要再后移了,此时需要插入到小于当前元素之后的一位{break;}// 把大于当前待排序元素的元素后移arr[j + 1] = arr[j];}// 插入当前元素arr[j + 1] = tmp;}
}

4. 希尔排序

希尔排序(Shell)是插入排序的一种,它是针对直接插入排序算法的改进。希尔排序的基本思想:把待排序的数列分成多个组,然后对每个组进行插入排序,先让数列整体大致有序,然后多次调整分组方式,使数列更加有序,最后再使用一次插入排序,整个数列将全部有序。
流程:

  • 初始
    在这里插入图片描述
  • 分组在这里插入图片描述
  • 对每个组进行插入排序
    在这里插入图片描述
  • 调整元素间隔,重新分组,并对每组进行插入排序
    在这里插入图片描述
  • 调整元素间隔,重新分组,并对每组进行插入排序
    在这里插入图片描述
    希尔排序的核心思想是化远为近:1)查找次数减少;2)移动元素次数减少

4.1 代码实现

希尔排序是在插入排序的基础上,每次取固定步长的间隔组成的分组,在其中进行插入排序。具体代码实现

// 间隔step执行插入排序
// start_pos每组的起始位置
// step 每组每个元素之间间隔的步长
void GroupSort(int* arr, int len, int start_pos, int step)
{int i=0, j=0;for (i = start_pos + step; i < len; i += step) // arr[start_pos]是第一个元素,跳过,从第二个开始即start_pos+step{int tmp = arr[i];//待排序袁旭,其中 arr[start_pos],...,arr[start_pos+step*(i-1)]是排序好的for (j = i - step; j >= 0; j -= step)// 从后往前组内进行插入排序{if (arr[j] <= tmp){break;}arr[j + step] = arr[j]; // 组内右移元素}// 插入当前元素arr[j + step] = tmp;}
}void ShellSort(int* arr, int len)
{// step是步长,每次都为原来的一半取整数,最后一次必定为1for (int step = len / 2; step > 0; step = step / 2){// 此时分为了step个组,对step个组内进行间隔step之间的元素插入排序for (int j = 0; j < step; j++){GroupSort(arr, len, j, step);}}
}

5. 快速排序

快速排序的基本思想是:

  1. 先从数列中取出一个元素作为基准数
  2. 扫描数列,将比基准数小的元素放在它的左边,大于或等于基准数的元素全部放到它的右边,得到左右两个区间
  3. 再对左右区间重复第1,2步,直到各个区间小于两个元素
    流程:挖坑填数+分治思想
  • 初始化
    在这里插入图片描述

  • 这里以左指针指向的第一个为基准数,以右指针指向的第一个数开始扫描数组:1<4,将它插入到4左指针指向的位置;移动左指针
    在这里插入图片描述
    在这里插入图片描述

  • 3<4,继续移动左指针;5>4,将5填入到右指针指向的位置;移动右指针,7>4,继续移动右指针,指向2
    在这里插入图片描述

  • 2<4 将2填入到左指针指向位置,移动左指针,左指针指向6,6>4,将6填入到右指针指向的位置,移动右指针
    在这里插入图片描述
    在这里插入图片描述

  • 此时左指针和右指针重叠,把基准元素插入到左右指针指向的位置。

  • 下一次比较从当前基准数的左区间和右区间分别开始迭代。
    在这里插入图片描述

可以看到快速排序算法需要维护左指针,右指针,维护基准数。

5.1 代码实现

具体的代码实现如下:

void QuickSort(int* arr, int len)
{if (len < 2){return;}int tmp = arr[0];	// 选取最左边的数作为基准数int left = 0; // 左下标int right = len - 1; // 右下标int moving_flag = 2; // 移动左下标还是右下标标志while (left < right){if (moving_flag == 2) // 移动右下标{if (arr[right] >= tmp) // 大于基准数,则继续移动右下标{right--;continue;}	// 小于基准数,把它填入到左下标对应的坑中arr[left] = arr[right];// 左下标移动left++;// 下次将继续移动左下标moving_flag = 1;continue;}if (moving_flag == 1) // 移动左下标{if (arr[left] < tmp) // 小于基准数,则继续移动左下标{left++;continue;}// 大于基准数,把它填入到右下标对应的坑中arr[right] = arr[left];// 移动右下标right--;moving_flag = 2;// 下次移动右下标continue;}}// 循环结束,左右下标重合,填入基准数的值arr[left] = tmp;// 对基准数左边区间进行排序QuickSort(arr, left);// 对基准数右边区间进行排序QuickSort(arr + left + 1, len - left - 1);
}

6. 归并排序

归并排序(Merge Sort)就是将已经有序的子数列合并得到另一个有序的数列。
归是归并的归,不是递归,归并排序就是合并排序。
流程:

  • 初始化
    在这里插入图片描述
    在这里插入图片描述

  • 归并排序
    在这里插入图片描述

  • 继续归并
    在这里插入图片描述

  • 最终结果
    在这里插入图片描述

6.1 递归实现

流程:
在这里插入图片描述
代码

// 利用递归实现归并排序
// arr是待排序数组
// arr_tmp是用于排序的临时数组的首地址
// start是排序区间第一个元素的位置
// end是排序区间最后一个元素的位置
void _mergeSort(int* arr,int* arr_tmp, int start,int end)
{if (start >= end) // 表示该区间的元素少于两个,递归终止{return;}int mid = (start + end) / 2; // 计算排序区中间的位置int start1 = start, end1 = mid; // 左区间int start2 = mid + 1, end2 = end;// 右区间_mergeSort(arr, arr_tmp, start1, end1); // 对左边区间进行递归拆分_mergeSort(arr, arr_tmp, start2, end2); // 对右边区间进行递归拆分// 对区间内的元素进行合并排序// 把区间左右两边合并到已经排序数组arr_tmp中// 从arr_tmp的start开始int i = start;while (start1 <= end1 && start2 <= end2){arr_tmp[i++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];}while (start1 <= end1) // 把左边剩下的追加到arr_tmp;{arr_tmp[i++] = arr[start1++];}while (start2 <= end2) // 把右边剩下的追加到arr_tmp{arr_tmp[i++] = arr[start2++];}// 把已经排序好的数组,复制到arr中memcpy(arr+start, arr_tmp+start, sizeof(int) * (end - start + 1));
}void MergeSort(int* arr, int len)
{// 创建临时数组int* arr_tmp = new int[len];memset(arr_tmp, 0, sizeof(int) * len);_mergeSort(arr, arr_tmp, 0, len - 1);delete[]arr_tmp;
}

6.2 循环实现

// 利用循环实现归并排序
void mergeSort(int* arr, int len)
{// 创建临时数组,用于存放已排序元素int* arr_tmp = new int[len];memset(arr_tmp, 0, sizeof(int) * len);for (int i = 1; i < len; i = i * 2) // 每趟选取i个元素作为左右区间{for (int j = 0; j < len; j = j + i * 2) // 把len长度按照i*2 拆分{int start = j; // 起始int mid = min(start + i, len); // 中间 ,考虑分配不均int end = min(start + i * 2, len); // 结尾,考虑分配不均的情况int k = start;int start1 = start, end1 = mid;int start2 = mid, end2 = end;while (start1 < end1 && start2 < end2){arr_tmp[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];}// 把左边剩余元素追加while (start1 < end1){arr_tmp[k++] = arr[start1++];}// 把右边剩余元素追加while (start2 < end2){arr_tmp[k++] = arr[start2++];}}int* ptr_tmp = arr;arr = arr_tmp;arr_tmp = ptr_tmp;}if (arr!=arr_tmp){memcpy(arr, arr_tmp, sizeof(int) * len);}delete [] arr_tmp;
}

7. 堆排序

堆排序是利用堆这种数据结构而设计的一种排序算法,堆具备以下的特点:

  • 完全二叉树(从上到下,从左到右都是满的,最后一层的结点都连续集中在最左边),对于用数组存储的完全二叉树有:N[i]的左子结点N[2i+1],右子结点N[2i+2],父结点N[(i-1)/2]
  • 二叉树每个结点的值都大于等于其左右子树结点的值称为大顶堆;或者每个结点的值都小于等于其左右子树结点的值称为小顶堆。
    在这里插入图片描述

7.1 构建大顶堆

流程:
首先利用heapify即元素下沉的方法,从最后一个元素的父结点开始,不断下沉小元素,构建一个大顶堆

  • 比较结点的两个子结点,如果结点值都大于两个子结点,则不交换。不断向前
    在这里插入图片描述
  • 比较两个子结点,如果结点值小于子结点,取子结点最大值的那个结点与结点交换。并对交换后的结点进行同样的操作。
    如图中所示,结点0的左子结点和右子结点都大于0,取最大的那个结点即6,与0交换。此时0没有左子结点和右子结点则完成。
    在这里插入图片描述
  • 比较两个子结点,如果结点值小于子结点,取子结点最大值的那个结点与结点交换。并对交换后的结点进行同样的操作。
    如图中所示,结点1小于结点8,交换两个结点。之后继续比较结点的左子结点和右子节点,此时两个子结点都大于1,取最大的子结点7,交换。
    在这里插入图片描述

此时已经完成了所有结点的比较,构建出了一个大顶堆。可以看到8>6,8>7,6>5,6>0,7>1,7>4,5>2,5>3。

用循环实现heapify操作

void Swap(int* elem1, int* elem2)
{int tmp = *elem2;*elem2 = *elem1;*elem1 = tmp;
}
// 元素下沉
// 待排序数组地址,start-待下沉元素结点的下标,end待排序数组最后一个元素的下标
void heapify(int* arr, int start, int end)
{// 确定下沉结点和左子结点位置int parent = start;int son = 2 * start + 1; // 先比较左子结点while (son <= end)// 下标不越界{// 比较两个子结点的大小if ((son+1 <= end) && (arr[son] < arr[son+1])) // 右子结点存在 且 左子结点小于右子结点{son++; // 两个子节点中大的是右子节点}if (arr[parent] > arr[son]) // 比左右子结点都大,则不需要交换元素{return;}Swap(&arr[parent], &arr[son]); // 交换父子结点内容parent = son; // 继续向下son = 2 * parent + 1; // 左子结点}
}void HeapSort(int* arr, int len)
{// 从最后一个元素的父结点开始初始化堆for (int i = (len - 1) / 2; i >= 0; i--){heapify(arr, i, len - 1);}
}

用递归实现heapify操作

// 递归实现heapify
void heapify2(int* arr, int start, int end)
{// 确定下沉结点和左子结点位置int parent = start;int son = 2 * start + 1;if (son > end){return;}if ((son + 1 <= end) && arr[son] < arr[son + 1]) // 选择左右子结点最大的{son = son + 1;}if (arr[parent] > arr[son]) // 待下沉结点比左右子结点都大,无需下沉{return;}// 交换父结点与大的子结点Swap(&arr[parent], &arr[son]);// 对子结点进行heapifyheapify2(arr, son, end);
}

7.2 堆排序

在将数组初始化为大顶堆之后,交换首个元素与待排序数组的最后一个元素的位置(此时带排序数组的最后一个元素一定是最大的元素),并从交换后的首个元素进行下沉操作,除掉交换后的最后一个元素,构建大顶堆,如此循环。
在这里插入图片描述

在这里插入图片描述

7.3 代码实现

void Swap(int* elem1, int* elem2)
{int tmp = *elem2;*elem2 = *elem1;*elem1 = tmp;
}// 元素下沉
// 待排序数组地址,start-待下沉元素结点的下标,end待排序数组最后一个元素的下标
void heapify(int* arr, int start, int end)
{// 确定下沉结点和左子结点位置int parent = start;int son = 2 * start + 1;while (son <= end)// 下标不越界{// 比较两个子结点的大小if ((son+1 <= end) && (arr[son] < arr[son+1])) // 右子结点存在 且 左子结点小于右子结点{son++; // 两个子节点中大的是右子节点}if (arr[parent] > arr[son]) // 比左右子结点都大,调整完毕{return;}Swap(&arr[parent], &arr[son]); // 否则交换父子结点内容parent = son; // 继续向下son = 2 * parent + 1;}
}// 堆排序
void HeapSort(int* arr, int len)
{// 从最后一个元素的父结点开始初始化堆for (int i = (len - 1) / 2; i >= 0; i--){heapify(arr, i, len - 1);}for (int i = 0; i < len; i++){cout << arr[i] << " ";}cout << endl;// 把待排序数组第一个元素和最后一个元素交换,并从第一个元素开始进行下沉操作for (int i = len - 1; i > 0; i--){Swap(&arr[0], &arr[i]);heapify(arr, 0, i - 1);}
}

8. 计数排序

计数排序原理很简单,申请一个计数数组,遍历待排序数组,对每个出现的数据元素在计数数组的对应下标进行计数。遍历完成后,根据计数数组计数个数,对数据进行还原。
代码实现:

// 获取数组中最大元素的值
int array_max(int* arr, int len)
{int max_elem = arr[0];for (int i = 1; i < len; i++){if (arr[i] > max_elem)max_elem = arr[i];}return max_elem;
}void CountSort(int* arr, int len)
{int max_elem = array_max(arr, len);int* arr_tmp = new int[max_elem + 1];memset(arr_tmp, 0, sizeof(int) * (max_elem + 1));// 计数for (int i = 0; i < len; i++){arr_tmp[arr[i]]++;// arr_tmp[arr[i]]的计数值++}// 重新填充int ii = 0;for (int j = 0; j < max_elem + 1; j++) // 遍历arr_tmp,下标对应的就是原数组的元素{for (int k = 0; k < arr_tmp[j]; k++) // 填充arr_tmp[jj]个{arr[ii++] = j;}}
}

9. 桶排序

桶排序(BucketSort)的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,然后再对每个桶分别排序(可以使用冒泡排序,快速排序等排序方法),最后把全部桶的数据合并。

void BubbleSort(int* arr, int len)
{for (int i = len - 1; i > 0; i--) // 比较len-1趟{// 每趟比较n-1个数据for (int j = 0; j < i; j++) // 只需要比较0,1,2,..,i之间的数据i之后的元素是已经排好序了{if (arr[j] > arr[j + 1]){int tmp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = tmp;}}}
}void BucketSort(int* arr, int len)
{int bucket[5][5];  // 分配5个桶,实际按照数据大小调整,每个桶最多五个元素int bucketsize[5]; // 每个桶中的元素个数计数memset(bucket, 0, sizeof(bucket));memset(bucketsize, 0, sizeof(bucketsize));// 把数据arr放入桶中for (int i = 0; i < len; i++){bucket[arr[i] / 10][bucketsize[arr[i] / 10]++] = arr[i];}// 对每个桶中的数据进行快速排序for (int i = 0; i < 5; i++){BubbleSort(bucket[i], bucketsize[i]);}// 再把每个桶中的数据填充到arr中int k = 0;for (int i = 0; i < 5; i++){for (int j = 0; j < bucketsize[i]; j++){arr[k++] = bucket[i][j];}}
}

10. 基数排序

基数排序(Radix Sort)是桶排序的扩展,它的基本思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较。
具体做法是:将所有带比较数字统一为一样的数位长度,数位较短的数前面补零。然后从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,就变成了一个有序数列。

  • 第一次分配和收集
    在这里插入图片描述
  • 第二次分配和收集
    在这里插入图片描述
  • 第三次分配和收集
    在这里插入图片描述

10.1 代码实现

// 获取最大元素
int getMax(int* arr, int len)
{int max_elem = arr[0];for (int i = 1; i < len; i++){if (arr[i] > max_elem){max_elem = arr[i];}}return max_elem;
}// 按base位进行分配
void _radixsort(int* arr, int len, int base)
{int* arr_tmp = new int[len];memset(arr_tmp, 0, sizeof(int) * len);int bucket[10] = { 0 }; // 初始化桶0,1,2,...,9for (int i = 0; i < len; i++) // 按位数计数{bucket[arr[i] / base % 10] ++;}// 累加bucketfor (int i = 1; i < 10; i++){bucket[i] = bucket[i] + bucket[i - 1];}// 存放for (int i = len - 1; i >= 0; i--){arr_tmp[bucket[arr[i] / base % 10] - 1] = arr[i];bucket[arr[i] / base % 10]--;}memcpy(arr, arr_tmp, sizeof(int) * len);delete[] arr_tmp;
}void RadixSort(int* arr, int len)
{// 获取最大数值,决定分配收集的次数int max_elem = getMax(arr, len);int base = 1; // 从个位开始while (max_elem / base != 0){_radixsort(arr, len, base);base = base * 10; // 向前一位}
}

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

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

相关文章

春秋云镜 CVE-2023-51048

靶标介绍&#xff1a; S-CMS v5.0 被发现存在SQLI。 开启靶场 根据题目查找S-CMS v5.0漏洞&#xff0c;百度没有查询到&#xff0c;使用必应搜索S-CMS v5.0 查找到githubCVE-2023-51052的描述 S-CMS v5.0 was discovered to contain a SQL injection... CVE-2023-51052 Git…

达梦数据库的AWR报告

达梦数据库的AWR报告 数据库快照是一个只读的静态的数据库。 DM 快照功能是基于数据库实现的&#xff0c;每个快照是基于数据库的只读镜像。通过检索快照&#xff0c;可以获取源数据库在快照创建时间点的相关数据信息。 为了方便管理自动工作集负载信息库 AWR&#xff08;Auto…

C++修炼之路之多态---多态的原理(虚函数表)

目录 一&#xff1a;多态的原理 1.虚函数表 2.原理分析 3.对于虚表存在哪里的探讨 4.对于是不是所有的虚函数都要存进虚函数表的探讨 二&#xff1a;多继承中的虚函数表 三&#xff1a;常见的问答题 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗--…

Vue3+TS版本Uniapp:封装uni.request请求配置

作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者✍/CSDN百万访问博主/B站千粉前端up主 封装请求配置项 封装拦截器封装uni.request 封装拦截器 uniapp的封装逻辑不同于Vue3项目中直接使用axios.create()方法创建实例&#xff08;在create方法中写入请求…

【探讨】RocketMQ消息灰度方案-消息逻辑隔离

vivo 鲁班平台 RocketMQ 消息灰度方案 - 稀土掘金分布式- vivo鲁班RocketMQ平台的消息灰度方案MQ消息在生产环境和灰度环境隔离一般怎么实现?消息隔离的原则 中心正常消费者,可以同时消费正常的消息和特定标签的消息(自动识别);特定标签的消费者,只能消费特定标签的消息。灰…

内存管理下及模板初阶

嗨喽&#xff0c;今天阿鑫给大家带来内存管理下以及模板初阶的博客&#xff0c;下面让我们开始今天的学习吧&#xff01; 内存管理下及模板初阶 new和delete的实现原理定位new表达式(placement-new)常见面试题泛型编程函数模板类模板 1. new和delete的实现原理 1.1 内置类型…

用全连接对手写数字识别案例(附解决TensorFlow2.x没有examples问题)

数据集介绍 数据集直接调用可能出现问题&#xff0c;建议从官网直接下载下来&#xff0c;下载存在这四个文件 手写数字识别数据集下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nqhP4yPNcqefKYs91jp9ng?pwdxe1h 提取码&#xff1a;xe1h 55000行训练数据集&a…

【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建+内核源码获取与配置+内核交叉编译+内核镜像挂载)

【树莓派Linux内核开发】入门实操篇&#xff08;虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载&#xff09; 文章目录 【树莓派Linux内核开发】入门实操篇&#xff08;虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载&#xff09;一、搭建…

判断完数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int n 0;int i 1;int j 0;int result 1;//提示用户&#xff1b;printf("请输入一个…

目标检测网络YOLO进化之旅

yolo系列网络在目标检测领域取得了巨大的成功&#xff0c; 尤其是在工程实践中&#xff0c; 以其出色的性能优势获得了广泛的应用落地。 YOLO的前3个版本是由同一个作者团队出品&#xff0c; 算是官方版本。 之后的版本都是各个研究团队自己改进的版本&#xff0c; 之间并无明…

基础SQL DDL语句

MySQL的DDL&#xff08;Data Definition Language&#xff09;语句用于定义或修改数据库结构。 DDL数据库操作 查看所有的数据库 show databases; 红色圈起来的是系统数据库&#xff0c;是系统自带的 mysql&#xff1a;包含存储MySQL服务器运行时所需信息的表。这包括数据字典…

【Linux】MySQL的安装及配置(Ubuntu-18.04)

一、安装MySQL 分别安装MySQL服务器、MySQL客户端、C/C开发库 sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev 二、配置MySQL 1.查看默认配置文件&#xff0c;此处的user和password为默认提供的&#xff0c;…

Ceph 分布式文件系统 搭建及使用

一、Ceph 介绍 在当今数据爆炸式增长的时代&#xff0c;企业对于可靠、可扩展的存储解决方案的需求日益迫切。Ceph 作为一种开源的、可伸缩的分布式存储解决方案&#xff0c;正逐渐成为企业级存储领域的热门选择。Ceph是一种由Radicalbit公司开发的开源分布式存储系统&#xf…

ElasticSearch虚拟机安装(单机版)

1.下载7.10.2 下载链接&#xff0c;选择LINUX X86_64下载 2.创建用户 useradd es也可以使用系统默认用户&#xff08;非root&#xff09;,root用户会报错 3.解压 tar xvf elasticsearch-7.10.2-linux-x86_64.tar.gz假定目录在/home/es/elasticsearch-7.10.2-linux-x86_64 …

Spring Boot | Spring Boot 默认 “缓存管理“ 、Spring Boot “缓存注解“ 介绍

目录: 一、Spring Boot 默认 "缓存" 管理 :1.1 基础环境搭建① 准备数据② 创建项目③ 编写 "数据库表" 对应的 "实体类"④ 编写 "操作数据库" 的 Repository接口文件⑤ 编写 "业务操作列" Service文件⑥ 编写 "applic…

JavaCard学习笔记: CAP Component 之 Class Component

文章目录 整体结构tag和size字段signature_pool_length和signature_pooltype_descriptor结构导入类型编码导入项签名示例导入类导入数组导入远程方法 interfaces[]interface_info结构flagsinteface_countsuperinterfacesinterface_name class_info_compact classes[]结构flagsi…

基于Springboot的网上商城购物系统

基于SpringbootVue的网上商城购物系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 商品信息 商品资讯 后台登录页面 后台管理首页 用户管理 商品分类管…

记录一个hive中跑insert语句说没创建spark客户端的问题

【背景说明】 我目前搭建离线数仓&#xff0c;并将hive的执行引擎改成了Spark&#xff0c;在将ods层的数据装载到dim层&#xff0c;执行insert语句时报如下错误 【报错】 [42000][40000] Error while compiling statement: FAILED: SemanticException Failed to get a spark…

星链全解1

星链基本信息 星链卫星的寿命约为5年&#xff0c;最终目标是发射42000颗卫星。最初&#xff0c;每颗卫星重约260公斤&#xff0c;与1吨以上的大卫星相比属于“小卫星”。现在&#xff0c;向V2版进化的星链卫星重量近800公斤&#xff0c;约为老一代卫星的3倍。 点击“星链地图…

【Entity Framework】聊一聊EF如何使用数据库函数

【Entity Framework】聊一聊EF如何使用数据库函数 文章目录 【Entity Framework】聊一聊EF如何使用数据库函数一、数据库函数的类型二、内置函数与用户定义的函数四、聚合函数、标量函数和表值函数五、Niladic函数六、EF Core 中的数据库函数映射6.1 内置函数映射6.2 EF.Functi…