第二章 算法基礎(chǔ)

這一章介紹貫穿全書(shū)的框架,即設(shè)計(jì)算法的大致方法過(guò)程。以插入排序和歸并排序?yàn)槔榻B描述算法的方法——偽代碼,證明正確性并分析運(yùn)行時(shí)間——循環(huán)不變量和效率分析,最后引入分治法。

2.1 插入排序

偽代碼:用最清晰、最簡(jiǎn)潔的表示方法說(shuō)明算法,主要是理順?biāo)悸贰?br> 插入排序:在一個(gè)有序數(shù)據(jù)序列中插入新的數(shù)。思路是從前到后比較查找新數(shù)的正確位置,將此位置以后的數(shù)整體后移一位,插入此數(shù)。
插入排序偽代碼:

插入排序

C++實(shí)現(xiàn):第一個(gè)參數(shù)為待排序數(shù)組,第二個(gè)為該數(shù)組長(zhǎng)度,下標(biāo)1~ n存數(shù)共n個(gè) 。

void InsertSort(int *a, int n)
{
    int i, j, t;
    for (j = 2; j < 10; j++ )
    {
        t = a[j];
        i = j - 1;
        while(i > 0 && a[i] > t)
        {
            a[i + 1] = a[i];
            i --;
        }
        a[i + 1] = t;
    }
}

循環(huán)不變式證明正確性

對(duì)于循環(huán)不變式必須證明三條性質(zhì):

循環(huán)不變式

前兩步類似于數(shù)學(xué)歸納法的基本情況和歸納步,像多米諾骨牌一樣。第三條通常是和導(dǎo)致循環(huán)條件終止的條件一起使用循環(huán)不變式。與數(shù)學(xué)歸納法不同,循環(huán)終止時(shí)停止歸納。

舉例說(shuō)明:黑色框代表當(dāng)前插入數(shù)字,即下標(biāo) j 所指。A[1···j - 1]為已排好序,A[j + 1···n]為待插入數(shù),即桌上牌堆。下圖顯示排序過(guò)程

image.png

此時(shí)循環(huán)不變式就是A[1···j - 1]子數(shù)組有序
初始化:第一次循環(huán)迭代之前(j = 2),此時(shí)A[1···j - 1]子數(shù)組為A [1],循環(huán)不變式成立。
保持:偽代碼4~7行將A[j - 1]、A[j - 2]等向右移動(dòng)一個(gè)位置直到A[j] 的適當(dāng)位置。此時(shí)子數(shù)組A[1··j]元素只是插入一個(gè)數(shù),相對(duì)位置不變,下一次迭代保持循環(huán)不變式。
終止:終止時(shí)j = n + 1,將循環(huán)不變式中j 用n + 1帶入有A[1···n]有序。

練習(xí)

2.1-1
2.1-2
INSERTION-SORT(A)
    for j = 2 to A.length
        key = A[j]
            //Insert A[j] into the sorted sequence A[1..j-1].
        i = j - 1
        while i > 0 and A[i] < key // > 改 <
            A[i+1] = A[i]
            i = i - 1
        A[i+1] = key
2.1-3

偽代碼:

SEARCH(A, v):
  for i = 1 to A.length
      if A[i] == v
          return i
  return NIL

循環(huán)不變式為找過(guò)的子數(shù)組無(wú)v。

2.1-4

偽代碼:

ADD-BINARY(A, B):
  C = new integer[A.length + 1]
  carry = 0
  for i = 1 to A.length
      C[i] = (A[i] + B[i] + carry) % 2  // remainder
      carry = (A[i] + B[i] + carry) / 2 // quotient
  C[i] = carry

  return C



2.2 分析算法

插入排序算法的分析

一般來(lái)說(shuō)算法需要的時(shí)間與輸入的規(guī)模同步增長(zhǎng)。輸入規(guī)模根據(jù)不同問(wèn)題,有時(shí)指輸入中的項(xiàng)數(shù),有時(shí)是用二進(jìn)制表示輸入時(shí)用的總位數(shù),有時(shí)是圖的邊和點(diǎn)數(shù)。算法在特定輸入上的運(yùn)行時(shí)間指執(zhí)行的基本操作數(shù)或步數(shù)。插入排序每步執(zhí)行次數(shù)為:


所有項(xiàng)加起來(lái)得到總時(shí)間。但是真正關(guān)注的是運(yùn)行時(shí)間關(guān)于輸入的增長(zhǎng)量級(jí),所以只考慮公式中最重要的項(xiàng),增長(zhǎng)量級(jí)低的算法更好。

練習(xí)

2.2-1
2.2-2

偽代碼:

SELECTION-SORT(A):
  for i = 1 to A.length - 1
      min = i
      for j = i + 1 to A.length
          if A[j] < A[min]
              min = j
      temp = A[i]
      A[i] = A[min]
      A[min] = temp

C++實(shí)現(xiàn):

void SelectSort(int *a, int n)
{
    int i, j, min, t;
    for ( i = 1;i < n; i ++)
        {
            min = i;
            for (j = i + 1; j<= n; j ++)
            {
                if (a[j] < a[min])
                    k = j;
            }
            if (min != i)
            {
                t = a[min];
                a[min] = a[i];
                a[i] = t;
            }
        }
}

循環(huán)不變量是子數(shù)組A[1..i - 1]是原數(shù)組前i-1個(gè)最小數(shù)的有序排列。或者當(dāng)前位置 i 是子數(shù)組A[i..n]的最小數(shù)的最終位置。分析初始化、保持、終止可知正確。因?yàn)閚 - 1個(gè)最小數(shù)排到正確位置后第 n 個(gè)自然是最大數(shù),排最后一個(gè)。最好最壞都是Θ(n^2)

2.2-3

答:平均n/2,最壞n。運(yùn)行時(shí)間都是Θ(n)。因?yàn)榈瓤赡埽總€(gè)數(shù)的概率為1/n,平均查找個(gè)數(shù)為 1/n * (1 + 2 + ... +n) = (n+1)/2,Θ(n)。最壞找到最后一個(gè)或者沒(méi)找到,比較 n 個(gè),Θ(n)。

2.2-4

答:首先檢查輸入數(shù)據(jù)看是否滿足某些可以直接輸出的特定條件,可以輸出事先計(jì)算好的結(jié)果。如:排序數(shù)組本來(lái)有序則直接輸出。




2.3 設(shè)計(jì)算法

算法設(shè)計(jì)技術(shù)有很多,插入排序使用了增量法,還有很多結(jié)構(gòu)遞歸:算法一次或多次遞歸地調(diào)用其自身以解決緊密相關(guān)的若干子問(wèn)題

分治法

思想:將原問(wèn)題分解為幾個(gè)規(guī)模較小但類似于原問(wèn)題的子問(wèn)題,遞歸地求解這些子問(wèn)題,然后在合并這些子問(wèn)題的解來(lái)建立原問(wèn)題的解。分治模式在遞歸時(shí)有三個(gè)步驟:

  1. 分解原問(wèn)題為若干子問(wèn)題,這些子問(wèn)題是原問(wèn)題的規(guī)模較小的實(shí)例。
  2. 解決這些子問(wèn)題,遞歸地求解各子問(wèn)題。若子問(wèn)題規(guī)模足夠小則直接求解。
  3. 合并這些子問(wèn)題的解成原問(wèn)題的解。

以歸并排序?yàn)槔?/p>


關(guān)鍵是合并操作,調(diào)用MERGE(A, p, q, r),假設(shè)A[p···q]與A[q + 1 ···r]都已有序,合并成一個(gè)有序數(shù)組A[p···r]。思路是:每次將兩子數(shù)組當(dāng)前元素比較,較小的加入總數(shù)組并后移該子數(shù)組指針一位。復(fù)雜度Θ(n)。偽代碼:

n = r - p + 1為待合并元素個(gè)數(shù),為避免檢查堆是否為空加哨兵牌無(wú)窮大。排序過(guò)程:

循環(huán)不變式:
按初始化、保持、終止的步驟分析算法正確性。歸并排序偽代碼:
若p>=r則子數(shù)組最多一個(gè)元素已排好,作基底情況返回。否則分兩半遞歸排序最后合并。合并過(guò)程:

C++實(shí)現(xiàn):

void Merge(int *a ,int p, int q, int r)
{
    int i, j, k;
    int n1 = q - p + 1;
    int n2 = r - q;

    int L[n1];
    int R[n2];

    for (i = 0; i < n1; i++)
        L[i] = a[p + i];
    for (j = 0; j < n2; j++)
        R[j] = a[q + j + 1];

    for(i = 0, j = 0, k = p; k <= r; k++)
    {
        if (i == n1)
            a[k] = R[j++];
        else if (j == n2)
            a[k] = L[i++];
        else if (L[i] <= R[j])
            a[k] = L[i++];
        else
            a[k] = R[j++];
    }
}
void MergeSort(int *a, int p, int r)
{
    if (p < r)
    {
        int q = (p + r) / 2;
        MergeSort(a, p, q);
        MergeSort(a, q + 1, r);
        Merge(a, p, q, r);
    }
}

分析分治算法

算法包含遞歸調(diào)用時(shí)可用遞歸式描述運(yùn)行時(shí)間。設(shè)T(n)為一個(gè)規(guī)模為n的問(wèn)題的運(yùn)行時(shí)間。如果問(wèn)題的規(guī)模足夠小,如n≤c(c為常量),則得到它的直接解的時(shí)間為常量,寫(xiě)作?(1)。假設(shè)我們把原問(wèn)題分解成a個(gè)子問(wèn)題,每一個(gè)的大小是原問(wèn)題的1/b。如果分解該問(wèn)題和合并解的時(shí)間各為D(n)和C(n),則得到遞歸式:

歸并排序算法的分析

  • 分解:這一步僅僅是計(jì)算出子數(shù)組的中間位置,需要常量時(shí)間,因而D(n)= ?(1)
  • 解決:遞歸地解兩個(gè)規(guī)模為n/2的子問(wèn)題,時(shí)間為2T(n/2)
  • 合并:在一個(gè)含有n個(gè)元素的子數(shù)組上,MERGE過(guò)程的運(yùn)行時(shí)間為?(n),則C(n) = ? (n)

    遞歸式為:
    構(gòu)建遞歸樹(shù):

    n為葉子數(shù),把各層加起來(lái)得到?(nlgn)。

練習(xí)

2.3-1
2.3-2
MERGE(A, p, q, r)
  n1 = q - p + 1
  n2 = r - q
  let L[1..n?] and R[1..n?] be new arrays
  for i = 1 to n?
      L[i] = A[p + i - 1]
  for j = 1 to n?
      R[j] = A[q + j]
  i = 1
  j = 1
  for k = p to r
      if i > n?
          A[k] = R[j]
          j = j + 1
      else if j > n?
          A[k] = L[i]
          i = i + 1
      else if L[i] ≤ R[j]
          A[k] = L[i]
          i = i + 1
      else
          A[k] = R[j]
          j = j + 1

區(qū)別主要在for循環(huán)中加了if判斷,如果其中一個(gè)子數(shù)組已經(jīng)遍歷完則加入另一數(shù)組元素。

2.3-3
  • k = 1即n = 2時(shí) T(2) = 2成立
  • 假設(shè)n = 2^k時(shí)成立,n = 2^(k+1)時(shí):
    T(2^ (k + 1))= 2 * T(2^k) + 2^ (k + 1) = 2 * k * 2^k + 2^ (k + 1) = (k + 1)*2^ (k + 1) = nlgn
2.3-4
2.3-5

偽代碼:

BINARY-SEARCH(A, v):
  low = 1
  high = A.length

  while low <= high
      mid = (low + high) / 2
      if A[mid] == v
          return mid
      if A[mid] < v
          low = mid + 1
      else
          high = mid - 1

  return NIL

C++實(shí)現(xiàn):

int BinarySearch(int *a, int length, int v)
{
    int low  = 0;
    int high = length;

    int mid;
    while (low < high)
    {
        mid = (low + high) / 2;

        if (a[mid] == v)
            return mid;
        if (a[mid] < v)
            low = mid + 1;
        else
            high = mid;
    }
    return -1;
}

T(n) = T(n/2) + c, 故為Θ(lg n)。

