8000 GitHub - devilkun/algorithm-php: ðŸ­ðŸ­uniting the internal work in a way that is in PHP
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

devilkun/algorithm-php

 
 

Repository files navigation

​

🳠用 PHP 的方å¼å®žçŽ°çš„å„类算法åˆé›† ðŸ³

php

English 

æ¯å‘¨æœ€å°‘一更,求出题,求è™å¾… At least once a week, ask for problems and abuse

简易结构

├──Package
│    ├── Sort  排åºç¯‡
│    │    ├── BubbleSort.php          冒泡排åº
│    │    ├── HeapSort.php            å †æŽ’åº   大根堆
│    │    ├── MBaseSort.php           åŸºæ•°æŽ’åº MSD
│    │    ├── LBaseSort.php           åŸºæ•°æŽ’åº LSD
│    │    ├── QuickSort.php           快速排åº
│    │    ├── ShuttleSort.php         飞梭排åº
│    │    ├── ShellSort.php           希尔排åº
│    │    ├── MergeSort.php           归并排åº
│    │    ├── InsertSort.php          æ’入排åº
│    │    └── SelectSort.php          选择排åº
│    │
│    ├── Query 查找篇
│    │    ├── BinaryQuery.php         二分查找
│    │    ├── InseertQuery.php        æ’入查找
│    │    ├── FibonacciQuery.php      æ–æ³¢é‚£å¥‘查找
│    │    ├── BFSQuery.php            广度优先查找
│         ├── Kmp.php                 算法导论-KMP算法
│         ├── DijkstraQuery.php       迪克斯特拉算法
│    │    └── QulickQuery.php         快速查找
│    │     
│    ├── Structure æ•°æ®ç»“æž„
│    │    ├── StackExample.php         堆栈   先进åŽå‡º LIFO (Last In First Out)
│    │    ├── LinearChain.php          线性表 å•链存储
│    │    └── LinearOrder.php          线性表 顺åºå­˜å‚¨
│    │    └── BinarySearchTree.php     äºŒå‰æœç´¢æ ‘  
│    │     
│    ├── Tools å°å·¥å…·é›†
│    │    └──  SystemSwitch.php       å †æ ˆå®žçŽ°è¿›åˆ¶è½¬æ¢  
│    │  
│    └── Other 其他
│         ├──  MonkeyKing.php         约瑟夫环
│         ├──  DynamicProgramming.php 动æ€è§„划
│         ├──  Fibonacci.php          æ–æ³¢é‚£å¥‘数列
│         ├──  StealingApples.php     å·è‹¹æžœæ±‚ä½™
│         ├──  HanoiGames.php         汉诺塔游æˆ
│         ├──  BidirectionalQueue.php åŒå‘队列
│         ├──  ColorBricks.php        彩色砖å—
│         ├──  GetCattle.php          牛年求牛
│         ├──  OnlyNumbers.php        求唯一数
│         ├──  PokerGames.php         洗扑克牌
│         ├──  Interval.php           抽奖区间算法
│         ├──  Maze.php               迷宫寻å€ç®—法
│         ├──  AntsClimb.php          èš‚èšçˆ¬æ†ç®—法
│         ├──  Encryption.php         对称加密算法
│         ├──  ElevatorDispatch.php   编程之美-电梯调度算法
│         ├──  PointInTriangle.php    å‘é‡å‰é›†è®¡ç®—点是å¦åœ¨ä¸‰è§’形中
│         ├──  TraversalOfBinary.php  äºŒå‰æ ‘éžé€’å½’é历算法实现
│         ├──  Knapsack.php           贪心算法之背包问题实现
│         └──  BigSmallReplace.php    Hello World 输出 Olleh Dlrow
│         └──  Solution.php           Facebooké¢è¯•题之岛屿周长算法
│         └──  RotationSort.php       Facebooké¢è¯•题之顺时针回旋算法
│         └──  Square.php             Facebooké¢è¯•题之判断四个点能å¦ç»„æˆæ­£æ–¹å½¢ç®—法
│         └──  Prim.php               Prim算法(最å°ç”Ÿæˆæ ‘算法)
│         └──  CartesianProduct.php   笛å¡å°”积算法
│         └──  Square.php             é¢è¯•题之平é¢ä»»æ„四点能å¦ç»„æˆä¸€ä¸ªçŸ©å½¢
│         └──  Judge.php              é¢è¯•é¢˜ä¹‹æ‰‘å…‹ç‰Œä¸­ä»»é€‰äº”å¼ åˆ¤æ–­æ˜¯ä¸æ˜¯é¡ºå­
│         └──  Factorial.php          é¢è¯•题之N的阶乘末尾有多少个0
|         └──  HashTable.php          HashTable
|         └──  RotateSort.php         é¢è¯•题之风车旋转排åºç®—法
│     
├──LICENSE
└──README.md

è¦åšä»€ä¹ˆï¼Ÿ

记录自己ç†è§£ç®—法,数æ®ç»“构的过程,尽å¯èƒ½çš„简å•å…¨é¢ä»¥åŠè¯¦ç»†ï¼Œè®©ç®—法学习è¿ç”¨çµæ´»è‡ªå¦‚,加油(ง •̀_•Ì)ง

当然

用 PHP 实现算法并替代官方æä¾›çš„函数是愚蠢的事情 .但这决ä¸ä»£è¡¨æ–Ÿé…Œç®—法就是件无æ„义的事 , æ¯ä¸ªç®—æ³•éƒ½æ˜¯ä¸€ç§æ€æƒ³çš„结晶 , å­¦ä¹ ä¼˜ç§€çš„æ€æƒ³ , 开拓æ€ç»´

什么是算法?

直白地说,算法就是任何明确定义的计算过程,它接收一些值或集åˆä½œä¸ºè¾“入,并产生一些值或集åˆä½œä¸ºè¾“出。这样,算法就是将输入转æ¢ä¸ºè¾“å‡ºçš„ä¸€ç³»åˆ—è®¡ç®—è¿‡ç¨‹ã€‚æ¥æºï¼šThomas H. Cormen, Chales E. Leiserson (2009), 《算法导论第三版》。

简而言之,我们å¯ä»¥è¯´ç®—法就是用æ¥è§£å†³ä¸€ä¸ªç‰¹å®šä»»åŠ¡çš„ä¸€ç³»åˆ—æ­¥éª¤ï¼ˆæ˜¯çš„ï¼Œä¸æ­¢è®¡ç®—æœºåœ¨ä½¿ç”¨ç®—æ³•ï¼Œäººç±»ä¹ŸåŒæ ·å¦‚此)。目å‰ï¼Œä¸€ä¸ªæœ‰æ•ˆçš„ç®—æ³•åº”è¯¥å«æœ‰ä¸‰ä¸ªé‡è¦ç‰¹æ€§ï¼š

  • 它必须是有é™çš„:如果你设计的算法永无休止地å°è¯•解决问题,那么它是无用的。
  • 它必须具备明确定义的指令:算法的æ¯ä¸€æ­¥éƒ½å¿…须准确定义,在任何场景下指令都应当没有歧义。
  • 它必须是有效的:一个算法被设计用以解决æŸä¸ªé—®é¢˜ï¼Œé‚£ä¹ˆå®ƒå°±åº”å½“èƒ½è§£å†³è¿™ä¸ªé—®é¢˜ï¼Œå¹¶ä¸”ä»…ä»…ä½¿ç”¨çº¸å’Œç¬”å°±èƒ½è¯æ˜Žè¯¥ç®—法是收敛的。

对数

log10100 相当于问"将多少个10相乘的结果为100",答案当然是2个了 å› æ­¤log10100=2,å³å¯¹æ•°è¿ç®—是幂è¿ç®—的逆è¿ç®—

