1. 程式人生 > >0x05演算法設計與分析複習(二):演算法設計策略-分治法2

0x05演算法設計與分析複習(二):演算法設計策略-分治法2

參考書籍:演算法設計與分析——C++語言描述(第二版)

演算法設計策略-分治法

二分搜尋

問題描述

在有序表(已按關鍵字值非減排序)中搜索給定元素的問題。

分治法求解

設有一個長度為n的有序表(a0,a1,,an1),要求在表中搜索與給定元素x有相同關鍵字值的元素。若n=0,則顯然搜尋失敗;若n>0,則可將有序表分解成若干個子表。最簡單的做法是分成兩個子表。假定以元素am為劃分點,將原表分成(a0,a1,,am1)(am+1,am+2,,an1)兩個子表。那麼將元素am與給定元素x進行比較,比較結果有三種可能:x<amx=amx>

am。對於這三種情況,有:

  • x<am時,若與x相同關鍵字值的元素在表中,則必定在子表(a0,a1,,am1)中,可以在該子表中繼續進行搜尋;
  • x=am時,搜尋成功;
  • x>am時,若與x相同關鍵字值的元素在表中,則必定在子表(am+1,am+2,,an1)中,可以在該子表中繼續進行搜尋。

根據以上分析,可以得到分治法搜尋有序表的演算法——二分搜尋