2.3-6

答:不行,因?yàn)椴坏檎疫€要移動(dòng)元素。偽代碼:

INSERTION-SORT(A)
    for j = 2 to A.length
        key = A[j]
        i = BinarySearch(A[1..j-1], key)  // C1 = ∑lgj {j=2 to n}
        for k = j to i+1        //C2 = ∑(j/2) {j=2 to n}
            A[k] = A[k-1]
        A[i] = k
2.3-7

答:

  1. 將S排序,遍歷元素 i (< x),二分查找(x - i)。運(yùn)行時(shí)間 = 排序Θ(nlgn) + 遍歷Θ(n)*二分查找(lgn) = Θ(nlgn)。偽代碼:
PAIR-EXISTS(S, x):
  A = MERGE-SORT(S)
  for i = 1 to S.length
      if BINARY-SEARCH(A, x - S[i]) != NIL
          return true

  return false
  1. 將S排序,設(shè)兩指針指向頭尾向中間掃描。
  2. 哈希達(dá)到Θ(n)。同LeetCode Two Sum,Python代碼:
def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        buff_dict = {}
        for i in range(len(nums)):
            if nums[i] in buff_dict:
                return [buff_dict[nums[i]], i]
            else:
                buff_dict[target - nums[i]] = i

思考題

2-1

答:
a. 長(zhǎng)度為k的子表插入排序最壞為Θ(k^2),一共n/k個(gè),所以總運(yùn)行時(shí)間 = n/k * Θ(k^2) = Θ(nk)。
b. 根據(jù)歸并排序的第歸屬分析可知:總代價(jià) = 樹(shù)高 * 每層代價(jià),而每層代價(jià)常數(shù)倍的結(jié)點(diǎn)數(shù)。題干中 n/k 為最底層即葉子個(gè)數(shù),每次合并減少一半,故樹(shù)高為 lg(n/k) ,每層 n 個(gè)元素,所以復(fù)雜度為 n * lg(n/k) = Θ(nlg(n/k))。
c. k = Θ(lgn)。此時(shí) Θ(nk + nlg(n/k)) = Θ(nlgn + nlg(n/lgn)) = Θ(nlgn)。
d. 根據(jù)練習(xí)1.2-2可知 n>43 mergesort 好于 insertion sort,故取 k>43 且 k + lg(n/k) < lgn的值,因?yàn)榉值锰?xì)增加樹(shù)高。

2-2

答:
a. 還要證明數(shù)組A中的元素還是原來(lái)的那些。
b. 循環(huán)不變式為A[j]為A[j...n]中最小的

  • 初始化:剛開(kāi)始只有A[n]故滿足最小。
  • 保持:每次循環(huán)若A[j] < A[j-1]則交換,故成立。
  • 終止:j = i 時(shí)迭代結(jié)束,此時(shí)A[i]是子數(shù)組A[i..n]的最小元素。

c. 位置 i 為原數(shù)組第 i 小的數(shù)。

  • 初始化:數(shù)組為空,滿足。
  • 保持:每次一輪內(nèi)循環(huán)都滿足 b 中的終止條件,即A[i]是子數(shù)組A[i..n]的最小元素。
  • 終止:i = n 時(shí)迭代結(jié)束,此時(shí)A[n]是最后一個(gè)最小數(shù)。
    d. Θ(n^2),同一個(gè)數(shù)量級(jí)但由于有交換操作,通常冒泡更慢。
2-3

答:
a. Θ(n)
b. 偽代碼:

y = 0
for i = 0 to n
    m = 1
    for k = 1 to i
        m = m·x
    y = y + a?·m

復(fù)雜度Θ(n^2),更慢。
c.

  • 初始時(shí): 沒(méi)有項(xiàng),y = 0。

  • 保持:第 i 次迭代結(jié)束時(shí):
  • 終止:此時(shí) i = -1,帶入則為該和式。
    d. 根據(jù)前三小問(wèn)得出答案。

2-4