left right
23 = 8 log28 = 3
24 = 16 log216 = 4
25 = 32 log232 = 5

è¿è¡Œæ—¶é—´

以二分查找为例,使用它å¯èŠ‚çœå¤šå°‘æ—¶é—´å‘¢ï¼Ÿç®€å•æŸ¥æ‰¾é€ä¸ªåœ°æ£€æŸ¥æ•°å­—,如果列表包å«100个数字,最多需è¦çŒœ100次。 æ¢è€Œè¨€ä¹‹æœ€å¤šéœ€è¦çŒœæµ‹çš„æ¬¡æ•°ä¸Žåˆ—表长度相åŒï¼Œè¿™è¢«ç§°ä¸ºçº¿æ€§æ—¶é—´(linear time),而二分查找则ä¸åŒï¼Œå¦‚果列表包å«100个元素 最多需è¦7次,如果列表包å«40亿个数字,最多需猜32次,而分查找的è¿è¡Œæ—¶é—´ä¸ºå¯¹æ•°æ—¶é—´ O(log)

大O表示法

大O表示法是一ç§ç‰¹æ®Šçš„表示法 ,指出了算法的速度有多快。有个屌用啊,实际上,你ç»å¸¸è¦åŽ»å¤åˆ¶åˆ«äººçš„代ç ã€‚ åœ¨è¿™ç§æƒ…况下,知é“这些算法的速度有快有慢

  • 算法的è¿è¡Œæ—¶é—´ä»¥ä¸åŒçš„速度增加
    • ä¾‹å¦‚ç®€å•æŸ¥æ‰¾ä¸ŽäºŒåˆ†æŸ¥æ‰¾çš„区别
元素 ç®€å•æŸ¥æ‰¾ 二分查找
100个元素 100ms 7ms
10000个元素 10s 14ms
1 000 000 000 个元素 11天 30ms
  • 大O表示法指出了算法有多快,例如列表包å«nä¸ªå…ƒç´ ï¼Œç®€å•æŸ¥æ‰¾éœ€è¦æ£€æŸ¥æ¯ä¸ªå…ƒç´ ï¼Œå› æ­¤éœ€è¦æ‰§è¡Œn次æ“作 使用大O表示法这个è¿è¡Œæ—¶é—´ä¸ºO(n),äºŒåˆ†æŸ¥æ‰¾éœ€è¦æ‰§è¡Œlogn次æ“作,使用大O表示为O(log n)
    • 一些常è§çš„大Oè¿è¡Œæ—¶é—´
  • O(log n) ,也å«å¯¹æ•°æ—¶é—´ï¼Œè¿™æ ·çš„算法包括二分算法
  • O(n),也å«çº¿æ€§æ—¶é—´ï¼Œè¿™æ ·çš„ç®—æ³•åŒ…æ‹¬ç®€å•æŸ¥æ‰¾ã€‚
  • O(n * log n) 快速排åº
  • O(n2),选择排åº
  • O(n!) å³é˜¶ä¹˜æ—¶é—´
    • 这里是é‡ç‚¹
  • ç®—æ³•çš„é€Ÿåº¦æŒ‡çš„å¹¶éžæ—¶é—´ï¼Œè€Œæ˜¯æ“作数的增速
  • 谈论算法的速度时间时,我们说的是éšç€è¾“入的增加,其è¿è¡Œæ—¶é—´å°†ä»¥ä»€ä¹ˆæ ·çš„速度增加
  • 算法的è¿è¡Œæ—¶é—´ç”¨å¤§O表示法表示
  • O(log n)比O(n)å¿«ï¼Œå½“éœ€è¦æœç´¢çš„元素越多时,å‰è€…比åŽè€…快的越多