//二分搜尋演算法框架
//後置條件: 在範圍為[left,right]的表中搜索與x有相同關鍵字值的元素;如果存在該元素,則函式返回該元素在表中的位置,否則函式返回-1,表示搜尋失敗。
template <class
T> int SortableList<T>::BSearch(const T& x, int left, int right)const { if(left <= right){ //按照某種規則求分割點m int m = Divide(left, right); //使用不同的規則求分割點m,則可得到不同的二分搜尋方法,如:對半搜尋、斐波那契搜尋等。 if(x<l[m]) return BSearch(x,left,m-1); else if(x>l[m]) return
Bsearch(x,m+1,right); else //搜尋成功 return m; } //搜尋失敗 return -1; }

對半搜尋

對半搜尋是一種二分搜尋,它的分割點設為m=(left+right)/2

//對半搜尋遞迴演算法
template<class T>
  int SortableList<T>:BSearch(const T& x, int left, int right)const
  {
    //若表(子表)非空
    if(left <= right){
      //對半分割
      int m = (left+right)/2;
      if(x<l[m])
        //搜尋左半子表
        return BSearch(x,left,m-1);
      else if(x>l[m])
        //搜尋右半子表
        return BSearch(x,m+1,right);
      else 
        //搜尋成功
        return m;
    }
    else 
      //搜尋失敗
      return -1;
  }

對半搜尋的正確性用歸納法可以證明。

//對半搜尋的迭代演算法
template<class T>
  int SortableList<T>::BSearch(T& x)const
  {
    int m, left = 0, right = n-1;
    while(left<=right){
      m=(left+right)/2;
      if(x<l[m])
        right = m-1;
      else if(x>l[m])
        left = m+1;
      else
        //搜尋成功
        return m;
    }
    //搜尋失敗
    return -1;
  }

C語言實驗如下:

#include <stdio.h>
//對半搜尋遞迴演算法
int BSearch1(int l[], int x, int left, int right)
{
  //若表(子表)非空
  if(left<=right){
      //對半分割
      int m = (left+right)/2;
      if(x<l[m])
        return BSearch1(l, x, left, m);
      else if(x>l[m])
        return BSearch1(l, x, m+1, right);
      else
        return m;
    }
  else
    return -1;
}

//對半搜尋的迭代演算法
int BSearch2(int l[], int x, int n)
{
  int m, left = 0, right = n-1;
  while(left<=right){
      m = (left+right)/2;
      if(x<l[m]){
          right = m-1;
        }
      else if(x>l[m]){
          left = m+1;
        }
      else
        return m;
    }
  return -1;
}

int main()
{
  int l[5] = {1,2,3,4,5};
  printf("number 5's position is %d\n", BSearch1(l, 5, 0, 4));
  printf("number 3's position is %d\n", BSearch2(l, 3, 5));
  return 0;
}

實驗結果:

number 5's position is 4
number 3's position is 2

二叉判定樹

二分搜尋過程的演算法行為可以用一顆二叉樹來描述,通常稱這顆描述搜尋演算法執行過程的二叉樹為二叉判定樹(binary decision tree).

一個以關鍵字值為基礎的搜尋演算法的二叉判定樹模型的建立過程:

  1. 指定元素x與表中元素l[m]之間的一次比較操作,表現為二叉判定樹中的一個內結點(internal node),用一個圓形結點表示,並用m標識。如果x=l[m],則演算法在該結點處成功終止。
  2. 二叉判定樹的根節點,代表演算法中首次與x比較的元素l[m],用m標識。
  3. x<l[m]時,演算法隨後與x比較的元素下標所標識的結點是結點m的左孩子;當x>l[m]時,演算法隨後與x比較的元素下標所標識的結點是結點m的右孩子。
  4. x<l[m]且演算法終止,那麼結點m的左孩子以標號為m-1的方形結點表示;若x>l[m]且演算法終止,那麼結點m的右孩子以標號m的方形結點表示。方形結點稱為外結點(external node)。如果演算法在方形結點m處終止,這意味著搜尋失敗。
  5. 從根節點到每一個內結點的一條路徑代表成功搜尋的一條比較路徑。如果搜尋成功則演算法在內結點處終止,否則在外結點處終止。

二叉判定樹性質

  • 只有n(n>0)個內結點的對半搜尋二叉判定樹的左子樹上有(n1)/2個內結點,右子樹上有n/2個內結點。
  • 具有n(n>0)個內結點的對半搜尋二叉判定樹的高度為logn+1(不計外結點)。
  • n=2h1,則對半搜尋二叉判定樹為滿二叉樹。
  • n=2h2,則對半搜尋二叉判定樹的外結點均在h+1層,否則,在第h或者h+1層上,h=logn+1
  • 對半搜尋演算法成功情況下,關鍵字之間的比較次數不超過logn+1。失敗的情況下,演算法需要進行lognlogn+1次比較。
  • 對半搜尋演算法在搜尋成功時的平均時間複雜度為Θ(logn)

搜尋演算法的時間下界

定理:在一個有

相關推薦

0x05演算法設計分析複習演算法設計策略-治法2

參考書籍:演算法設計與分析——C++語言描述(第二版) 演算法設計策略-分治法 二分搜尋 問題描述 在有序表(已按關鍵字值非減排序)中搜索給定元素的問題。 分治法求解 設有一個長度為n的有序表(a0,a1,⋯,an−1),要求

VIVADO FIR濾波器設計仿真

put tps ilo 用法 ilog ril [ ] 技術 仿真 VIVADO FIR濾波器設計與仿真(二) 在VIVADO FIR濾波器設計與仿真(一)中產生了兩路正弦信號,頻率分別為4MHz和5MHz,今天要進行FIR濾波器設計,在進行濾波器設計之前,需要對濾波器的參

PHP面試程序設計、框架基礎知識、算法數據結構、高並發解決方案類

表設計 工作原理 結構 單一入口 php 能力 高並發解決方案 數據表 缺點 一、程序設計 1、設計功能系統——數據表設計、數據表創建語句、連接數據庫的方式、編碼能力 二、框架基礎知識 1、MVC框架基本原理——原理、常見框架、單一入口的工作原理、模板引擎的理解 2、常見框

Java常用的八種排序演算法程式碼實現歸併排序法、快速排序法

注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

資料結構演算法及其描述

一、演算法及其描述 1、什麼是演算法 資料元素之間的關係有邏輯關係和物理關係,對應的操作有邏輯結構上的操作功能和具體儲存結構上的操作實現。 把 具體儲存結構上的操作實現方法 稱為演算法。 確切地說,演算法是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一

Spring Boot Actuator詳解深入應用Actuator 2.x

《Spring Boot Actuator詳解與深入應用》預計包括三篇,第一篇重點講Spring Boot Actuator 1.x的應用與定製端點;第二篇將會對比Spring Boot Actuator 2.x 與1.x的區別,以及應用和定製2.x的端點;第三篇將會介紹Actuator metric指

資料探勘十大演算法——支援向量機SVM線性支援向量機的軟間隔最大化模型

首先感謝“劉建平pinard”的淵博知識以及文中詳細準確的推導!!! 支援向量機原理SVM系列文章共分為5部分: (一)線性支援向量機 (二)線性支援向量機的軟間隔最大化模型 (三)線性不可分支援向量機與核函式 (四)SMO演算法原理 (五)線性支援迴歸

資料探勘演算法之關聯規則挖掘FPGrowth演算法

之前介紹的apriori演算法中因為存在許多的缺陷,例如進行大量的全表掃描和計算量巨大的自然連線,所以現在幾乎已經不再使用 在mahout的演算法庫中使用的是PFP演算法,該演算法是FPGrowth演算法的分散式執行方式,其內部的演算法結構和FPGrowth演算法相差並不是

從ECMAScript規範深度分析JavaScript變數物件

本文譯自Dmitry Soshnikov的《ECMA-262-3 in detail》系列教程。其中會加入一些個人見解以及配圖舉例等等,來幫助讀者更好的理解JavaScript。 宣告:本文不涉及與ES6相關的知識。 前言 在本系列教程上一篇文章《從ECMAScript規範深度分

從ECMAScript規範深度分析JavaScript變數物件

本文譯自Dmitry Soshnikov的《ECMA-262-3 in detail》系列教程。其中會加入一些個人見解以及配圖舉例等等,來幫助讀者更好的理解JavaScript。 宣告:本文不涉及與ES6相關的知識。 前言 在學習變數物件之前,我們要對執行期上下文有所瞭解,可以先

機器學習神經網路感知器的介紹和Python程式碼實現

前言:本篇博文主要介紹感知器的相關知識,採用理論+程式碼實踐的方式,進行感知器的學習。本文首先介紹感知器的模型,然後介紹感知器學習規則(Perceptron學習演算法),最後通過Python程式碼實現單層感知器,從而給讀者一個更加直觀的認識。 1.單層感知器模型 單層感知器

Python機器學習Windows下科學計算環境搭建

【注意:安裝numpy和scipy模組時注意與Python版本保持一致】 1.安裝numpy 測試: 沒有報錯,bingo~ 2.安裝scipy 在官網中下載scipy3.4版本:scipy-0

網路遊戲《叢林戰爭》開發學習之粘包分包現象以及服務端解析資料

1. 粘包和分包 粘包和分包是利用Socket在TCP協議下內部的優化機制。粘包指的是傳送資料比較頻繁,但資料量較少,此時客戶端不會直接將資料包傳送給伺服器,而是會與其它的資料包進行一個結合,例如遊戲中的位置資訊就是屬於頻繁傳送但資料量小的資訊,此時如果每條資料都S

高效能伺服器架構快取清理策略

  雖然使用快取思想似乎是一個很簡單的事情,但是快取機制卻有一個核心的難點,就是——快取清理。我們所說的快取,都是儲存一些資料,但是這些資料往往是會變化的,我們要針對這些變化,清理

《深入理解Spark-核心思想源碼分析第二章Spark設計理念和基本架構

基礎知識 cut info 負責 驅動 源碼分析 spa spark 節點 若夫乘天地之正,而禦六氣之辯解,以遊無窮者,彼且惡乎待哉?

計算機演算法設計分析課本王曉東著課後演算法實現題1-3 最多約數問題

問題描述: 正整數x的約數是能整除x的正整數。正整數x的約數個數記為div(x)。例如,1 2 5 10都是10的約數,且div(10)=4。設a和b是2個正整數,a<=b,找出a和b之間約數個數最多的數x。 演算法設計: 對於給定的2個正整數a<=b,計算a和b之間約數個數最多

Spark學習——RDD的設計運行原理

center data 創建 組成 分享圖片 img medium 列操作 信息 Spark的核心是建立在統一的抽象RDD之上,使得Spark的各個組件可以無縫進行集成,在同一個應用程序中完成大數據計算任務。RDD的設計理念源自AMP實驗室發表的論文《Resilient

遊戲開發經驗談對戰類全球服遊戲的設計實現

bbr tro 機房 產品 sql 服務器 通過 簡單 自己實現 上篇文章《遊戲開發經驗談(一):遊戲架構裏隱藏的五個坑及其應對方案》,我們主要講解了遊戲架構設計當中隱藏的一些坑及其應對方案,錯過的小夥伴可以點擊鏈接回溯之前的內容。本期內容,將會重點介紹對戰類全球服遊戲的設

跟廠長學PHP內核源碼分析的環境工具

compiler one upload info org print fin 圖形界面 waiting 本文主要介紹分析源碼的方式,其中包含環境的搭建、分析工具的安裝以及源碼調試的基本操作。 一、工具清單 PHP7.0.12 GDB CLion 二、源碼下載及安裝

NOIP複賽複習STL演算法樹結構模板

STL演算法 STL 演算法是一些模板函式,提供了相當多的有用演算法和操作,從簡單如for_each(遍歷)到複雜如stable_sort(穩定排序),標頭檔案是:#include <algorithm>。常用STL 演算法庫包括:sort快速排序演算法、二分