算法導論14.1節習題解答


算法導論習題解答系列停了一年了,現在重新拾起,好多算法已經忘了,有的記得大概,但是真正的用代碼實現卻很難下手。

CLRS 14.1-3 寫出OS-SELECT的非遞歸形式
一般遞歸形式改寫為非遞歸形式要用到while,有時還要用到棧結構。

OS-SELECT(x, i)
{
  r = size[left[x]] + 1;
  while (r != i)
  {
    if (i < r)
    {
      x = left[x];
      r = size[left[x]] + 1;
    }
    else
    {
      x = right[x];
      i = i -r;
      r = size[left[x]] + 1;
    }
  }
  return x;
}

 

CLRS 14.1-4 寫出一個遞歸過程OS-KEY-RANK(T, k)

int OS-KEY-RANK(T, k)
{
  if (k == key[root[T]])
    return size[left[root[T]]] + 1;
  else if (k < key[root[T]])
    return OS-KEY-RANK(left[root[T]], k);
  else
    return OS-KEY-RANK(right[root[T]], k) + size[left[root[T]]] + 1;
}

 

CLRS 14.1-5 確定元素x的第i個后繼,時間為lg(n)

GET-SUCCESSOR(T, x, i)
{
  r = OS-RANK(T, x);
    return OS-SELECT(root[T], r + i);
}

 

CLRS 14.1-6
在這題中,將每個結點的秩存於該結點自身之中,這個秩是相對於以該結點為根的子樹而言的。
因而在插入結點x時,對於從root到x結點的路經上的所有結點y,如果插入路經經過y的左支,則rank[y]的值加1,若經過其右支,則rank[y]的值不變。
在刪除結點x時,對於從root到x結點的路經上的所有結點y,如果刪除路經經過y的左支,則rank[y]的值減1,若經過其右支,則rank[y]的值不變。

如圖,在進行右旋轉時,x的秩是不變的,node的秩變為rank[node]減去原來的rank[x]。左旋同理。

 

CLRS 14.1-7 利用順序統計樹在O(nlgn)的時間內統計逆序對
在習題2-4中,其要求用歸並排序來計算逆序對,見算法導論2-4習題解答(合並排序算法)
在這里,我們對於數組{2,3,8,6,1}這樣分析,對於每個數,選取其前面的數與其比較,
對於6,與其對比的為2,3,8,逆序對有1對,記作inversion_count,
6在原數組的索引為3,記作j,
然后我們來分析子數組{2,3,8,6},6在其中的排名為3,記作rank_j;
再通過分析其他數,我們歸納如下:
inversion_count = j + 1 - rank_j
當把每個結點插入順序統計樹時,我們可以知道j的值,同時調用OS-RANK來得到rank_j,從而得到inversion_count,在這里,每插入一次,就計算一次。
由於插入和OS-RANK都是lg(n),故n個結點即為n*lg(n)。

CLRS 14.1-8 現有一個圓上的n條弦,每條弦都按其端點來定義,請給出一個能在O(n*lgn)時間內確定圓內相交弦的對數的算法,假設任意兩條弦都不會共享端點。

如圖,對於兩條弦P1Q1和P3Q3來說,圓心與端點形成的向量有一個角度A
如果A(P1)<A(P3)<A(Q1)<A(Q3)或者A(P3)<A(P1)<A(Q3)<A(Q1),這樣角度區間“交叉”就意味着兩條弦有交叉。
 

由於有n條弦,故有2n個端點,每個端點的取值范圍為[0, 2*π),對這2n個端點按角度值進行從小到大排序,排序的時間復雜度為O(n*lgn),所得數組為A[1...2n]
然后建立一個順序統計樹,起先為空,先插入A[1],它為一條弦的起始端點,然后遇到其他弦的起始端點就插入,當遇到一條弦的終端點時,就統計在該樹中大於該弦的起始端點角度值的端點個數,之后就從樹中刪除該弦的兩個端點。
如圖,先插入P1,再插入P2,再插入P3,再插入P4,再插入Q4,Q4為弦P4Q4的終端店,故停止插入,開始統計樹中大於P4角度值的端點個數,為0,然后刪除P4與Q4。
再插入Q2,為終端點,統計此時樹中大於P2端點值的個數,為1個,然后刪除P2與Q2。
再插入Q1,為終端點,統計此時樹中大於P1端點值的個數,為1個,然后刪除P1與Q1。
再插入Q3,為終端點,統計此時樹中大於P3端點值的個數,為0個,然后刪除P3與Q3。
結束,統計結果一共為2,與圖中相符。
在這里,要用到順序統計樹的插入、刪除操作,以及OS-RANK函數。每個操作都為O(lgn)的時間復雜度,有2n個結點,故時間復雜度仍是O(n*lgn)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM