当前位置: 首页 > wzjs >正文

美容院网站制作网站站长

美容院网站制作,网站站长,没有域名可以做网站吗,中国宁波网首页目录 引言十大排序算法1. 冒泡排序 (Bubble Sort)2. 选择排序 (Selection Sort)3. 插入排序 (Insertion Sort)4. 希尔排序 (Shell Sort)简单代码说明关键特点 5. 归并排序 (Merge Sort)6. 快速排序 (Quick Sort)7. 堆排序 (Heap Sort)8. 计数排序 (Counting Sort)9. 桶排序 (Bu…

目录

  • 引言
  • 十大排序算法
    • 1. 冒泡排序 (Bubble Sort)
    • 2. 选择排序 (Selection Sort)
    • 3. 插入排序 (Insertion Sort)
    • 4. 希尔排序 (Shell Sort)
      • 简单代码说明
      • 关键特点
    • 5. 归并排序 (Merge Sort)
    • 6. 快速排序 (Quick Sort)
    • 7. 堆排序 (Heap Sort)
    • 8. 计数排序 (Counting Sort)
    • 9. 桶排序 (Bucket Sort)
    • 10. 基数排序 (Radix Sort)
    • 总结
  • 排序链表
    • 我的解题
    • 代码优化

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:算法专栏
  • 💥 标题:【Hot 100】 148. 排序链表
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

引言

今天的题目是对链表进行排序,所以我先简单回顾一下十大排序算法的基本思想以及C++代码实现。

十大排序算法

1. 冒泡排序 (Bubble Sort)

基本思想:重复地遍历要排序的数列,一次比较两个元素,如果顺序错误就交换它们。每次遍历后,最大的元素会"冒泡"到最后。

void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {swap(arr[j], arr[j+1]);}}}
}

2. 选择排序 (Selection Sort)

基本思想:每次从未排序部分选择最小(或最大)的元素,放到已排序部分的末尾。

void selectionSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {int min_idx = i;for (int j = i+1; j < n; j++) {if (arr[j] < arr[min_idx]) {min_idx = j;}}swap(arr[i], arr[min_idx]);}
}

3. 插入排序 (Insertion Sort)

基本思想:将未排序部分的第一个元素插入到已排序部分的适当位置。

void insertionSort(int arr[], int n) {for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}
}

4. 希尔排序 (Shell Sort)

讲解视频(这个视频讲的非常好)

希尔排序就是使用分治思想的插入排序,他使用了插入排序的两个优点:

  1. 如果数组基本有序的话,插入排序的时间复杂度为 O(n)
  2. 数据量较小时,排序效率较高

在这里插入图片描述

用班级排队来理解希尔排序

想象你是一个体育老师,要帮全班同学按身高从矮到高排队。如果直接用插入排序(让每个同学一个个找到自己的位置),对于乱序的队伍会非常耗时。希尔排序的做法更聪明:

  1. 先把同学分成几组:比如先让每间隔4个同学为一组(第1、5、9…个同学一组,第2、6、10…个同学一组,以此类推)

  2. 在组内排好序:让每个小组内部先按身高排好

  3. 缩小分组范围:然后让每间隔2个同学为一组,再次排序

  4. 最后全体一起排:最后取消分组,全体一起做一次完整的插入排序

这时候队伍已经基本有序了,最后这次完整的排序会非常快!

为什么这样更快?

  • 前期分组排序:就像先把大问题拆成小问题解决
  • 逐步细化:每次排序后队伍都更有序一点
  • 最后一步轻松:当队伍基本有序时,插入排序效率最高

简单代码说明

void shellSort(int arr[], int n) {// 初始间隔是数组长度的一半for (int gap = n/2; gap > 0; gap /= 2) {// 对每个分组进行插入排序for (int i = gap; i < n; i++) {int temp = arr[i]; // 记住当前这张"牌"int j;// 把比当前"牌"大的往后移for (j = i; j >= gap && arr[j-gap] > temp; j -= gap) {arr[j] = arr[j-gap];}// 把当前"牌"放到正确位置arr[j] = temp;}}
}

关键特点

  • 不是相邻比较:普通插入排序是相邻元素比较,希尔排序是"跳着比较"
  • 越来越精确:比较的间隔从大到小,最后变成1(就是普通插入排序)
  • 前期工作不白费:每次分组排序都为下一次创造了更好的基础

记住这个算法就像"先粗排,再细排,最后精排"的过程,这样就能既快又好地完成排序任务!

5. 归并排序 (Merge Sort)

基本思想:分治法,将列表分成两半,分别排序,然后合并两个有序列表。

