日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【编程4】插入排序+快速排序+LeetCode.148(排序链表)

發(fā)布時間:2025/3/19 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【编程4】插入排序+快速排序+LeetCode.148(排序链表) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 一、排序鏈表
      • 1、題目描述——LeetCode.148
      • 2、分析
        • (1)一般的快排
        • (2)解題思路
      • 3、實現(xiàn)
    • 二、排序算法
    • 三、插入排序
      • 1、基本思想
        • (1)過程概述
        • (2)具體算法描述:
      • 2、示例
      • 3、實現(xiàn)
      • 4、分析
        • (1)原地排序算法
        • (2)穩(wěn)定排序算法
        • (3)時間復(fù)雜度
    • 四、快速排序
      • 1、基本思想
        • (1)快速排序的流程
      • 2、實現(xiàn)
      • 3、性能分析

一、排序鏈表

1、題目描述——LeetCode.148

在 O(n logn) 時間復(fù)雜度和常數(shù)級空間復(fù)雜度下,對鏈表進(jìn)行排序。

示例 1:

輸入: 4->2->1->3
輸出: 1->2->3->4

示例 2:

輸入: -1->5->3->4->0
輸出: -1->0->3->4->5

2、分析

本實現(xiàn)采用快速排序算法實現(xiàn)

(1)一般的快排

需要一個指針指向頭,一個指針指向尾,然后兩個指針相向運動并按一定規(guī)律交換值,最后找到一個支點使得支點左邊小于支點,支點右邊大于支點
==》如果是這樣的話,對于單鏈表我們沒有前驅(qū)指針,怎么能使得后面的那個指針往前移動呢?
==》使兩個指針都往next方向移動并且能找到支點那就好了。

(2)解題思路

只需要兩個指針p和q,這兩個指針均往next方向移動,移動的過程中保持p之前的key都小于選定的key,p和q之間的key都大于選定的key,那么當(dāng)q走到末尾的時候便完成了一次支點的尋找。

3、實現(xiàn)

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* sortList(ListNode* head) {if(head == NULL)return NULL;ListNode *right = head;while(right->next)right = right->next;QuickSort(head, right);return head;} private:void QuickSort(ListNode *left, ListNode *right){if(left != right){ListNode *partion = GetPartion(left, right);QuickSort(left, partion);if(partion->next)QuickSort(partion->next, right);}}ListNode *GetPartion(ListNode *left, ListNode *right){int key = left->val;ListNode *p = left;ListNode *q = p->next;while(q != right->next){if(q->val < key){p = p->next;swap(p->val, q->val);}q = q->next;}swap(p->val, left->val);return p;} };

二、排序算法

排序方法時間復(fù)雜度是否基于比較適用性
1冒泡、插入、選擇O(n2)適合小規(guī)模數(shù)據(jù)排序
2快排、歸并O(nlogn)適合大規(guī)模的數(shù)據(jù)排序
3桶、計數(shù)、基數(shù)O(n)×

三、插入排序

1、基本思想

將一個記錄插入到已經(jīng)排好序的有序表中,從而得到一個新的、記錄數(shù)增1的有序表。

(1)過程概述

插入排序在實現(xiàn)上,通常采用in-place排序(即只需用到O(1)的額外空間的排序),因而在從后向前掃描過程中,需要反復(fù)把已排序元素逐步向后挪位,為最新元素提供插入空間。

(2)具體算法描述:

① 從第一個元素開始,該元素可以認(rèn)為已經(jīng)被排序;
② 取出下一個元素,在已經(jīng)排序的元素序列中從后向前掃描;
③ 如果該元素(已排序)大于新元素,將該元素移到下一位置;
④ 重復(fù)步驟 ③,直到找到已排序的元素小于或者等于新元素的位置;
⑤ 將新元素插入到該位置后
⑥ 重復(fù)步驟②~⑤

2、示例

原數(shù)據(jù):{4,5,6,1,3,2}
排序過程:其中左側(cè)是已排序區(qū)間,右側(cè)是未排序區(qū)間。