编写解决实际问题的程åºè¿‡ç¨‹

  • 如何用数æ®å½¢å¼æè¿°é—®é¢˜ï¼Œå³å°†é—®é¢˜æŠ½è±¡ä¸ºä¸€ä¸ªæ•°å­¦æ¨¡åž‹
  • 问题所涉åŠåˆ°çš„æ•°æ®é‡çš„大å°åŠæ•°æ®ä¹‹é—´çš„关系
  • 如何在计算机中储存数æ®åŠä½“现数æ®ä¹‹é—´çš„关系
  • å¤„ç†æ•°æ®æ—¶éœ€è¦å¯¹æ•°æ®æ‰§è¡Œçš„æ“ä½œ
  • 编写的程åºçš„æ€§èƒ½æ˜¯å¦è‰¯å¥½

æ•°æ®(Data)

  • 是客观事物的符å·è¡¨ç¤ºï¼Œåœ¨è®¡ç®—机科学中指的是所有能输入到计算机中并被计算机程åºå¤„ç†çš„符å·çš„æ€»ç§°ã€‚
  • æ•°æ®å…ƒç´ (Data Element) :是数æ®çš„基本å•ä½ï¼Œåœ¨ç¨‹åºä¸­é€šå¸¸ä½œä¸ºä¸€ä¸ªæ•´ä½“æ¥è¿›è¡Œè€ƒè™‘和处ç†ã€‚一个数æ®å…ƒç´ å¯ç”±è‹¥å¹²ä¸ªæ•°æ®é¡¹(Data Item)组æˆã€‚
  • æ•°æ®é¡¹(Data Item) : 是数æ®çš„ä¸å¯åˆ†å‰²çš„æœ€å°å•ä½ã€‚æ•°æ®é¡¹æ˜¯å¯¹å®¢è§‚事物æŸä¸€æ–¹é¢ç‰¹æ€§çš„æ•°æ®æè¿°ã€‚
  • æ•°æ®å¯¹è±¡(Data Object) :是性质相åŒçš„æ•°æ®å…ƒç´ çš„集åˆï¼Œæ˜¯æ•°æ®çš„一个å­é›†ã€‚如字符集åˆC={‘A’,’B’,’C,…} 。
  • æ•°æ®ç»“æž„ :相互之间具有一定è”系的数æ®å…ƒç´ çš„集åˆã€‚
  • æ•°æ®çš„逻辑结构 : æ•°æ®å…ƒç´ ä¹‹é—´çš„相互关系称为逻辑结构。
  • æ•°æ®æ“作 : 对数æ®è¦è¿›è¡Œçš„è¿ç®—
  • æ•°æ®ç±»åž‹(Data Type):指的是一个值的集åˆå’Œå®šä¹‰åœ¨è¯¥å€¼é›†ä¸Šçš„一组æ“作的总称。

æ•°æ®çš„逻辑结构有四ç§åŸºæœ¬ç±»åž‹

  • 集åˆï¼šç»“构中数æ®å…ƒç´ ä¹‹é—´é™¤äº†â€œå±žäºŽåŒä¸€ä¸ªé›†åˆ"外,å†ä¹Ÿæ²¡æœ‰å…¶ä»–的关系
  • 线性结构:结构中的数æ®å…ƒç´ å­˜åœ¨ä¸€å¯¹ä¸€çš„关系
  • 树形结构:结构中的数æ®å…ƒç´ å­˜åœ¨ä¸€å¯¹å¤šçš„关系
  • 网状或者图状结构:结构中的数æ®å…ƒç´ å­˜åœ¨å¤šå¯¹å¤šçš„关系

æ•°æ®ç»“构的储存方å¼