void merge(int arr[], int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;int L[n1], R[n2];for (int i = 0; i < n1; i++) L[i] = arr[l + i];for (int j = 0; j < n2; j++) R[j] = arr[m + 1 + j];int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) arr[k++] = L[i++];else arr[k++] = R[j++];}while (i < n1) arr[k++] = L[i++];while (j < n2) arr[k++] = R[j++];
}void mergeSort(int arr[], int l, int r) {if (l < r) {int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);merge(arr, l, m, r);}
}

6. 快速排序 (Quick Sort)

基本思想:分治法,选择一个基准元素,将数组分为两部分,一部分小于基准,一部分大于基准,然后递归排序。

int partition(int arr[], int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;swap(arr[i], arr[j]);}}swap(arr[i + 1], arr[high]);return i + 1;
}void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}

7. 堆排序 (Heap Sort)

基本思想:利用堆这种数据结构进行排序,首先构建最大堆,然后逐个取出堆顶元素。

void heapify(int arr[], int n, int i) {int largest = i;int l = 2 * i + 1;int r = 2 * i + 2;if (l < n && arr[l] > arr[largest]) largest = l;if (r < n && arr[r] > arr[largest]) largest = r;if (largest != i) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(int arr[], int n) {for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}for (int i = n - 1; i > 0; i--) {swap(arr[0], arr[i]);heapify(arr, i, 0);}
}

8. 计数排序 (Counting Sort)

基本思想:适用于整数排序,统计每个元素出现的次数,然后计算每个元素在输出数组中的位置。

void countingSort(int arr[], int n) {int max_val = *max_element(arr, arr + n);int min_val = *min_element(arr, arr + n);int range = max_val - min_val + 1;vector<int> count(range), output(n);for (int i = 0; i < n; i++) count[arr[i] - min_val]++;for (int i = 1; i < range; i++) count[i] += count[i - 1];for (int i = n - 1; i >= 0; i--) {output[count[arr[i] - min_val] - 1] = arr[i];count[arr[i] - min_val]--;}for (int i = 0; i < n; i++) arr[i] = output[i];
}

9. 桶排序 (Bucket Sort)

基本思想:将数组分到有限数量的桶里,每个桶再分别排序(可以使用其他排序算法)。

void bucketSort(float arr[], int n) {vector<vector<float>> buckets(n);for (int i = 0; i < n; i++) {int bi = n * arr[i];buckets[bi].push_back(arr[i]);}for (int i = 0; i < n; i++) {sort(buckets[i].begin(), buckets[i].end());}int index = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < buckets[i].size(); j++) {arr[index++] = buckets[i][j];}}
}

10. 基数排序 (Radix Sort)

基本思想:按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。

void countingSortForRadix(int arr[], int n, int exp) {int output[n];int count[10] = {0};for (int i = 0; i < n; i++) count[(arr[i] / exp) % 10]++;for (int i = 1; i < 10; i++) count[i] += count[i - 1];for (int i = n - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}for (int i = 0; i < n; i++) arr[i] = output[i];
}void radixSort(int arr[], int n) {int max_val = *max_element(arr, arr + n);for (int exp = 1; max_val / exp > 0; exp *= 10) {countingSortForRadix(arr, n, exp);}
}

总结

1. 冒泡排序 (Bubble Sort)

优点

  • 实现简单,代码容易理解
  • 对于小规模数据效率尚可
  • 稳定排序(相同元素相对位置不变)

缺点

  • 效率低下,时间复杂度高
  • 不适用于大规模数据

复杂度

  • 时间复杂度:
    • 最好:O(n)(已排序情况)
    • 平均:O(n²)
    • 最坏:O(n²)
  • 空间复杂度:O(1)(原地排序)

2. 选择排序 (Selection Sort)

优点

  • 实现简单
  • 不占用额外内存空间
  • 交换次数少(最多n-1次交换)

缺点

  • 时间复杂度高
  • 不稳定排序
  • 对已排序数组仍需同样时间

复杂度

  • 时间复杂度:
    • 最好/平均/最坏:O(n²)
  • 空间复杂度:O(1)

3. 插入排序 (Insertion Sort)

优点

  • 对小规模或基本有序数据效率高
  • 稳定排序
  • 实现简单
  • 原地排序

缺点

  • 大规模乱序数据效率低
  • 最坏情况性能差

复杂度

  • 时间复杂度:
    • 最好:O(n)(已排序)
    • 平均:O(n²)
    • 最坏:O(n²)
  • 空间复杂度:O(1)
  1. 希尔排序 (Shell Sort)