3、實現(xiàn)

void insertSort(int a[], int len){int tmp, j;for(int i = 1; i < len; i++){tmp = a[i];int j = i - 1;while(tmp < a[j]){a[j + 1] = a[j];j--;}a[j + 1] = tmp;} }

4、分析

(1)原地排序算法

  • 空間復(fù)雜度為 O(1)
    ==》原地排序算法

(2)穩(wěn)定排序算法

  • 對于值相同的元素,可以選擇將后面出現(xiàn)的元素,插入到前面出現(xiàn)元素的后面。
    ==》保持原有前后順序,也就是穩(wěn)定的排序算法

(3)時間復(fù)雜度

  • 最好情況時間復(fù)雜度(數(shù)據(jù)已經(jīng)有序):O(n)
  • 最壞情況時間復(fù)雜度:O(n2)
  • 平均時間復(fù)雜度:O(n2)
    • 對于插入排序來說,每次插入操作(時間復(fù)雜度為O(n))都相當(dāng)于在數(shù)組中插入一個數(shù)據(jù),循環(huán)執(zhí)行 n 次插入操作

四、快速排序

1、基本思想

基于分治思想,快速排序算法:選擇一個基準(zhǔn)數(shù),通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨立的兩部分;其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小。然后,再按此方法對這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個排序過程可以遞歸進(jìn)行,以此達(dá)到整個數(shù)據(jù)變成有序序列。

(1)快速排序的流程

① 從數(shù)列中挑出一個基準(zhǔn)值(樞軸,pivot)。
② 將數(shù)組進(jìn)行劃分(partition),將比基準(zhǔn)數(shù)大的元素都移至樞軸右邊,將小于等于基準(zhǔn)數(shù)的元素都移至樞軸左邊。在這個分區(qū)退出之后,該基準(zhǔn)就處于數(shù)列的中間位置。
③ 遞歸地把"基準(zhǔn)值前面的子數(shù)列"和"基準(zhǔn)值后面的子數(shù)列"進(jìn)行排序。

2、實現(xiàn)

  • 實現(xiàn)一
    將第一個元素設(shè)置為基準(zhǔn)值來劃分區(qū)間,基準(zhǔn)值的位置始終不變,最后交換使得基準(zhǔn)值的位置。
// left、right分別表示要交換數(shù)組的第一個元素和最后一個元素的位置 int partition(int arr[], int left, int right) {int i = left + 1;int j = right;// 將第一個元素設(shè)置為 基準(zhǔn)值int temp = arr[left];while(i <= j){while(arr[i] < temp)i++;while(arr[j] > temp)j--;if(i < j)swap(arr[i++], arr[j--]);elsei++;}swap(arr[j], arr[left]);return j; } void quick_sort(int arr[], int left, int right) {if(left > right)return;int j = partition(arr, left, right);quick_sort(arr, left, j - 1);quick_sort(arr, j + 1, right); }
  • 實現(xiàn)二
    將第一個元素設(shè)置為基準(zhǔn)值來劃分區(qū)間,將基準(zhǔn)值不斷與沖突值進(jìn)行換位。
void QuickSort(int arr[], int left, int right) {int i = left;int j = right;int temp = arr[i];if(i < j){while(i < j){while(i < j && arr[j] >= temp)j--;if(i < j){arr[i] = arr[j];i++;}while(i < j && arr[i] < temp)i++;if(i < j){arr[j] = arr[i];j--;}}// 將基準(zhǔn)數(shù)放在 i 位置arr[i] = temp;// 遞歸實現(xiàn)QuickSort(arr, left, i - 1);QuickSort(arr, i + 1, right);} }

3、性能分析

  • 不穩(wěn)定
  • 原地排序——空間復(fù)雜度為O(1)
  • 時間復(fù)雜度:大部分情況下的時間復(fù)雜度都可以做到 O(nlogn),只有在極端情況下,才會退化到 O(n2)。

總結(jié)

以上是生活随笔為你收集整理的【编程4】插入排序+快速排序+LeetCode.148(排序链表)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。