由数æ®å…ƒç´ ä¹‹é—´çš„关系在计算机中有两ç§ä¸åŒçš„表示方法——顺åºè¡¨ç¤ºå’Œéžé¡ºåºè¡¨ç¤ºï¼Œä»Žåˆ™å¯¼å‡ºä¸¤ç§å‚¨å­˜æ–¹å¼ï¼Œé¡ºåºå‚¨å­˜ç»“构和链å¼å‚¨å­˜ç»“æž„

  • 顺åºå­˜å‚¨ç»“构:用数æ®å…ƒç´ åœ¨å­˜å‚¨å™¨ä¸­çš„相对ä½ç½®æ¥è¡¨ç¤ºæ•°æ®å…ƒç´ ä¹‹é—´çš„逻辑结构(关系),数æ®å…ƒç´ å­˜æ”¾çš„åœ°å€æ˜¯è¿žç»­çš„
  • 链å¼å­˜å‚¨ç»“构:在æ¯ä¸€ä¸ªæ•°æ®å…ƒç´ ä¸­å¢žåŠ ä¸€ä¸ªå­˜æ”¾å¦ä¸€ä¸ªå…ƒç´ åœ°å€çš„æŒ‡é’ˆ(pointer),用该指针æ¥è¡¨ç¤ºæ•°æ®å…ƒç´ ä¹‹é—´çš„逻辑结构(关系),数æ®å…ƒç´ å­˜æ”¾çš„åœ°å€æ˜¯å¦è¿žç»­æ²¡æœ‰è¦æ±‚

æ•°æ®çš„逻辑结构和物ç†ç»“构是密ä¸å¯åˆ†çš„两个方é¢ï¼Œä¸€ä¸ªç®—法的设计å–决于所选定的逻辑结构,而算法的实现ä¾èµ–于所采用的存储结构

算法(Algorithm)

是对特定问题求解方法(步骤)çš„ä¸€ç§æè¿°ï¼Œæ˜¯æŒ‡ä»¤çš„æœ‰é™åºåˆ—,其中æ¯ä¸€æ¡æŒ‡ä»¤è¡¨ç¤ºä¸€ä¸ªæˆ–多个æ“作。

算法具有以下五个特性

  • 有穷性: 一个算法必须总是在执行有穷步之åŽç»“æŸï¼Œä¸”æ¯ä¸€æ­¥éƒ½åœ¨æœ‰ç©·æ—¶é—´å†…完æˆ
  • 确定性:算法中æ¯ä¸€æ¡æŒ‡ä»¤å¿…须有确切的å«ä¹‰ï¼Œä¸å­˜åœ¨äºŒä¹‰æ€§ï¼Œä¸”ç®—æ³•åªæœ‰ä¸€ä¸ªå…¥å£å’Œä¸€ä¸ªå‡ºå£
  • å¯è¡Œæ€§ï¼š 一个算法是能行的,å³ç®—法æè¿°çš„æ“ä½œéƒ½å¯ä»¥é€šè¿‡å·²ç»å®žçŽ°çš„åŸºæœ¬è¿ç®—æ‰§è¡Œæœ‰é™æ¬¡æ¥å®žçް
  • 输入: 一个算法有零个或多个输入,这些输入å–自于æŸä¸ªç‰¹å®šçš„对象集åˆ
  • 输出: 一个算法有一个或多个输出,这些输出是åŒè¾“å…¥æœ‰ç€æŸäº›ç‰¹å®šå…³ç³»çš„é‡

ç®—æ³•å’Œç¨‹åºæ˜¯ä¸¤ä¸ªä¸åŒçš„æ¦‚念

ä¸€ä¸ªè®¡ç®—æœºç¨‹åºæ˜¯å¯¹ä¸€ä¸ªç®—法使用æŸç§ç¨‹åºè®¾è®¡è¯­è¨€çš„具体实现。算法必须å¯ç»ˆæ­¢æ„味ç€ä¸æ˜¯æ‰€æœ‰çš„计算机程åºéƒ½æ˜¯ç®—法。