优点

  • 插入排序的改进版,效率更高
  • 适用于中等规模数据
  • 原地排序

缺点

  • 复杂度分析复杂
  • 不稳定排序
  • 增量序列选择影响性能

复杂度

  • 时间复杂度:
    • 最好:O(n)
    • 平均:O(n^1.3)(取决于增量序列)
    • 最坏:O(n²)
  • 空间复杂度:O(1)
  1. 归并排序 (Merge Sort)

优点

  • 稳定排序
  • 时间复杂度稳定为O(nlogn)
  • 适合链表排序
  • 适合外部排序

缺点

  • 需要额外O(n)空间
  • 对小规模数据可能不如插入排序

复杂度

  • 时间复杂度:
    • 最好/平均/最坏:O(nlogn)
  • 空间复杂度:O(n)
  1. 快速排序 (Quick Sort)

优点

  • 平均情况下最快的排序算法
  • 原地排序(优化版本)
  • 缓存友好

缺点

  • 最坏情况O(n²)
  • 不稳定排序
  • 递归实现需要栈空间

复杂度

  • 时间复杂度:
    • 最好/平均:O(nlogn)
    • 最坏:O(n²)(已排序或所有元素相同)
  • 空间复杂度:
    • 平均:O(logn)(递归栈)
    • 最坏:O(n)
  1. 堆排序 (Heap Sort)

优点

  • 时间复杂度稳定
  • 原地排序
  • 适合获取前k个元素

缺点

  • 不稳定排序
  • 缓存不友好(跳跃访问)
  • 实际效率常不如快速排序

复杂度

  • 时间复杂度:
    • 最好/平均/最坏:O(nlogn)
  • 空间复杂度:O(1)
  1. 计数排序 (Counting Sort)

优点

  • 线性时间复杂度
  • 稳定排序(实现得当)

缺点

  • 仅适用于整数且范围不大的情况
  • 需要额外空间

复杂度

  • 时间复杂度:O(n+k)(k是数值范围)
  • 空间复杂度:O(n+k)
  1. 桶排序 (Bucket Sort)

优点

  • 当分布均匀时效率高
  • 稳定排序(实现得当)

缺点

  • 需要知道数据分布情况
  • 最坏情况退化为O(n²)
  • 需要额外空间

复杂度

  • 时间复杂度:
    • 最好:O(n)
    • 平均:O(n+k)(k是桶数量)
    • 最坏:O(n²)
  • 空间复杂度:O(n+k)
  1. 基数排序 (Radix Sort)

优点

  • 线性时间复杂度
  • 稳定排序(实现得当)

缺点

  • 仅适用于整数或特定格式数据
  • 需要额外空间
  • 常数因子较大

复杂度

  • 时间复杂度:O(d(n+k))(d是位数,k是基数)
  • 空间复杂度:O(n+k)
排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性适用场景
冒泡排序O(n²)O(n²)O(1)稳定小规模数据教学用途
选择排序O(n²)O(n²)O(1)不稳定交换成本高的情况
插入排序O(n²)O(n²)O(1)稳定小规模或基本有序数据
希尔排序O(n^1.3)O(n²)O(1)不稳定中等规模数据
归并排序O(nlogn)O(nlogn)O(n)稳定大规模数据、外部排序
快速排序O(nlogn)O(n²)O(logn)不稳定通用排序、大规模随机数据
堆排序O(nlogn)O(nlogn)O(1)不稳定需要稳定时间复杂度
计数排序O(n+k)O(n+k)O(n+k)稳定小范围整数
桶排序O(n+k)O(n²)O(n+k)稳定均匀分布的数据
基数排序O(d(n+k))O(d(n+k))O(n+k)稳定多位数整数或字符串

实际应用中,快速排序通常是最佳选择,但当需要稳定性或特定数据特性时,其他算法可能更合适。C++中的std::sort通常采用快速排序的优化版本(如内省排序,结合了快速排序、堆排序和插入排序的优点)。

排序链表

  • 🎈 题目链接:
  • 🎈 做题状态:

我的解题

使用了冒泡排序的思想,在排序链表时和排序数组完全是不一样的。因为链表的访问都是从前往后,不能随机访问。所以在实现的时候需要额外处理。