答:
a. ?2,1?, ?3,1?, ?8,6?, ?8,1?,?6,1?.
b. ?n,n-1,n-2,...,3,2,1?最多,共(n-1) + (n-2) + …… + 3 + 2 + 1 = n(n-1)/2。
c. 插入排序中移動(dòng)元素的次數(shù)就是逆序數(shù)的對(duì)數(shù)。分析例子可知每次對(duì)一個(gè)小數(shù)插入時(shí),前面每個(gè)比它大的數(shù)都要后移,個(gè)數(shù)恰好是該元素的逆序?qū)?shù)。
d. 歸并排序merge操作時(shí)每次插入后半邊子數(shù)組時(shí),前半邊還未插入的元素個(gè)數(shù),就是逆序?qū)?shù)。
偽代碼:

MERGE-SORT(A, p, r):
  if p < r
      inversions = 0
      q = (p + r) / 2
      // 逆序?qū)?shù)量 = 左分支產(chǎn)生的數(shù)量 + 右分支產(chǎn)生的數(shù)量 + 歸并中產(chǎn)生的數(shù)量
      inversions += merge_sort(A, p, q)
      inversions += merge_sort(A, q + 1, r)
      inversions += merge(A, p, q, r)
      return inversions
  else
      return 0

MERGE(A, p, q, r)
  n1 = q - p + 1 //前半部元素個(gè)數(shù)
  n2 = r - q     //后半部元素個(gè)數(shù)
  let L[1..n?] and R[1..n?] be new arrays
  for i = 1 to n?
      L[i] = A[p + i - 1]
  for j = 1 to n?
      R[j] = A[q + j]
  i = 1
  j = 1
  for k = p to r
      if i > n?      //前半部完成
          A[k] = R[j]
          j = j + 1
      else if j > n?
          A[k] = L[i]
          i = i + 1
      else if L[i] ≤ R[j]
          A[k] = L[i]
          i = i + 1
      else            //后半部有更小元素
          A[k] = R[j]
          j = j + 1
          inversions += n? - i
  return inversions

C++實(shí)現(xiàn):

void Merge(int *a ,int p, int q, int r)
{
    int i, j, k, inversions = 0;
    int n1 = q - p + 1;
    int n2 = r - q;

    int L[n1];
    int R[n2];

    for (i = 0; i < n1; i++)
        L[i] = a[p + i];
    for (j = 0; j < n2; j++)
        R[j] = a[q + j + 1];

    for(i = 0, j = 0, k = p; k <= r; k++)
    {
        if (i == n1)
            a[k] = R[j++];
        else if (j == n2)
            a[k] = L[i++];
        else if (L[i] <= R[j])
            a[k] = L[i++];
        else
        {
            a[k] = R[j++];
            inversions += n1 - i;
        }
    }
    return inversions;
}
void MergeSort(int *a, int p, int r)
{
    if (p < r)
    {
        int inversions = 0;
        int q = (p + r) / 2;
        inversions += MergeSort(a, p, q);
        inversions += MergeSort(a, q + 1, r);
        inversions += Merge(a, p, q, r);
        return inversions;
    }
    return 0;
}
參考:算法導(dǎo)論題解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,169評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,722評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,465評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,823評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,000評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,513評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,722評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,125評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,430評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,237評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,482評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容

  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,211評(píng)論 0 52
  • 概述:排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,740評(píng)論 0 15
  • 查看作者原文 vim是個(gè)很好的編輯器,遠(yuǎn)古神器嘛,當(dāng)你熟悉了這個(gè)編輯器你的逼格是不是瞬間就會(huì)高了許多首先安裝vim...
    秋風(fēng)喵閱讀 365評(píng)論 0 5
  • ?R閱讀原文片段 《高效能人士的七個(gè)習(xí)慣》 積極主動(dòng)不僅指行事的態(tài)度,還意味著人一定要對(duì)自己的人生負(fù)責(zé)。個(gè)人行為取...
    隱士_1b52閱讀 193評(píng)論 0 0
  • 人都是懷舊的,十七歲那年的風(fēng),那年走過(guò)的路,那年在教室與餐廳路上奔波的日子,那年午飯?jiān)谝黄鸫颠^(guò)的牛逼,那年為了學(xué)習(xí)...
    下里巴人vs斌閱讀 221評(píng)論 0 0