评价一个好的算法有以下几个标准

  • 正确性(Correctness ): 算法应满足具体问题的需
  • å¯è¯»æ€§(Readability): 算法应容易供人阅读和交æµï¼Œå¯è¯»æ€§å¥½çš„算法有助于对算法的ç†è§£å’Œä¿®æ”¹
  • å¥å£®æ€§(Robustness): 算法应具有容错处ç†ï¼Œå½“è¾“å…¥éžæ³•æˆ–é”™è¯¯æ•°æ®æ—¶ï¼Œç®—法应能适当地作出å应或进行处ç†ï¼Œè€Œä¸ä¼šäº§ç”ŸèŽ«å其妙的输出结果
  • 通用性(Generality): 算法应具有一般性 ,å³ç®—法的处ç†ç»“果对于一般的数æ®é›†åˆéƒ½æˆç«‹

效率与存储é‡éœ€æ±‚: 效率指的是算法执行的时间;存储é‡éœ€æ±‚指算法执行过程中所需è¦çš„æœ€å¤§å­˜å‚¨ç©ºé—´ï¼Œä¸€èˆ¬åœ°ï¼Œè¿™ä¸¤è€…与问题的规模有关

ç®—æ³•çš„æ—¶é—´å¤æ‚度

算法中基本æ“作é‡å¤æ‰§è¡Œçš„æ¬¡æ•°æ˜¯é—®é¢˜è§„模nçš„æŸä¸ªå‡½æ•°ï¼Œå…¶æ—¶é—´é‡åº¦è®°ä½œT(n)=O(f(n)),称作算法的æ¸è¿‘æ—¶é—´å¤æ‚度(Asymptotic Time complexity)ï¼Œç®€ç§°æ—¶é—´å¤æ‚度

ç®—æ³•çš„ç©ºé—´å¤æ‚度

是指算法编写æˆç¨‹åºåŽï¼Œåœ¨è®¡ç®—机中è¿è¡Œæ—¶æ‰€éœ€å­˜å‚¨ç©ºé—´å¤§å°çš„度é‡ï¼Œè®°ä½œï¼šS(n)=O(f(n)),其中n为问题规模

é€’å½’å’Œå¾ªçŽ¯çš„ç®€å•æ¯”较:

  1. 从程åºä¸Šçœ‹ï¼Œé€’归表现为自己调用自己,循环则没有这样的形å¼ã€‚
  2. 递归是从问题的最终目标出å‘ï¼Œé€æ¸å°†å¤æ‚问题化为简å•问题,并且简å•的问题的解决æ€è·¯å’Œå¤æ‚é—®é¢˜ä¸€æ ·ï¼ŒåŒæ—¶å­˜åœ¨åŸºå‡†æƒ…况,就能最终求得问题,是逆å‘的。而循环是从简å•问题出å‘,一步步的å‘å‰å‘展,最终求得问题,是正å‘的。
  3. ä»»æ„循环都是å¯ä»¥ç”¨é€’å½’æ¥è¡¨ç¤ºçš„,但是想用循环æ¥å®žçŽ°é€’å½’ï¼ˆé™¤äº†å•å‘递归和尾递归),都必须引入栈结构进行压栈出栈。
  4. 一般æ¥è¯´ï¼Œéžé€’归的效率高于递归。而且递归函数调用是有开销的,递归的次数å—堆栈大å°çš„é™åˆ¶ã€‚

一起进步学习

  1. Fork 我的项目并æäº¤ä½ çš„ idea
  2. Pull Request
  3. Merge

纠错

如果大家å‘现有什么ä¸å¯¹çš„地方,å¯ä»¥å‘起一个issue或者pull request,æˆ‘ä¼šåŠæ—¶çº æ­£

补充:å‘èµ·pull requestçš„commit message请å‚考文章Commit message å’Œ Change log 编写指å—

致谢

感谢以下朋å‹çš„issue或pull request:

MIT

5EEF

About

ðŸ­ðŸ­uniting the internal work in a way that is in PHP

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%
0