class Solution {
public:ListNode* sortList(ListNode* head) {// 我感觉这道题用插入排序还是比较难写出代码,相比冒泡排序思路代码就好写一点,因为每次都是比较相邻的节点// 边界情况if (head == nullptr || head->next == nullptr) return head;ListNode* tail = nullptr;while (head != tail){ListNode* left = head;ListNode* right = head->next;while(right != tail){if (left->val > right->val){swap(left->val, right->val);}left = left->next;right = right->next;}tail = left;    // 更新结束点位}return head;}
};

代码优化

最适合链表的排序是归并排序,这个时间复杂度还低一点

class Solution {
public:ListNode* sortList(ListNode* head) {return sortList(head, nullptr);}ListNode* sortList(ListNode* head, ListNode* tail) {if (head == nullptr) {return head;}if (head->next == tail) {head->next = nullptr;return head;}ListNode* slow = head, *fast = head;while (fast != tail) {slow = slow->next;fast = fast->next;if (fast != tail) {fast = fast->next;}}ListNode* mid = slow;return merge(sortList(head, mid), sortList(mid, tail));}ListNode* merge(ListNode* head1, ListNode* head2) {ListNode* dummyHead = new ListNode(0);ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;while (temp1 != nullptr && temp2 != nullptr) {if (temp1->val <= temp2->val) {temp->next = temp1;temp1 = temp1->next;} else {temp->next = temp2;temp2 = temp2->next;}temp = temp->next;}if (temp1 != nullptr) {temp->next = temp1;} else if (temp2 != nullptr) {temp->next = temp2;}return dummyHead->next;}
};作者:力扣官方题解
链接:https://leetcode.cn/problems/sort-list/solutions/492301/pai-xu-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

文章转载自:

http://sMbJ8XOM.yfnjk.cn
http://lCye7k9f.yfnjk.cn
http://PdfxeV9z.yfnjk.cn
http://17rWCtLH.yfnjk.cn
http://TPXuPTDP.yfnjk.cn
http://KkVyoiVf.yfnjk.cn
http://1dQE4IQh.yfnjk.cn
http://u1uqqmvv.yfnjk.cn
http://afxMKGjC.yfnjk.cn
http://7yyHS2RP.yfnjk.cn
http://KSnutOmn.yfnjk.cn
http://lr34pIri.yfnjk.cn
http://9dC8ofBt.yfnjk.cn
http://9ib7g3uC.yfnjk.cn
http://Vd3Pfh7G.yfnjk.cn
http://AUpWFZXF.yfnjk.cn
http://cEPBfRoc.yfnjk.cn
http://BrKYRVq6.yfnjk.cn
http://KeCP1BTt.yfnjk.cn
http://R3iSpl7H.yfnjk.cn
http://ObLpNdm9.yfnjk.cn
http://1DMQyyKi.yfnjk.cn
http://4heqzQPx.yfnjk.cn
http://e00r7CZa.yfnjk.cn
http://dKIBcIOl.yfnjk.cn
http://XbDPvQj2.yfnjk.cn
http://pJutvf8W.yfnjk.cn
http://8f3LBnAM.yfnjk.cn
http://NxkuL522.yfnjk.cn
http://hEOmEAKB.yfnjk.cn
http://www.dtcms.com/wzjs/747198.html

相关文章:

  • 网站建设与维护相关知识设计必知的设计网站 039
  • 做展厅的网站seo怎么做网站内容
  • 深圳模板建站多少钱艺术网站建设公司
  • 网站建设与管理专业电子上网站开发
  • wordpress 多个站点广东微信网站制作价格
  • 网站登录页面怎么做安化网站建设
  • 东莞哪些网络公司做网站比较好网站主色调简介
  • 网站 wap 插件个人网站免费推广
  • 左右左布局网站建设拉销智能模板建站系统
  • 站长收录查询网页制作模板素材免费
  • 重庆网站建设子沃科技熊掌号dw做的网站如何上传图片
  • 广州科 外贸网站建设亚马逊的免费网站
  • 南宁论坛建站模板宁夏建设工程造价信息网
  • 做网站虚拟主机推荐做论坛网站时应该注意什么
  • 哪里做网站优化品牌注册名字大全
  • 网站维护哪些wordpress登录跳转
  • 苏州网络网站建设怎么制作视频网站
  • 校园网站建设途径destoon 网站后台显示不出模板
  • 保山市城市建设网站dw怎么把设计网页显示出来
  • 饿了么网站做要多少钱德州做网站
  • 建设网站定位分析辽宁专业网站建设大全
  • 如何进入公司网站后台wordpress 单栏
  • 朋友圈网站广告怎么做小程序开发专业定制
  • 昆明建设银行纪念币预约网站今天新闻
  • 顺德网站开发招聘怀化seo公司
  • 像素人物制作网站wordpress音乐美化
  • 中山网站建设哪家便宜商品网站怎么做
  • 在线网站制作类似于建设通的网站
  • 大连 做网站商标注册查询官网网站
  • 做网站怎么推广收益大软文范文200字