├── .gitignore ├── C01-The-Role-of-Algorithms-in-Computing ├── 1.1.md ├── 1.2.md └── problem.md ├── C02-Getting-Started ├── 2.1.md ├── 2.2.md ├── 2.3.md ├── exercise_code │ ├── binary-search.py │ ├── inversions.cpp │ ├── inversions.py │ └── merge-sort.py ├── problem.md └── repo │ ├── s1 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── algorithm.png │ ├── s2 │ └── 1.png │ └── s3 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png ├── C03-Growth-of-Functions ├── 3.1.md ├── 3.2.md └── problem.md ├── C04-Recurrences ├── 4.1.md ├── 4.2.md ├── 4.3.md ├── 4.4.md ├── exercise_code │ ├── findIndex.py │ └── findMissing.py ├── problem.md └── repo │ ├── p │ └── 1.png │ └── s2 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png ├── C05-Probabilistic-Analysis-and-Randomized-Algorithms ├── 5.1.2.png ├── 5.1.md ├── 5.2.md ├── 5.3.md ├── 5.4.md ├── 5_7.JPG ├── myrandom.py └── problem.md ├── C06-Heapsort ├── 6.1.md ├── 6.2.md ├── 6.3.md ├── 6.4.md ├── 6.5.md ├── d-ary-heaps.cpp ├── heap.cpp ├── main.cpp ├── makefile ├── p_queue.cpp ├── p_queue.h ├── problem.md ├── repo │ ├── p │ │ └── 1.png │ ├── s2 │ │ └── 1.png │ ├── s3 │ │ └── 1.png │ ├── s4 │ │ └── 1.png │ └── s5 │ │ ├── 1.png │ │ └── 2.png └── young.cpp ├── C07-Quicksort ├── 7.1.md ├── 7.2.md ├── 7.3.md ├── 7.4.md ├── exercise_code │ ├── fuzzy_sort.py │ ├── hoare.py │ ├── quickSortWithEqualElements.cpp │ ├── quicksort.py │ └── tailrecursive.py ├── problem.md ├── quicksort.py ├── randomized-quicksort.py └── repo │ ├── p │ └── 1.png │ └── s1 │ └── 1.png ├── C08-Sorting-in-Linear-Time ├── 8.1.md ├── 8.2.md ├── 8.3.md ├── 8.4.md ├── exercise_code │ ├── in_place_counting_sort.py │ ├── intergerQuery.cpp │ ├── radixSort.cpp │ └── water-jugs.py ├── problem.md └── repo │ ├── s1 │ └── 1.png │ └── s4 │ └── 1.png ├── C09-Medians-and-Order-Statistics ├── 9.1.md ├── 9.2.md ├── 9.3.md ├── exercise_code │ ├── k-close2median.py │ ├── k-quantile.py │ ├── randomized-select-iterative.cpp │ └── second-smallest.cpp ├── minmax.c ├── problem.md ├── problems │ ├── i-largest.cpp │ ├── i-largest.py │ └── weighted_median.py ├── randomized-select.cpp ├── repo │ ├── oil.png │ ├── p │ │ └── o.png │ ├── s1 │ │ ├── gif-1.gif │ │ ├── gif-2.gif │ │ ├── gif-3.gif │ │ ├── gif-4.gif │ │ └── gif.gif │ ├── s2 │ │ └── 1.gif │ └── s3 │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.gif │ │ └── 4.gif └── worst-case-linear-time.cpp ├── C10-Elementary-Data-Structures ├── 10.1.md ├── 10.2.md ├── 10.3.md ├── 10.4.md ├── README.md ├── exercise_code │ ├── af-obj.c │ ├── deque.cpp │ ├── deque.py │ ├── dict.cpp │ └── traversal.cpp ├── problem.md └── repo │ └── s4 │ └── 1.png ├── C11-Hash-Tables ├── 11.1.md ├── 11.2.md ├── 11.3.md ├── 11.4.md ├── 11.5.md ├── README.md ├── problem.md └── repo │ └── s1 │ └── 1.png ├── C12-Binary-Search-Trees ├── 12.1.md ├── 12.2.md ├── 12.3.md ├── 12.4.md ├── BSTree.h ├── main.cpp ├── makefile └── repo │ ├── s1 │ ├── 1.png │ ├── 2.png │ └── 3.png │ ├── s2 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png │ └── s3 │ ├── 1.png │ └── 2.png ├── C13-Red-Black-Trees ├── 13.1.md ├── 13.2.md ├── 13.3.md ├── 13.4.md ├── problem.md ├── rbtree.c ├── rbtree.cpp └── repo │ ├── p │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── 5.png │ ├── s1 │ ├── 1.png │ ├── 2.png │ └── 3.png │ ├── s2 │ └── 1.png │ ├── s3 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png │ └── s4 │ ├── 1.png │ └── 2.png ├── C14-Augmenting-Data-Structures ├── 14.1.md ├── 14.2.md ├── 14.3.md ├── exercise_code │ ├── m-Josephus.cpp │ └── test └── problem.md ├── C15-Dynamic-Programming ├── 15.1.md ├── 15.2.md ├── 15.3.md ├── 15.4.md ├── 15.5.md ├── Assembly-line-sche.c ├── Matrix-chain-multiplication.c ├── lincrs.cpp ├── optimalBST.cpp ├── repo │ └── s3 │ │ └── 1.png └── rodcutting.cpp ├── C16-Greedy-Algorithms ├── 16.1.md ├── 16.2.md ├── 16.3.md ├── huffman │ ├── BinaryStdIn.cpp │ ├── BinaryStdIn.h │ ├── BinaryStdOut.cpp │ ├── BinaryStdOut.h │ ├── HUFFMAN.cpp │ ├── HUFFMAN.h │ ├── binary_test │ │ ├── main.cpp │ │ └── makefile │ ├── binarystdin_test │ │ ├── main.cpp │ │ └── makefile │ ├── binarystdout_test │ │ ├── data │ │ ├── main.cpp │ │ └── makefile │ └── huffman_test │ │ ├── compressed │ │ ├── huffman_test_client.cpp │ │ └── makefile └── repo │ ├── s1 │ └── 1.png │ ├── s2 │ ├── 1.png │ └── 2.png │ └── s3 │ └── 1.png ├── C17-Amortized-Analysis ├── 17.1.md └── 17.2.md ├── C18-B-Trees ├── 18.1.md ├── 18.2.md ├── 18.3.md ├── btree.cpp └── repo │ ├── s1 │ ├── 1.png │ └── 2.png │ └── s2 │ ├── 1.png │ └── 2.png ├── C19-Binomial-Heaps ├── 19.1.md ├── 19.2.md ├── BinomialHeap.h └── Main.cpp ├── C21-Data-Structures-for-Disjoint-Sets ├── 21.1.md ├── 21.2.md ├── 21.3.md ├── repo │ └── s3 │ │ └── 1.png └── uf.cpp ├── C22-Elementary-Graph-Algorithms ├── 22.1.md ├── 22.2.md ├── 22.3.md ├── 22.4.md ├── 22.5.md ├── README.md ├── elementary_graph_algo.py ├── exercise_code │ └── EulerTour.cpp ├── problem.md └── repo │ ├── s2 │ ├── 1.png │ ├── 2.png │ └── 3.png │ ├── s3 │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png │ ├── s4 │ └── 1.png │ └── s5 │ ├── 1.png │ └── 2.png ├── C23-Minimum-Spanning-Trees ├── 23.1.md ├── 23.2.md └── repo │ ├── s1 │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ └── 4.jpg │ └── s2 │ ├── 1.png │ └── 2.png ├── C24-Single-Source-Shortest-Paths ├── 24.1.md ├── 24.2.md ├── 24.3.md ├── 24.4.md ├── README.md └── repo │ └── s3 │ ├── 1.png │ ├── 2.png │ ├── 24.3-5-equal.png │ ├── 24.3-5.png │ └── 3.png ├── C25-All-Pairs-Shortest-Paths ├── 25.1.md ├── 25.2.md ├── 25.3.md ├── Floyd_Warshall.cpp ├── README.md └── repo │ ├── s2 │ ├── 1.png │ └── 2.png │ └── s3 │ └── 25_3_6.gif ├── C26-Flow-networks ├── 26.1.md ├── 26.2.md ├── 26.3.md ├── maxflow │ ├── FlowEdge.cpp │ ├── FlowNetwork.cpp │ ├── FordFulkerson.cpp │ ├── input.txt │ ├── makefile │ ├── readme.md │ ├── testFlowEdge.cpp │ └── testFlowNetwork.cpp └── repo │ ├── s2 │ ├── 1.png │ └── 2.png │ └── s3 │ ├── 1.png │ └── 5.png ├── C31-Number-Theoretic-Algorithms ├── 31.1.md ├── 31.2.md ├── 31.7.md ├── euclid.py ├── exercise_code │ ├── binary2decimal.py │ └── lcm.py └── extended_euclid.py ├── C32-String-Matching ├── 32.1.md ├── 32.2.md ├── 32.3.md ├── 32.4.md ├── BF.c ├── BM.c ├── FA.c ├── KMP.c ├── README.md ├── RK.c ├── exercise_code │ └── str_spin.c └── repo │ ├── s1 │ ├── 1.png │ └── 2.png │ └── s2 │ └── 1.png ├── C33-Computational-Geometry ├── 33.1.md ├── Graham_Scan.py ├── area.png ├── exercise_code │ ├── area.cpp │ ├── colinear.cpp │ ├── convex_polygon.cpp │ ├── pointpolygon.cpp │ ├── polarCMP.cpp │ └── ray_intersection.cpp └── twoline.cpp ├── C35-Approximation-Algorithms ├── 35.1.md └── 35.2-5.md ├── LICENSE ├── README.md └── other ├── Karatsuba ├── Karatsuba.cpp ├── main.cpp └── makefile ├── segmentTree.cpp ├── stringSpilit.cpp └── trie.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.out 3 | *.log 4 | *.gz 5 | *.aux 6 | *.tex 7 | 8 | images/ 9 | Tools/ 10 | -------------------------------------------------------------------------------- /C01-The-Role-of-Algorithms-in-Computing/1.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 1.1-1 2 | *** 3 | Give a real-world example in which one of the following computational problems appears: sorting, determining the best order for multiplying matrices, or finding the convex hull. 4 | 5 | ### `Answer` 6 | * 用到排序的应用很多,比如电商网站对商品按价格进行排序 7 | * The multiplication process in computers are time consuming than addition process. If we have three or more matrices to multiply, then we should check the order in which to multiply to reduce the number of multiplications. 8 | * [From Wiki]The problem of finding convex hulls finds its practical applications in pattern recognition, image processing, statistics, geographic information system, game theory, construction of phase diagrams, and static code analysis by abstract interpretation. It also serves as a tool, a building block for a number of other computational-geometric algorithms such as the rotating calipers method for computing the width and diameter of a point set. also application in [CV](http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html). 9 | 10 | 11 | ### Exercises 1.1-2 12 | *** 13 | Other than speed, what other measures of efficiency might one use in a real-world setting? 14 | 15 | ### `Answer` 16 | 内存使用,资源占用(网络,磁盘等) 17 | Memory requirement, Degree of parallelism, Resource use( cpu or gpu cycles, Disk IO etc), Accessibility(Cloud/local) 18 | 19 | 20 | ### Exercises 1.1-3 21 | *** 22 | Select a data structure that you have seen previously, and discuss its strengths and limitations. 23 | 24 | ### `Answer` 25 | 数组,访问速度快,不能动态调整大小. 26 | 27 | ### Exercises 1.1-4 28 | *** 29 | How are the shortest-path and traveling-salesman problems given above similar? How are they different? 30 | 31 | ### `Answer` 32 | * 相同点:都是在图中找一条路径 33 | * 不同点:最短路径只是求2个点之间的路径,但是旅行商问题要遍历全部点并且回到起点,是一个全排列问题. 34 | * In travelling salesman problem we want to know an order of delivery of stops that yields "lowest overall distance" travelled . 35 | * This "lowest overall distance" is similar to shortest path finding situation . 36 | * Shortest path is polynomially solvable but travelling -salesman is NP-Complete 37 | 38 | ### Exercises 1.1-5 39 | *** 40 | Come up with a real-world problem in which only the best solution will do. Then come up with one in which a solution that is "approximately" the best is good enough. 41 | 42 | ### `Answer` 43 | 这题好抽象 0 0 求根如果是无理数近似就行了找不到最优的. 44 | 45 | 46 | 47 | 48 | *** 49 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 50 | 51 | -------------------------------------------------------------------------------- /C01-The-Role-of-Algorithms-in-Computing/1.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 1.2-1 2 | *** 3 | Give an example of an application that requires algorithmic content at the application level, and discuss the function of the algorithms involved. 4 | 5 | ### `Answer` 6 | 导航!!! 7 | Fingerprint matching algorithm used by forensics. Storing the fingerprints, and comparing them with the suspects prints 8 | it requires algorithms at application level. Function of algorithm is to have accurate matching and quick response. 9 | 10 | Akinator is web application that tells what was on our mind simly by asking questions . It uses Decision trees to come to conclusion. 11 | http://en.akinator.com/ 12 | 13 | 14 | ### Exercises 1.2-2 15 | *** 16 | Suppose we are comparing implementations of insertion sort and merge sort on the same machine. For inputs of size n, insertion sort runs in ![](http://latex.codecogs.com/gif.latex?8n^2) 17 | steps, while merge sort runs in ![](http://latex.codecogs.com/gif.latex?64nlg{n}) 18 | steps. For which values of n does insertion sort beat merge sort? 19 | 20 | ### `Answer` 21 | 解方程 ![](http://latex.codecogs.com/gif.latex?8n^2=64nlg{n}) 22 | 23 | for 2 < n < 43 24 | 25 | 26 | ### Exercises 1.2-3 27 | *** 28 | What is the smallest value of n such that an algorithm whose running time is ![](http://latex.codecogs.com/gif.latex?100n^2) runs faster 29 | than an algorithm whose running time is ![](http://latex.codecogs.com/gif.latex?2^n) on the same machine? 30 | 31 | ### `Answer` 32 | 还是解方程 ![](http://latex.codecogs.com/gif.latex?100n^2=2^n) 33 | 34 | for n = 15 35 | 36 | *** 37 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 38 | 39 | -------------------------------------------------------------------------------- /C01-The-Role-of-Algorithms-in-Computing/problem.md: -------------------------------------------------------------------------------- 1 | ### Problems 1 : Comparison of running times 2 | *** 3 | For each function **f**(n) and time t in the following table, determine the largest size n of a problem that can be solved in time t, assuming that the algorithm to solve the problem takes **f**(n) microseconds. 4 | 5 | ### `Answer` 6 | Item | 1 second | 1 miniute | 1 hour | 1 day | 1 month | 1 year | 1 century 7 | :----:|----:|----:|----:|----:|----:|----:|----: 8 | ![](http://latex.codecogs.com/gif.latex?\\lg{n}) | ![](http://latex.codecogs.com/gif.latex?\\2^{10^6}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{6*10^7}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{36*10^8}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{864*10^8}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{25920*10^8}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{315360*10^8}}) | ![](http://latex.codecogs.com/gif.latex?\\2^{31556736*10^8}}) 9 | ![](http://latex.codecogs.com/gif.latex?\\/{n}^{1/2}) | ![](http://latex.codecogs.com/gif.latex?\\10^{12}) | ![](http://latex.codecogs.com/gif.latex?\\36*10^{14}) | ![](http://latex.codecogs.com/gif.latex?\\1296*10^{16}) | ![](http://latex.codecogs.com/gif.latex?\\746496*10^{16}) | ![](http://latex.codecogs.com/gif.latex?\\6718464*10^{18}) | ![](http://latex.codecogs.com/gif.latex?\\994519296*10^{18}) | ![](http://latex.codecogs.com/gif.latex?\\995827586973696*10^{16}) 10 | ![](http://latex.codecogs.com/gif.latex?\\/{n}) | ![](http://latex.codecogs.com/gif.latex?\\10^6) | ![](http://latex.codecogs.com/gif.latex?6*10^7) | ![](http://latex.codecogs.com/gif.latex?36*10^8) | ![](http://latex.codecogs.com/gif.latex?864*10^8) | ![](http://latex.codecogs.com/gif.latex?2592*10^9) | ![](http://latex.codecogs.com/gif.latex?31536*10^9) | ![](http://latex.codecogs.com/gif.latex?31556736*10^8) 11 | ![](http://latex.codecogs.com/gif.latex?\\/{n}\\lg{n}) | 62746 | 2801417 | 133378058 | 2755147513| 71870856404 | 797633893349 | 68654697441062 12 | ![](http://latex.codecogs.com/gif.latex?\\/{n}^2) | 1000 | 7745 | 60000 | 293938 | 1609968 | 5615692 | 56175382 13 | ![](http://latex.codecogs.com/gif.latex?\\/{n}^3) | 100 | 391 | 1532 | 4420 | 13736 | 31593 | 146677 14 | ![](http://latex.codecogs.com/gif.latex?\\2^n) | 19 | 25 | 31 | 36 | 41 | 44 | 51 15 | ![](http://latex.codecogs.com/gif.latex?\\/{n}!) | 9 | 11 | 12 | 13 | 15 | 16 | 17 16 | 17 | 18 | *** 19 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 20 | 21 | -------------------------------------------------------------------------------- /C02-Getting-Started/2.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 2.1-1 2 | *** 3 | Using Figure 2.2 as a model, illustrate the operation of INSERTION-SORT on the array A = [31, 41, 59, 26, 41, 58]. 4 | 5 | ### `Answer` 6 | ![pic](./repo/s1/1.png) 7 | 8 | 9 | ### Exercises 2.1-2 10 | *** 11 | Rewrite the INSERTION-SORT procedure to sort into nonincreasing instead of nondecreasing order. 12 | 13 | ### `Answer` 14 | ![pic](./repo/s1/2.png) 15 | 16 | 17 | ### Exercises 2.1-3 18 | *** 19 | Consider the searching problem: 20 | 21 | * **Input**: A sequence of n numbers A = [a1, a2, . . . , an] and a value v. 22 | * **Output**: An index i such that v = A[i] or the special value NIL if v does not appear in A. 23 | 24 | 25 | Write pseudocode for **linear search**, which scans through the sequence, looking for v. Using a loop invariant, prove that your algorithm is correct. Make sure that your loop invariant fulfills the three necessary properties. 26 | 27 | ### `Answer` 28 | ![pic](./repo/s1/3.png) 29 | 30 | ### Exercises 2.1-4 31 | *** 32 | Consider the problem of adding two n-bit binary integers, stored in two n-element arrays A and B. The sum of the two integers should be stored in binary form in an (n + 1)-element array C. State the problem formally and write pseudocode for adding the two integers. 33 | 34 | ### `Answer` 35 | ![pic](./repo/s1/algorithm.png) 36 | 37 | ``` 38 | C = Array[A.length+1] 39 | carry <- 0, 40 | for i <- A.length to 1 41 | C[i+1] <- (A[i] + B[i] + carry) % 2; 42 | carry = (A[i] + B[i] + carry)/2; 43 | C[1] <- carry; 44 | return C 45 | ``` 46 | 47 | *** 48 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 49 | -------------------------------------------------------------------------------- /C02-Getting-Started/2.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 2.2-1 2 | *** 3 | Express the function ![](http://latex.codecogs.com/gif.latex?n^3/1000-100n^2-100n+3) 4 | in terms of Θ-notation. 5 | 6 | ### `Answer` 7 | Θ(n^3) 8 | 9 | 10 | ### Exercises 2.2-2 11 | *** 12 | Consider sorting n numbers stored in array A by first finding the smallest element of A and exchanging it with the element in A[1]. Then find the second smallest element of A, and exchange it with A[2]. Continue in this manner for the first n - 1 elements of A. Write pseudocode for this algorithm, which is known as **selection sort**. What loop invariant does this algorithm maintain? Why does it need to run for only the first n - 1 elements, rather than for all n elements? Give the best-case and worst-case running times of selection sort in Θ- notation. 13 | 14 | ### `Answer` 15 | ![pic](./repo/s2/1.png) 16 | 17 | Loop invariant: at the start of each iteration of the outer for loop, the subarray A[1..i-1] consists of the i-1 smallest elements in the array A[1..n] and this subarray is in sorted order. 18 | 19 | After the first n-1 elements, the subarray A[1..n-1] contains the smallest n-1 elements, sorted, and therefore element A[n] must be the largest element 20 | 21 | 时间都是Θ(![](http://latex.codecogs.com/gif.latex?n^2)) 22 | 23 | 24 | ### Exercises 2.2-3 25 | *** 26 | Consider linear search again (see Exercise 2.1-3). How many elements of the input sequence need to be checked on the average, assuming that the element being searched for is equally likely to be any element in the array? How about in the worst case? What are the average-case and worst-case running times of linear search in Θ-notation? Justify your answers. 27 | 28 | ### `Answer` 29 | * 平均情况应该要查找(n+1)/2个元素 30 | * 最坏情况是n个 31 | 32 | * Assuming equal probability of occurrence 1/n, average number of elements which need to be checked is 1/n * (1 + 2 + ... +n) = (n+1)/2. Running time is Θ(n) 33 | * Worst case, the element to search is dead last in the array. In that case n elements need to be searched. Running time is Θ(n) 34 | 35 | 所以都是Θ(n) 36 | 37 | 38 | ### Exercises 2.2-4 39 | *** 40 | How can we modify almost any algorithm to have a good best-case running time? 41 | 42 | ### `Answer` 43 | 算法开始检测输入数据,若符合特殊条件则输出事先计算好的结果 44 | 45 | Modify the algorithm so it checks whether the input satisfies some special case condition. If it does, output a pre-computed answer. 46 | 47 | 48 | 49 | *** 50 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 51 | 52 | -------------------------------------------------------------------------------- /C02-Getting-Started/exercise_code/binary-search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def binarysearch(items, v): 5 | low = 0 6 | high = len(items)-1 7 | while low <= high: 8 | mid = int((low+high)/2) 9 | if(items[mid] == v): 10 | return mid 11 | elif(items[mid] < v): 12 | low = mid 13 | else: 14 | high = mid + 1 15 | return None 16 | 17 | items = [1,2,3,4,5] 18 | print binarysearch(items, 3) 19 | print binarysearch(items, 6) 20 | -------------------------------------------------------------------------------- /C02-Getting-Started/exercise_code/inversions.cpp: -------------------------------------------------------------------------------- 1 | // Created by wander on 16/5/14. 2 | // Copyright © 2016年 W4anD0eR96. All rights reserved. 3 | // 采用左闭右开的区间描述方式 4 | 5 | #include "bits/stdc++.h" 6 | using namespace std; 7 | 8 | void MergeWithCountInversions(vector& v, int p, int q, int r, int& cnt) { 9 | int n1 = q - p, n2 = r - q; 10 | vector L, R; 11 | for (int i = 0; i < n1; ++i) L.push_back(v[p + i]); 12 | for (int i = 0; i < n2; ++i) R.push_back(v[q + i]); 13 | L.push_back(INT_MAX); R.push_back(INT_MAX); 14 | 15 | int i = 0, j = 0; 16 | for (int k = p; k < r; ++k) { 17 | // i n1 j n2 18 | // | | | | 19 | // |--------)|---------) 20 | // 若此时发生L[i] > R[j],则由于L[0..i) < R[j]且R[0..j) < R[j] 21 | // 故与R[j]构成逆序对的元素是L[i..n1) 22 | if (L[i] <= R[j]) { v[k] = L[i]; i += 1; } 23 | else { v[k] = R[j]; j += 1; cnt += n1 - i; 24 | { for (int u = i; u < n1; ++u) cout << "(" << L[u] << "," << R[j - 1] << "), "; } // Print Inversions 25 | } 26 | } 27 | } 28 | 29 | void MergeSort(vector& v, int p, int r, int& cnt) { 30 | if (p >= r - 1) return; 31 | int q = (p + r) >> 1; 32 | MergeSort(v, p, q, cnt); 33 | MergeSort(v, q, r, cnt); 34 | MergeWithCountInversions(v, p, q, r, cnt); 35 | } 36 | 37 | int main(int argc, const char * argv[]) { 38 | vector v = { 31, 41, 59, 26, 41, 58 }; 39 | int cntInversions = 0; 40 | 41 | cout << "v: "; 42 | for (auto i : v) cout << i << " "; 43 | cout << endl; 44 | 45 | cout << "Total inversions are: "; 46 | MergeSort(v, 0, (int)v.size(), cntInversions); 47 | cout << endl; 48 | cout << "Whose amount is: " << cntInversions << "." << endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /C02-Getting-Started/exercise_code/inversions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def merge(items, p, q, r): 5 | L = items[p:q+1] 6 | R = items[q+1:r+1] 7 | i = j = 0 8 | k = p 9 | inversions = 0 10 | while i < len(L) and j < len(R): 11 | if(L[i] < R[j]): 12 | items[k] = L[i] 13 | i += 1 14 | else: 15 | items[k] = R[j] 16 | j += 1 17 | inversions += (len(L) - i) 18 | k += 1 19 | if(j == len(R)): 20 | items[k:r+1] = L[i:] 21 | return inversions 22 | 23 | 24 | 25 | def mergesort(items, p, r): 26 | inversions = 0 27 | if(p < r): 28 | q = (p+r)/2 29 | inversions += mergesort(items, p, q) 30 | inversions += mergesort(items, q+1, r) 31 | inversions += merge(items, p, q, r) 32 | return inversions 33 | 34 | 35 | items = [4,3,2,1,17] 36 | inversions = mergesort(items, 0, len(items)-1) 37 | print items,inversions -------------------------------------------------------------------------------- /C02-Getting-Started/exercise_code/merge-sort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def merge(items, p, q, r): 5 | L = items[p:q+1] 6 | R = items[q+1:r+1] 7 | i = j = 0 8 | k = p 9 | while i < len(L) and j < len(R): 10 | if(L[i] < R[j]): 11 | items[k] = L[i] 12 | i += 1 13 | else: 14 | items[k] = R[j] 15 | j += 1 16 | k += 1 17 | if(j == len(R)): 18 | items[k:r+1] = L[i:] 19 | 20 | 21 | 22 | def mergesort(items, p, r): 23 | if(p < r): 24 | q = (p+r)/2 25 | mergesort(items, p, q) 26 | mergesort(items, q+1, r) 27 | merge(items, p, q, r) 28 | 29 | 30 | items = [4,3,2,1,17] 31 | mergesort(items, 0, len(items)-1) 32 | print items -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s1/1.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s1/2.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s1/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s1/3.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s1/algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s1/algorithm.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s2/1.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s3/1.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s3/2.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s3/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s3/3.png -------------------------------------------------------------------------------- /C02-Getting-Started/repo/s3/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C02-Getting-Started/repo/s3/4.png -------------------------------------------------------------------------------- /C04-Recurrences/exercise_code/findIndex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | 5 | def mergeindex(items, evens): 6 | res = [] 7 | l = len(items[0]) 8 | for i in range(len(items)): 9 | left = evens[i] 10 | right = -1 11 | if i == len(items)-1 and len(evens) == len(items): 12 | right = l - 1 13 | else: 14 | right = evens[i+1] 15 | 16 | minimum = items[i][left] 17 | pos = left 18 | for j in range(left, right+1): 19 | if items[i][j] < minimum: 20 | minimum = items[i][j] 21 | pos = j 22 | res.append(evens[i]) 23 | res.append(pos) 24 | 25 | if len(evens) > len(items): 26 | res.append(evens[-1]) 27 | return res 28 | 29 | 30 | 31 | 32 | def findindex(items): 33 | 34 | if len(items) == 1: 35 | res = 0 36 | minimum = 2**31-1 37 | for i in range(len(items[0])): 38 | if items[0][i] < minimum: 39 | minimum = items[0][i] 40 | res = i 41 | return [res] 42 | 43 | evens = items[::2] 44 | evenres = findindex(evens) 45 | res = mergeindex(items[1::2], evenres) 46 | return res 47 | 48 | 49 | items=[[37,23,24,32],[21,6,7,10],[53,34,30,31],[32,13,9,6],[43,21,15,8]] 50 | print findindex(items) 51 | -------------------------------------------------------------------------------- /C04-Recurrences/exercise_code/findMissing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def findmissing(items, i) : 5 | if len(items) == 0: 6 | return 0 7 | 8 | numone = numzero = 0 9 | itemone = [] 10 | itemzero = [] 11 | for e in items: 12 | if (e >> i) & 1 == 0: 13 | numzero += 1 14 | itemzero.append(e) 15 | else: 16 | numone += 1 17 | itemone.append(e) 18 | 19 | if numone >= numzero: 20 | #remove 0 21 | return 2 * findmissing(itemzero, i+1) 22 | else: 23 | #remove 1 24 | return 2 * findmissing(itemone, i+1) + 1 25 | 26 | 27 | 28 | items = [0,1,2,3,5,6,7,8] 29 | print findmissing(items, 0) 30 | -------------------------------------------------------------------------------- /C04-Recurrences/repo/p/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C04-Recurrences/repo/p/1.png -------------------------------------------------------------------------------- /C04-Recurrences/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C04-Recurrences/repo/s2/1.png -------------------------------------------------------------------------------- /C04-Recurrences/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C04-Recurrences/repo/s2/2.png -------------------------------------------------------------------------------- /C04-Recurrences/repo/s2/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C04-Recurrences/repo/s2/3.png -------------------------------------------------------------------------------- /C04-Recurrences/repo/s2/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C04-Recurrences/repo/s2/4.png -------------------------------------------------------------------------------- /C05-Probabilistic-Analysis-and-Randomized-Algorithms/5.1.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C05-Probabilistic-Analysis-and-Randomized-Algorithms/5.1.2.png -------------------------------------------------------------------------------- /C05-Probabilistic-Analysis-and-Randomized-Algorithms/5.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 5.1-1 2 | *** 3 | Show that the assumption that we are always able to determine which candidate is best in line 4 of procedure HIRE-ASSISTANT implies that we know a total order on the ranks of the candidates. 4 | 5 | ### `Answer` 6 | **always**这个词表示对所有n!种组合,都能够确定,而这n!种组合已经囊括了所有的两两比较. 7 | 8 | 9 | ### Exercises 5.1-2 10 | *** 11 | Describe an implementation of the procedure RANDOM(a, b) that only makes calls to RANDOM(0, 1). What is the expected running time of your procedure, as a function of a and b? 12 | 13 | ### `Answer` 14 | Without loss of generality we may assume that a = 0. Otherwise we can generate a random number between 0 and b − a, then add a to it. 15 | 16 | [solution](./myrandom.py) 17 | 18 | Each iteration of the while loop takes O(n) time to run. The probability that the while loop stops on a given iteration is (b+1)/(2^n). Thus the expected running time is the expected number of iterations of the while-loop times 19 | n. This is given by: 20 | 21 | ![](5.1.2.png) 22 | 23 | Since we assume a = 0 in the first, the final running time is: O(lg(b-a)) 24 | 25 | But this algorithm is non-deterministic. 26 | 27 | [Reference1: mathcamp.org](https://www.mathcamp.org/2015/academics/michelle/AlgorithmsHomework3Solutions.pdf) 28 | [Reference2: stackoverflow](https://stackoverflow.com/questions/8692818/how-to-implement-randoma-b-with-only-random0-1) 29 | 30 | ### Exercises 5.1-3 31 | *** 32 | Suppose that you want to output 0 with probability 1/2 and 1 with probability 1/2. At your disposal is a procedure BIASED-RANDOM, that outputs either 0 or 1. It outputs 1 with some probability p and 0 with probability 1 - p, where 0 < p < 1, but you do not know what p is. Give an algorithm that uses BIASED-RANDOM as a subroutine, and returns an unbiased answer, returning 0 with probability 1/2 and 1 with probability 1/2. What is the expected running time of your algorithm as a function of p? 33 | 34 | ### `Answer` 35 | while true: 36 | x = BIASED-RANDOM() 37 | y = BIASED-RANDOM() 38 | if x != y: 39 | return x 40 | 41 | expected running time = 1/(2p(1-p)) 42 | 43 | 44 | *** 45 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 46 | -------------------------------------------------------------------------------- /C05-Probabilistic-Analysis-and-Randomized-Algorithms/5.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 5.2-1 2 | *** 3 | In HIRE-ASSISTANT, assuming that the candidates are presented in a random order, what is the probability that you will hire exactly one time? What is the probability that you will hire exactly n times? 4 | 5 | ### `Answer` 6 | 分别是1/n和1/n! 7 | 8 | 9 | ### Exercises 5.2-2 10 | *** 11 | In HIRE-ASSISTANT, assuming that the candidates are presented in a random order, what is the probability that you will hire exactly twice? 12 | 13 | ### `Answer` 14 | 如果第一个雇员的质量是k,那么质量高于k的雇员都必须在质量最高的雇员后面. 15 | 16 | 假设有n个雇员,质量分别是1,2,...,n.当第一个质量为k时,只雇佣2次的概率p = 1/(n-k).因为有n-k个质量比k高的,而且必须要最高的那个在前.而第一个质量为k的概率是1/n.所以 17 | 18 | ![](http://latex.codecogs.com/gif.latex?%20p%20=%20\\sum_{k%20=%201}^{n-1}\\frac{1}{n}\\frac{1}{n-k}%20=%20\\frac{1}{n}\\sum_{k%20=%201}^{n-1}\\frac{1}{k}) 19 | 20 | ### Exercises 5.2-3 21 | *** 22 | Use indicator random variables to compute the expected value of the sum of n dice. 23 | 24 | ### `Answer` 25 | Expectation of a single die 26 | 27 | ![](http://latex.codecogs.com/gif.latex?%20E\(X_i\)%20=%20\\frac{1+2+3+4+5+6}{6}%20=%203.5%20%20) 28 | 29 | Expectation of N dies 30 | 31 | ![](http://latex.codecogs.com/gif.latex?%20E\(X\)%20=%20\\sum_{i%20=%201}^{n}%20E\(X_i\)%20=%203.5n%20) 32 | 33 | ### Exercises 5.2-4 34 | *** 35 | Use indicator random variables to solve the following problem, which is known as the **hat- check problem**. Each of n customers gives a hat to a hat-check person at a restaurant. The hat- check person gives the hats back to the customers in a random order. What is the expected number of customers that get back their own hat? 36 | 37 | ### `Answer` 38 | 每个人都是1/n的期望,所以总的是1 39 | 40 | ### Exercises 5.2-5 41 | *** 42 | Let A[1...n] be an array of n distinct numbers. If i < j and A[i] > A[j], then the pair (i, j) is called an inversion of A. (See Problem 2-4 for more on inversions.) Suppose that each element of A is chosen randomly, independently, and uniformly from the range 1 through n. Use indicator random variables to compute the expected number of inversions. 43 | 44 | ### `Answer` 45 | 最简单的解法如下: 46 | 47 | 因为概率是一样的,所以出现正序和逆序是等量的,总共有n(n-1)/2对,所以期望是n(n-1)/4对. 48 | 49 | 50 | *** 51 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 52 | 53 | -------------------------------------------------------------------------------- /C05-Probabilistic-Analysis-and-Randomized-Algorithms/5_7.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C05-Probabilistic-Analysis-and-Randomized-Algorithms/5_7.JPG -------------------------------------------------------------------------------- /C05-Probabilistic-Analysis-and-Randomized-Algorithms/myrandom.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import numpy as np 5 | from math import log 6 | from random import randint 7 | from collections import Counter 8 | import matplotlib.pyplot as plt 9 | 10 | def _m_random(b): 11 | n = int(log(b, 2)) + 1 12 | while True: 13 | r = 0 14 | for i in range(n): 15 | r = 2*r + randint(0, 1) 16 | if r <= b: 17 | return r 18 | 19 | def m_random(a, b): 20 | return _m_random(b - a) + a 21 | 22 | def main(): 23 | result = Counter() 24 | for i in xrange(10000): 25 | temp = m_random(1,7) 26 | result.update('{}'.format(temp)) 27 | key, value = zip(*result.items()) 28 | indexes = np.arange(len(key)) 29 | width = 1 30 | plt.bar(indexes,value,width) 31 | plt.xticks(indexes + 0.5 * width, key) 32 | plt.show() 33 | 34 | if __name__ == '__main__': 35 | main() 36 | -------------------------------------------------------------------------------- /C06-Heapsort/6.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 6.1-1 2 | *** 3 | What are the minimum and maximum numbers of elements in a heap of height h? 4 | 5 | ### `Answer` 6 | 最多就是一颗很完美的二叉树,是2^(h+1) − 1 ; 最少的话最后一层只有一个,是2^h 7 | 8 | What it is a perfect complete tree, it is 2^(h+1) - 1; when the last level has only one element, we have 2^h. 9 | 10 | ### Exercises 6.1-2 11 | *** 12 | Show that an n-element heap has height ⌞lg n⌟ 13 | 14 | ### `Answer` 15 | ![](http://latex.codecogs.com/gif.latex?%202^{h+1}-1\\geq%20x%20\\geq%202^{h}%20\\rightrightarrows%20%20\\lg{x}%20\\geq%20h%20\\geq%20\\lg\(x+1\)-1%20) 16 | 17 | 所以h = ⌞lg n⌟ 18 | 19 | ### Exercises 6.1-3 20 | *** 21 | Show that in any subtree of a max-heap, the root of the subtree contains the largest value occurring anywhere in that subtree. 22 | 23 | ### `Answer` 24 | 这就是最大堆的性质. 25 | 26 | This is the property of maximum heap. 27 | 28 | ### Exercises 6.1-4 29 | *** 30 | Where in a max-heap might the smallest element reside, assuming that all elements are distinct? 31 | 32 | ### `Answer` 33 | It must be in the leaf node. 34 | 35 | ### Exercises 6.1-5 36 | *** 37 | Is an array that is in sorted order a min-heap? 38 | 39 | ### `Answer` 40 | 没有说明是递增数组还是递减数组,所以不一定. 41 | 42 | We don't know whether it's an increasing order or descending order. 43 | 44 | ### Exercises 6.1-6 45 | *** 46 | Is the sequence [23, 17, 14, 6, 13, 10, 1, 5, 7, 12] a max-heap? 47 | 48 | ### `Answer` 49 | NO, because 7 > 6 50 | 51 | ### Exercises 6.1-7 52 | *** 53 | Show that, with the array representation for storing an n-element heap, the leaves are the nodes indexed by ⌞n/2⌟ + 1, ⌞n/2⌟ + 2, ... , n. 54 | 55 | ### `Answer` 56 | 挺容易推的,因为每增加两个节点,树的叶子节点就会往后推移一位.再注意一下取整的位置就行. 57 | 58 | It is easy to conclude, every time we add two nodes, the index of leaf nodes will increase 1. 59 | *** 60 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 61 | 62 | -------------------------------------------------------------------------------- /C06-Heapsort/6.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 6.2-1 2 | *** 3 | Using Figure 6.2 as a model, illustrate the operation of MAX-HEAPIFY(A, 3) on the array A = 27,17, 3, 16, 13, 10, 1, 5, 7, 12, 4, 8, 9, 0. 4 | 5 | 6 | ### `Answer` 7 | ![](./repo/s2/1.png) 8 | 9 | 10 | ### Exercises 6.2-2 11 | *** 12 | Starting with the procedure MAX-HEAPIFY, write pseudocode for the procedure MIN- HEAPIFY(A, i), which performs the corresponding manipulation on a min-heap. How does the running time of MIN-HEAPIFY compare to that of MAX-HEAPIFY? 13 | 14 | 15 | ### `Answer` 16 | 17 | MIN-HEAPIFY(A, i): 18 | l <- LEFT(i) 19 | r <- RIGHT(i) 20 | if l ≤ heap-size[A] and A[l] < A[i]: 21 | then smallest <- l 22 | else smallest <- i 23 | if r ≤ heap-size[A] and A[r] < A[smallest]: 24 | then smallest <- r 25 | if smallest ≠ i: 26 | then swap(A[i], A[smallest]) 27 | MIN-HEAPIFY(A, smallest) 28 | 29 | ### Exercises 6.2-3 30 | *** 31 | What is the effect of calling MAX-HEAPIFY(A, i) when the element A[i] is larger than its children? 32 | 33 | ### `Answer` 34 | 函数直接返回. 35 | 36 | Just return. 37 | 38 | ### Exercises 6.2-4 39 | *** 40 | What is the effect of calling MAX-HEAPIFY(A, i) for i > heap-size[A]/2? 41 | 42 | ### `Answer` 43 | 这种情况下,这个节点是叶子节点. 44 | 45 | Under this condition, this node is a leaf node. 46 | 47 | ### Exercises 6.2-5 48 | *** 49 | The code for MAX-HEAPIFY is quite efficient in terms of constant factors, except possibly for the recursive call in line 10, which might cause some compilers to produce inefficient code. Write an efficient MAX-HEAPIFY that uses an iterative control construct (a loop) instead of recursion. 50 | 51 | ### `Answer` 52 | 53 | MIN-HEAPIFY(A, i): 54 | while i ≤ heap-size[A]: 55 | l <- LEFT(i) 56 | r <- RIGHT(i) 57 | if l ≤ heap-size[A] and A[l] > A[i]: 58 | then largest <- l 59 | else largest <- i 60 | if r ≤ heap-size[A] and A[r] > A[largest]: 61 | then largest <- r 62 | if largest ≠ i: 63 | then swap(A[i], A[largest]) 64 | i = largest 65 | else break 66 | 67 | ### Exercises 6.2-6 68 | *** 69 | Show that the worst-case running time of MAX-HEAPIFY on a heap of size n is Ω(lg n). (Hint: For a heap with n nodes, give node values that cause MAX-HEAPIFY to be called recursively at every node on a path from the root down to a leaf.) 70 | 71 | ### `Answer` 72 | 最坏情况是从root一直递归到leaf,因为heap的高度为⌞lg n⌟,所以最坏运行时间是Ω(lgn). 73 | 74 | In the worst case, this function will call until the leaf node. 75 | 76 | *** 77 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 78 | 79 | -------------------------------------------------------------------------------- /C06-Heapsort/6.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 6.3-1 2 | *** 3 | Using Figure 6.3 as a model, illustrate the operation of BUILD-MAX-HEAP on the array A = [5, 3, 17, 10, 84, 19, 6, 22, 9]. 4 | 5 | 6 | 7 | ### `Answer` 8 | ![](./repo/s3/1.png) 9 | 10 | 11 | ### Exercises 6.3-2 12 | *** 13 | Why do we want the loop index i in line 2 of BUILD-MAX-HEAP to decrease from ⌞length[A]/2⌟ to 1 rather than increase from 1 to ⌞length[A]/2⌟? 14 | 15 | 16 | ### `Answer` 17 | 如果先从1开始,它的子树并不是最大堆,肯定不能这样迭代. 18 | 19 | If we start from 1, because its subtree is not a maximum heap, we can't follow this order. 20 | 21 | ### Exercises 6.3-3 22 | *** 23 | Show that there are at most ![](http://latex.codecogs.com/gif.latex?%20\\lceil%20n/\(2^{h+1}\)%20\\rceil) nodes of height h in any n-element heap. 24 | 25 | ### `Answer` 26 | According to [6.1.1](./6.1.md)we have 27 | 28 | ![](http://latex.codecogs.com/gif.latex?%202^{h_0}%20\\le%20n%20\\le%202^{h_0+1}-1%20) 29 | 30 | Mark h0 as the height of tree. 31 | 32 | ![](http://latex.codecogs.com/gif.latex?%20\\lceil%20n/\(2^{h+1}\)%20\\rceil%20\\le%20\\lceil%20\(2^{h_0+1}-1\)/\(2^{h+1}\)%20\\rceil%20=%202^{h_0-h}) 33 | 34 | If the current layer is full, then we have equal. If in the leaf node and not full, we have less. 35 | 36 | *** 37 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 38 | 39 | -------------------------------------------------------------------------------- /C06-Heapsort/6.4.md: -------------------------------------------------------------------------------- 1 | ### Exercises 6.4-1 2 | *** 3 | Using Figure 6.4 as a model, illustrate the operation of HEAPSORT on the array A = [5, 13, 2, 25, 7, 17, 20, 8, 4]. 4 | 5 | 6 | 7 | ### `Answer` 8 | ![](./repo/s4/1.png) 9 | 10 | 11 | ### Exercises 6.4-2 12 | *** 13 | Argue the correctness of HEAPSORT using the following loop invariant: 14 | 15 | • At the start of each iteration of the for loop of lines 2-5, the subarray A[1...i] is a max-heap containing the i smallest elements of A[1...n], and the subarray A[i + 1...n] contains the n - i largest elements of A[1...n], sorted. 16 | 17 | 18 | ### `Answer` 19 | It is very obvious. 20 | 21 | ### Exercises 6.4-3 22 | *** 23 | What is the running time of heapsort on an array A of length n that is already sorted in increasing order? What about decreasing order? 24 | 25 | ### `Answer` 26 | If the array is in descending order, then we have the worst case, we need 27 | 28 | ![](http://latex.codecogs.com/gif.latex?%20\\sum_{i%20=%201}^{n}\\lg{i}%20=%20\\lg{n!}%20=%20\\Theta\(n\\lg{n}\)%20) 29 | 30 | If it is in increasing order, we still need![](http://latex.codecogs.com/gif.latex?\\Theta\(n\\lg{n}\)%20),Because the cost of Max_heapify doesn't change. 31 | 32 | 33 | ### Exercises 6.4-4 34 | *** 35 | Show that the worst-case running time of heapsort is Ω(n lg n). 36 | 37 | ### `Answer` 38 | Same as 6.3.3. 39 | 40 | ### Exercises 6.4-5 41 | *** 42 | Show that when all elements are distinct, the best-case running time of heapsort is Ω(n lg n). 43 | 44 | ### `Answer` 45 | It is actually a hard problem, see [solution](http://stackoverflow.com/questions/4589988/lower-bound-on-heapsort) 46 | 47 | *** 48 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 49 | 50 | -------------------------------------------------------------------------------- /C06-Heapsort/d-ary-heaps.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: d-ary-heaps.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Tue Jun 23 19:22:21 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | #define PARENT(i,d) ((i - 1) / d) 14 | #define CHILD(i,c,d) (3 * i + c + 1) 15 | 16 | typedef struct { 17 | int *elements; 18 | int d; 19 | int heap_size; 20 | } heap_t; 21 | 22 | void max_heapify(heap_t *heap, int i) { 23 | int largest = i; 24 | int basechild = CHILD(i, 0, heap->d); 25 | 26 | for (int k = 0; k < heap->d; k++) { 27 | int child = basechild+k; 28 | if (child < heap->heap_size && heap->elements[child] > heap->elements[largest]) 29 | largest = child; 30 | } 31 | 32 | if (largest != i) { 33 | swap(heap->elements[i],heap->elements[largest]); 34 | max_heapify(heap, largest); 35 | } 36 | } 37 | 38 | int extract_max(heap_t *heap) { 39 | int max = heap->elements[0]; 40 | heap->elements[0] = heap->elements[heap->heap_size - 1]; 41 | heap->heap_size--; 42 | max_heapify(heap, 0); 43 | return max; 44 | }; 45 | 46 | void increase_key(heap_t *heap, int i, int key) { 47 | if (key < heap->elements[i]) { 48 | cerr << "new key is smaller than current key" << endl; 49 | exit(-1); 50 | } 51 | 52 | while (i > 0 && heap->elements[PARENT(i,heap->d)] < key) { 53 | heap->elements[i] = heap->elements[PARENT(i,heap->d)]; 54 | i = PARENT(i,heap->d); 55 | } 56 | 57 | heap->elements[i] = key; 58 | } 59 | 60 | void insert(heap_t *heap, int key) { 61 | heap->heap_size++; 62 | heap->elements[heap->heap_size - 1] = INT_MIN; 63 | increase_key(heap, heap->heap_size - 1, key); 64 | } -------------------------------------------------------------------------------- /C06-Heapsort/heap.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: 2.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: 一 12/22 21:47:37 2014 7 | ************************************************************************/ 8 | #include 9 | using namespace std; 10 | 11 | /* 12 | * get the parent of this node 13 | */ 14 | int parent(int i) 15 | { 16 | return (i-1)/2; 17 | } 18 | 19 | /* 20 | * get the left child 21 | */ 22 | int left(int i) 23 | { 24 | return 2*i+1; 25 | } 26 | 27 | /* 28 | * get the right child 29 | */ 30 | int right(int i) 31 | { 32 | return 2*i+2; 33 | } 34 | 35 | /* 36 | * construct a sub-tree whose root is node i 37 | */ 38 | void maxHeapify(int A[], int n, int i) 39 | { 40 | int l = left(i); 41 | int r = right(i); 42 | int largest(0); 43 | if (l <= (n-1) && A[l] > A[i]) 44 | largest = l; 45 | else 46 | largest = i; 47 | if (r <= (n-1) && A[r] > A[largest]) 48 | largest = r; 49 | if(largest != i) 50 | { 51 | swap(A[i], A[largest]); 52 | maxHeapify(A, n, largest); 53 | } 54 | } 55 | 56 | /* 57 | * build the heap 58 | */ 59 | void buildMaxHeap(int A[], int n) 60 | { 61 | for(int i = n/2-1;i >= 0;i--) 62 | maxHeapify(A, n, i); 63 | 64 | } 65 | 66 | /* 67 | * heapsort 68 | */ 69 | void heapsort(int A[], int n) 70 | { 71 | buildMaxHeap(A, n); 72 | for(int i = n-1;i > 0;i--) 73 | { 74 | swap(A[0],A[i]); 75 | maxHeapify(A, --n, 0); 76 | } 77 | } 78 | 79 | void print(int A[], int n) 80 | { 81 | for(int i = 0;i < n;i++) 82 | cout << A[i] << " "; 83 | cout << endl; 84 | 85 | } 86 | 87 | int main() 88 | { 89 | int A[10] = {16,14,10,8,7,9,3,2,4,1}; 90 | heapsort(A, 10); 91 | print(A, 10); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /C06-Heapsort/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Sun Jan 4 19:51:21 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "p_queue.h" 20 | 21 | int main() 22 | { 23 | int A[10] = {10,9,8,7,6,5,4,3,2,1}; 24 | p_queue q1(A, 10); 25 | 26 | std::cout << q1.maximum() << std::endl; 27 | q1.insert(20); 28 | q1.insert(10); 29 | std::cout << q1.maximum() << std::endl; 30 | q1.extract_max(); 31 | std::cout << q1.maximum() << std::endl; 32 | q1.increase_key(0, 5); 33 | std::cout << q1.maximum() << std::endl; 34 | q1.extract_max(); 35 | std::cout << q1.maximum() << std::endl; 36 | q1.increase_key(1, 30); 37 | std::cout << q1.maximum() << std::endl; 38 | 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /C06-Heapsort/makefile: -------------------------------------------------------------------------------- 1 | sample : main.o p_queue.o 2 | g++ -o sample main.o p_queue.o 3 | main.o : main.cpp p_queue.h 4 | g++ -c main.cpp 5 | p_queue.o : p_queue.h p_queue.cpp 6 | g++ -c p_queue.cpp 7 | 8 | clean : 9 | rm sample main.o p_queue.o 10 | -------------------------------------------------------------------------------- /C06-Heapsort/p_queue.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: p_queue.h 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Sun Jan 4 19:16:19 2015 7 | ************************************************************************/ 8 | #ifndef _P_QUEUE_H 9 | #define _P_QUEUE_H 10 | #endif 11 | 12 | #include 13 | 14 | class p_queue 15 | { 16 | public: 17 | p_queue(int *A, int n); 18 | void insert(int x); 19 | int maximum(void); 20 | int extract_max(void); 21 | void increase_key(int i, int x); 22 | 23 | private: 24 | int a[10000]; 25 | int size; 26 | 27 | int parent(int i); 28 | int left(int i); 29 | int right(int i); 30 | void maxHeapify(int A[], int n, int i); 31 | void buildMaxHeap(int A[], int n); 32 | void heapsort(int A[], int n); 33 | }; 34 | -------------------------------------------------------------------------------- /C06-Heapsort/repo/p/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/p/1.png -------------------------------------------------------------------------------- /C06-Heapsort/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/s2/1.png -------------------------------------------------------------------------------- /C06-Heapsort/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/s3/1.png -------------------------------------------------------------------------------- /C06-Heapsort/repo/s4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/s4/1.png -------------------------------------------------------------------------------- /C06-Heapsort/repo/s5/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/s5/1.png -------------------------------------------------------------------------------- /C06-Heapsort/repo/s5/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C06-Heapsort/repo/s5/2.png -------------------------------------------------------------------------------- /C07-Quicksort/7.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 7.1-1 2 | *** 3 | Using Figure 7.1 as a model, illustrate the operation of PARTITION on the array A = [13, 19, 3, 5, 12, 8, 7, 4, 21, 2, 6, 11]. 4 | 5 | ### `Answer` 6 | ![](./repo/s1/1.png) 7 | 8 | 9 | ### Exercises 7.1-2 10 | *** 11 | What value of q does PARTITION return when all elements in the array A[p...r] have the same value? Modify PARTITION so that q = (p+r)/2 when all elements in the array A[p...r] have the same value. 12 | 13 | ### `Answer` 14 | It will return r. So we have to modify the code in case the worst situation. 15 | 16 | [code](./exercise_code/quicksort.py) 17 | 18 | ### Exercises 7.1-3 19 | *** 20 | Give a brief argument that the running time of PARTITION on a subarray of size n is Θ(n). 21 | 22 | ### `Answer` 23 | Because we just iterate the array once. 24 | 25 | ### Exercises 7.1-4 26 | *** 27 | How would you modify QUICKSORT to sort into nonincreasing order? 28 | 29 | ### `Answer` 30 | Change the condition **A[j] <= x** to **A[j] >= x** 31 | 32 | 33 | *** 34 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 35 | 36 | -------------------------------------------------------------------------------- /C07-Quicksort/7.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 7.3-1 2 | *** 3 | Why do we analyze the average-case performance of a randomized algorithm and not its worst-case performance? 4 | 5 | ### `Answer` 6 | 因为最坏情况很极端才会发生,我们想要的是期望时间. 7 | 8 | Because the worst case happen rarely, we want the average case to be fine. 9 | 10 | ### Exercises 7.3-2 11 | *** 12 | During the running of the procedure RANDOMIZED-QUICKSORT, how many calls are made to the random-number generator RANDOM in the worst case? How about in the best case? Give your answer in terms of Θ-notation. 13 | 14 | ### `Answer` 15 | The best : T(n) = 2T(n/2) + 1 = Θ(n) 16 | 17 | The worst : T(n) = T(n-1) + 1 = Θ(n) 18 | 19 | 20 | 21 | *** 22 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 23 | 24 | -------------------------------------------------------------------------------- /C07-Quicksort/exercise_code/fuzzy_sort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import random 4 | import copy 5 | 6 | def intersects(a, b): 7 | return a[0] <= b[1] and b[0] <= a[1] 8 | 9 | def before(a, b): 10 | return a[1] < b[0] 11 | 12 | def partition(items, p, r): 13 | pick = random.randint(p, r) 14 | items[pick], items[r] = items[r], items[pick] 15 | intersection = copy.deepcopy(items[r]); 16 | 17 | for i in range(p, r): 18 | if intersects(intersection, items[i]): 19 | if items[i][0] > intersection[0]: 20 | intersection[0] = items[i][0] 21 | if items[i][1] < intersection[1]: 22 | intersection[1] = items[i][1] 23 | 24 | s = p 25 | for i in range(p, r): 26 | if before(items[i], intersection): 27 | items[i], items[s] = items[s], items[i] 28 | s += 1 29 | 30 | items[r], items[s] = items[s], items[r] 31 | 32 | 33 | t = s + 1 34 | while t <= i: 35 | if intersects(items[i], intersection): 36 | items[t], items[i] = items[i], items[t] 37 | t += 1 38 | else: 39 | i -= 1 40 | 41 | return (s, t) 42 | 43 | 44 | def fuzzy_sort(items, p, r): 45 | if (p < r): 46 | pivot = partition(items, p, r); 47 | fuzzy_sort(items, p, pivot[0]); 48 | fuzzy_sort(items, pivot[1], r); 49 | 50 | 51 | items = [[2,4],[0,1],[3,5],[-1,-2],[0,99]] 52 | print items 53 | fuzzy_sort(items, 0, len(items)-1) 54 | print items 55 | -------------------------------------------------------------------------------- /C07-Quicksort/exercise_code/hoare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def quicksort(items, p, r): 5 | if p < r: 6 | q = partition(items, p, r) 7 | quicksort(items, p, q) 8 | quicksort(items, q+1, r) 9 | 10 | def partition(items, p, r): 11 | x = items[p] 12 | i = p - 1 13 | j = r + 1 14 | while True: 15 | 16 | while True: 17 | j = j - 1 18 | if items[j] <= x: 19 | break 20 | while True: 21 | i = i + 1 22 | if items[i] >= x: 23 | break 24 | if i < j: 25 | items[i],items[j] = items[j],items[i] 26 | else: 27 | return j 28 | 29 | 30 | items = [13,19,9,5,12,8,7,4,11,2,6,21] 31 | quicksort(items, 0, len(items)-1) 32 | print items 33 | -------------------------------------------------------------------------------- /C07-Quicksort/exercise_code/quicksort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def quicksort(items, p, r): 5 | if p < r: 6 | q = partition(items, p, r) 7 | quicksort(items, p, q-1) 8 | quicksort(items, q+1, r) 9 | 10 | def partition(items, p, r): 11 | x = items[r] 12 | i = p-1 13 | count = 0 14 | 15 | for j in range(p, r): 16 | if items[j] == x: 17 | count += 1 18 | 19 | if items[j] <= x: 20 | i = i + 1 21 | items[i],items[j] = items[j],items[i] 22 | 23 | items[i+1],items[r] = items[r],items[i+1] 24 | return i+1-count/2 25 | 26 | 27 | 28 | items = [2,5,9,3,7,0,-1] 29 | quicksort(items, 0, len(items)-1) 30 | print items 31 | -------------------------------------------------------------------------------- /C07-Quicksort/exercise_code/tailrecursive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def tail_quicksort(items, p, r): 5 | while p < r: 6 | q = partition(items, p, r) 7 | if r-q >= q-p: 8 | tail_quicksort(items, p, q-1) 9 | p = q+1 10 | else: 11 | tail_quicksort(items, q+1, r) 12 | r = q-1; 13 | 14 | def partition(items, p, r): 15 | x = items[r] 16 | i = p-1 17 | for j in range(p, r): 18 | if items[j] <= x: 19 | i = i + 1 20 | items[i],items[j] = items[j],items[i] 21 | 22 | items[i+1],items[r] = items[r],items[i+1] 23 | return i+1 24 | 25 | 26 | 27 | items = [2,5,9,3,7,0,-1] 28 | tail_quicksort(items, 0, len(items)-1) 29 | print items 30 | -------------------------------------------------------------------------------- /C07-Quicksort/quicksort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def quicksort(items, p, r): 5 | if p < r: 6 | q = partition(items, p, r) 7 | quicksort(items, p, q-1) 8 | quicksort(items, q+1, r) 9 | 10 | def partition(items, p, r): 11 | x = items[r] 12 | i = p-1 13 | for j in range(p, r): 14 | if items[j] <= x: 15 | i = i + 1 16 | items[i],items[j] = items[j],items[i] 17 | 18 | items[i+1],items[r] = items[r],items[i+1] 19 | return i+1 20 | 21 | 22 | 23 | items = [2,5,9,3,7,0,-1] 24 | quicksort(items, 0, len(items)-1) 25 | print items 26 | -------------------------------------------------------------------------------- /C07-Quicksort/randomized-quicksort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import random 5 | 6 | def randomized_quicksort(items, p, r): 7 | if p < r: 8 | q = randomized_partition(items, p, r) 9 | randomized_quicksort(items, p, q-1) 10 | randomized_quicksort(items, q+1, r) 11 | 12 | def randomized_partition(items, p, r): 13 | i = random.randint(p, r) 14 | items[i],items[r] = items[r],items[i] 15 | return partition(items, p, r) 16 | 17 | def partition(items, p, r): 18 | x = items[r] 19 | i = p-1 20 | for j in range(p, r): 21 | if items[j] <= x: 22 | i = i + 1 23 | items[i],items[j] = items[j],items[i] 24 | 25 | items[i+1],items[r] = items[r],items[i+1] 26 | return i+1 27 | 28 | 29 | 30 | items = [2,5,9,3,7,0,-1] 31 | randomized_quicksort(items, 0, len(items)-1) 32 | print items 33 | -------------------------------------------------------------------------------- /C07-Quicksort/repo/p/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C07-Quicksort/repo/p/1.png -------------------------------------------------------------------------------- /C07-Quicksort/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C07-Quicksort/repo/s1/1.png -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/8.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 8.1-1 2 | *** 3 | What is the smallest possible depth of a leaf in a decision tree for a comparison sort? 4 | 5 | ### `Answer` 6 | 当数组已经排序好,是n-1. 7 | 8 | 9 | ### Exercises 8.1-2 10 | *** 11 | Obtain asymptotically tight bounds on lg(n!) without using Stirling's approximation. Instead, evaluate the summation  12 | ![](http://latex.codecogs.com/gif.latex?%20\\sum_{k=1}^{n}\\lg{k}) 13 | using techniques from Section A.2. 14 | 15 | 16 | ### `Answer` 17 | ![](http://latex.codecogs.com/gif.latex?%0d%0a\\sum_{k=1}^n\\lg{k}%20\\le%20\\sum_{k=1}^n\\lg{n}%20=%20n\\lg{n}%20=%20O\(n\\lg{n}\)%20) 18 | 19 | ![](http://latex.codecogs.com/gif.latex?%0d%0a\\sum_{k=1}^n\\lg{k}%20\\ge%20\\lg{\\sqrt{n}^n}%20=%20\\frac{n}{2}\\lg{n}%20=%20O\(n\\lg{n}\)%20) 20 | 21 | ### Exercises 8.1-3 22 | *** 23 | Show that there is no comparison sort whose running time is linear for at least half of the n! inputs of length n. What about a fraction of 1/n of the inputs of length n? What about a fraction 1/2^n? 24 | 25 | ### `Answer` 26 | n!/2, n!/n, n!/(2^n) are smaller than 2^n only when n is small. 27 | 28 | ### Exercises 8.1-4 29 | *** 30 | You are given a sequence of n elements to sort. The input sequence consists of n/k subsequences, each containing k elements. The elements in a given subsequence are all smaller than the elements in the succeeding subsequence and larger than the elements in the preceding subsequence. Thus, all that is needed to sort the whole sequence of length n is to sort the k elements in each of the n/k subsequences. Show an Ω(n lg k) lower bound on the number of comparisons needed to solve this variant of the sorting problem. (Hint: It is not rigorous to simply combine the lower bounds for the individual subsequences.) 31 | 32 | ### `Answer` 33 | ![](http://latex.codecogs.com/gif.latex?%0d%0a\(k!\)^{n/k}%20\\le%202^h%20\\\\%0d%0a\\Rightarrow%20h%20\\ge%20\\lg\(k!\)^{n/k}%20\\\\%0d%0a%20%20%20%20%20=%20%20%20\(n/k\)\lg\(k!\)%20\\\\%0d%0a%20%20%20%20%20\\ge%20\(n/k\)k\\lg{k}%20\\\\%0d%0a%20%20%20%20%20=%20%20%20\\Omega\(n\\lg{k}\)) 34 | 35 | *** 36 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 37 | 38 | -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/8.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 8.2-1 2 | *** 3 | Using Figure 8.2 as a model, illustrate the operation of COUNTING-SORT on the array A = [6, 0, 2, 0, 1, 3, 4, 6, 1, 3, 2]. 4 | 5 | ### `Answer` 6 | ![](./repo/s1/1.png) 7 | 8 | 9 | ### Exercises 8.2-2 10 | *** 11 | Prove that COUNTING-SORT is stable. 12 | 13 | ### `Answer` 14 | COUNTING-SORT最后是从后面往前面扫,并且把遇到的每一个item放在同大小(key)的最后面的位子.所以不改变相对顺序. 15 | 16 | ### Exercises 8.2-3 17 | *** 18 | Suppose that the for loop header in line 9 of the COUNTING-SORT procedure is rewritten 19 | 20 | as 9 for j ← 1 to length[A] 21 | 22 | Show that the algorithm still works properly. Is the modified algorithm stable? 23 | 24 | ### `Answer` 25 | 可以正常工作,只是不stable. 26 | 27 | ### Exercises 8.2-4 28 | *** 29 | Describe an algorithm that, given n integers in the range 0 to k, preprocesses its input and then answers any query about how many of the n integers fall into a range [a...b] in O(1) time. Your algorithm should use Θ(n + k) preprocessing time. 30 | 31 | ### `Answer` 32 | 利用数组C,[a,b]间的个数是C[b]-C[a-1].(C[-1] = 0) 33 | 34 | [implementation](./exercise_code/integerQuery.cpp) 35 | 36 | *** 37 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 38 | 39 | -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/exercise_code/in_place_counting_sort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def in_place_counting_sort(items, k): 5 | C = [0] * k 6 | for e in items: 7 | C[e] += 1 8 | for i in range(1,k): 9 | C[i] += C[i-1] 10 | i = len(items) - 1 11 | while i >= 0: 12 | print items,C 13 | v = items[i] 14 | pos = C[v] - 1 15 | if i > pos: 16 | i -= 1 17 | elif v != items[pos]: 18 | items[i],items[pos] = items[pos],items[i] 19 | C[v] -= 1 20 | else: 21 | C[v] -= 1 22 | 23 | 24 | items = [2, 5, 3, 0, 2, 3, 0, 3]; 25 | print items 26 | print "sorting --------------" 27 | in_place_counting_sort(items, 6) 28 | print "sorting finishing -------------" 29 | print items 30 | -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/exercise_code/intergerQuery.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class IntegerQuery{ 9 | public: 10 | IntegerQuery(vector & data); 11 | int countInRange(int a, int b); 12 | private: 13 | vector countArray; 14 | int k; 15 | bool noData; 16 | }; 17 | 18 | 19 | IntegerQuery::IntegerQuery(vector & data){ 20 | noData = data.empty(); 21 | if(!noData){ 22 | k = *max_element(data.begin(), data.end()); 23 | countArray = vector (k + 1); 24 | for(auto & num: data){ 25 | ++countArray[num]; 26 | } 27 | for(int i = 1; i <= k; ++i){ 28 | countArray[i] += countArray[i - 1]; 29 | } 30 | } 31 | } 32 | 33 | int IntegerQuery::countInRange(int a, int b){ 34 | if(a > b || b < 0 || a > k || noData){ 35 | return 0; 36 | } 37 | int sum = a <= 0 ? countArray[0] : 0; 38 | 39 | sum += countArray[min(k, b)] - countArray[max(0, a - 1)]; 40 | return sum; 41 | } 42 | 43 | int main(){ 44 | vector test{0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}; 45 | IntegerQuery query(test); 46 | assert(query.countInRange(-1, 4) == 12); 47 | assert(query.countInRange(-2, -1) == 0); 48 | assert(query.countInRange(-3, 0) == 3); 49 | assert(query.countInRange(0,1) == 6); 50 | } 51 | -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/exercise_code/water-jugs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import random 4 | 5 | def match(reds, blues): 6 | if not reds: 7 | return 8 | r = random.randint(0,len(reds)-1) 9 | v = reds[r] 10 | smaller_red = [item for item in reds if item < v] 11 | larger_red = [item for item in reds if item > v] 12 | smaller_blue = [item for item in blues if item < v] 13 | larger_blue = [item for item in blues if item > v] 14 | print v,v 15 | match(smaller_red,smaller_blue) 16 | match(larger_red,larger_blue) 17 | 18 | reds = [3,2,1,5,4] 19 | blues = [2,3,5,1,4] 20 | match(reds, blues) -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C08-Sorting-in-Linear-Time/repo/s1/1.png -------------------------------------------------------------------------------- /C08-Sorting-in-Linear-Time/repo/s4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C08-Sorting-in-Linear-Time/repo/s4/1.png -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/9.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 9.1-1 2 | *** 3 | Show that the second smallest of n elements can be found with ![](http://latex.codecogs.com/gif.latex?n+\\lceil\\lg{n}\\rceil-2) 4 | comparisons in the worst case. (Hint: Also find the smallest element.) 5 | 6 | ### `Answer` 7 | [code](./exercise_code/second-smallest.cpp) tells everything! 8 | 9 | 想法大致是这样的:首先由下往上建一颗二叉树,每个节点保存一对的最小值,这样总共需要n-1次比较.这棵树的顶点是最小值.第二小元素肯定在生成顶点的路径上,因为第二小元素只会被最小元素击败,所以两节点肯定交手过一次.因为树的高度不过超过 10 | ![image](./repo/s1/gif-2.gif) 所以需要![image](./repo/s1/gif-2.gif) - 1 次比较.因此总共需要![image](./repo/s1/gif.gif) 11 | 12 | First we build a BST from bottom to top,each node contains the smaller one of a pair, we need n-1 comparisions to build BST. The top of this BST is minimum, then the second smallest must be in the path to generate the top. Because the second smallest can only be defeated by the smallest one. Because the height of BST does not exceed 13 | ![image](./repo/s1/gif-2.gif) so we need ![image](./repo/s1/gif-2.gif) - 1 comparisions.The total times is![image](./repo/s1/gif.gif) 14 | 15 | 16 | ### Exercises 9.1-2 17 | *** 18 | Show that ![image](./repo/s1/gif-3.gif) comparisons are necessary in the worst case to find both the maximum and minimum of n numbers. (Hint: Consider how many numbers are potentially either the maximum or minimum, and investigate how a comparison affects these counts.) 19 | 20 | ### `Answer` 21 | 22 | As mentioned before, if n is odd,then we need 23 | ![image](./repo/s1/gif-4.gif) 24 | 25 | If n is even,then we need 3n/2-2 26 | 27 | 28 | ![image](./repo/s1/gif-3.gif) is the same format. 29 | 30 | 31 | 32 | *** 33 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 34 | 35 | -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/9.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 9.2-1 2 | *** 3 | Show that in RANDOMIZED-SELECT, no recursive call is ever made to a 0-length array. 4 | ### `Answer` 5 | 答案很明显,假如划分的一边数组是空的,那么这个if语句条件是不会成立的,这个调用是不会被call的. 6 | 7 | It is obvious, if the array is empty, then the condition of if will not hold, it will definitely not be called. 8 | 9 | ### Exercises 9.2-2 10 | *** 11 | Argue that the indicator random variable ![image](./repo/s2/1.gif) and the value T(max(k - 1, n - k)) are independent. 12 | 13 | ### `Answer` 14 | 15 | 不论![image](./repo/s2/1.gif)取0还是1, T(max(k-1,n-k))是不会变的. 16 | 17 | No matter ![image](./repo/s2/1.gif) is 0 or 1, T(max(k-1,n-k))will not change. 18 | 19 | ### Exercises 9.2-3 20 | *** 21 | Write an iterative version of RANDOMIZED-SELECT. 22 | 23 | ### `Answer` 24 | 25 | [code](./exercise_code/randomized-select-iterative.cpp) tells everything! 26 | 27 | ### Exercises 9.2-4 28 | *** 29 | Suppose we use RANDOMIZED-SELECT to select the minimum element of the array A = {3, 2, 9, 0, 7, 5, 4, 8, 6, 1}. Describe a sequence of partitions that results in a worst-case performance of RANDOMIZED-SELECT. 30 | 31 | ### `Answer` 32 | - pivot **9** {3, 2, 0, 7, 5, 4, 8, 6, 1} 33 | - pivot **8** {3, 2, 0, 7, 5, 4, 6, 1} 34 | - pivot **7** {3, 2, 0, 5, 4, 6, 1} 35 | - pivot **6** {3, 2, 0, 5, 4, 1} 36 | - pivot **5** {3, 2, 0, 4, 1} 37 | - pivot **4** {3, 2, 0, 1} 38 | - pivot **3** {2, 0, 1} 39 | - pivot **2** {0, 1} 40 | - pivot **1** {0} 41 | - return 0 42 | 43 | *** 44 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 45 | 46 | -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/exercise_code/k-close2median.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import math 4 | 5 | def k_close2median(items, k): 6 | med = median(items) 7 | 8 | abs_items = [] 9 | result = [] 10 | for element in items: 11 | abs_items.append(abs(element-med)) 12 | 13 | threshold = select(abs_items, k-1) 14 | 15 | for i in range(len(items)): 16 | if abs_items[i] <= threshold: 17 | result.append(items[i]) 18 | return result 19 | 20 | 21 | def select(items, n): 22 | med = median(items) 23 | smaller = [item for item in items if item < med] 24 | larger = [item for item in items if item > med] 25 | 26 | if len(smaller) == n: 27 | return med 28 | elif len(smaller) > n: 29 | return select(smaller, n) 30 | else: 31 | return select(list(larger), n - len(smaller) - 1) 32 | 33 | def median(items): 34 | def median_index(n): 35 | if n % 2: 36 | return n // 2 37 | else: 38 | return n // 2 - 1 39 | 40 | def partition(items, element): 41 | i = 0 42 | 43 | for j in range(len(items) - 1): 44 | if items[j] == element: 45 | items[j], items[-1] = items[-1], items[j] 46 | 47 | if items[j] < element: 48 | items[i], items[j] = items[j], items[i] 49 | i += 1 50 | 51 | items[i], items[-1] = items[-1], items[i] 52 | 53 | return i 54 | 55 | def select(items, n): 56 | if len(items) <= 1: 57 | return items[0] 58 | 59 | medians = [] 60 | 61 | for i in range(0, len(items), 5): 62 | group = sorted(items[i:i + 5]) 63 | items[i:i + 5] = group 64 | median = group[median_index(len(group))] 65 | medians.append(median) 66 | 67 | pivot = select(medians, median_index(len(medians))) 68 | index = partition(items, pivot) 69 | 70 | if n == index: 71 | return items[index] 72 | elif n < index: 73 | return select(items[:index], n) 74 | else: 75 | return select(items[index + 1:], n - index - 1) 76 | 77 | return select(items[:], median_index(len(items))) 78 | 79 | 80 | 81 | array = [1,2,3,4,10,20,30] 82 | print k_close2median(array, 2) -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/exercise_code/k-quantile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import math 5 | 6 | def k_quantiles(items, k): 7 | index = median_index(len(items)) 8 | 9 | if k == 1: 10 | return [] 11 | elif k % 2: 12 | n = len(items) 13 | left_index = math.ceil((k // 2) * (n / k)) - 1 14 | right_index = n - left_index - 1 15 | 16 | left = select(items, left_index) 17 | right = select(items, right_index) 18 | 19 | partition(items, left) 20 | lower = k_quantiles(items[:left], k // 2) 21 | partition(items, right) 22 | upper = k_quantiles(items[right + 1:], k // 2) 23 | 24 | return lower + [left, right] + upper 25 | else: 26 | index = median_index(len(items)) 27 | median = select(items, index) 28 | partition(items, median) 29 | 30 | return k_quantiles(items[:index], k // 2) + [median] + k_quantiles(items[index + 1:], k // 2) 31 | 32 | def median_index(n): 33 | if n % 2: 34 | return n // 2 35 | else: 36 | return n // 2 - 1 37 | 38 | def partition(items, element): 39 | i = 0 40 | 41 | for j in range(len(items) - 1): 42 | if items[j] == element: 43 | items[j], items[-1] = items[-1], items[j] 44 | 45 | if items[j] < element: 46 | items[i], items[j] = items[j], items[i] 47 | i += 1 48 | 49 | items[i], items[-1] = items[-1], items[i] 50 | 51 | return i 52 | 53 | def select(items, n): 54 | if len(items) <= 1: 55 | return items[0] 56 | 57 | medians = [] 58 | 59 | for i in range(0, len(items), 5): 60 | group = sorted(items[i:i + 5]) 61 | items[i:i + 5] = group 62 | median = group[median_index(len(group))] 63 | medians.append(median) 64 | 65 | pivot = select(medians, median_index(len(medians))) 66 | index = partition(items, pivot) 67 | 68 | if n == index: 69 | return items[index] 70 | elif n < index: 71 | return select(items[:index], n) 72 | else: 73 | return select(items[index + 1:], n - index - 1) 74 | 75 | 76 | arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18] 77 | print k_quantiles(arr, 4) 78 | 79 | -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/exercise_code/randomized-select-iterative.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: randomized-select-iterative.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Sun May 24 11:46:39 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | class Solution { 13 | 14 | int partition(int arr[], int l, int r) { 15 | int x = arr[r], i = l; 16 | for(int j = l; j <= r - 1; j++) { 17 | if (arr[j] <= x) { 18 | swap(arr[i], arr[j]); 19 | i++; 20 | } 21 | } 22 | swap(arr[i], arr[r]); 23 | return i; 24 | } 25 | 26 | int randomPartition(int arr[], int l, int r) { 27 | int n = r-l+1; 28 | int pivot = rand() % n; 29 | swap(arr[l + pivot], arr[r]); 30 | return partition(arr, l, r); 31 | } 32 | 33 | public: 34 | 35 | int kthSmallest(int arr[], int l, int r, int k) { 36 | int originalK = k; 37 | while (k > 0 && k <= r - l + 1) { 38 | int pos = randomPartition(arr, l, r); 39 | if (pos-l == k-1) { 40 | return arr[pos]; 41 | } else if(pos-l > k-1) { 42 | r = pos-1; 43 | } else { 44 | l = pos+1; 45 | k = originalK-l; 46 | } 47 | } 48 | return INT_MAX; 49 | } 50 | 51 | }; 52 | 53 | int main() { 54 | int arr[7] = {10, 100, 2, 4, 1, -2, 8}; 55 | Solution s; 56 | assert(s.kthSmallest(arr, 0, 6, 1) == -2); 57 | assert(s.kthSmallest(arr, 0, 6, 2) == 1); 58 | assert(s.kthSmallest(arr, 0, 6, 3) == 2); 59 | assert(s.kthSmallest(arr, 0, 6, 4) == 4); 60 | assert(s.kthSmallest(arr, 0, 6, 5) == 8); 61 | assert(s.kthSmallest(arr, 0, 6, 6) == 10); 62 | assert(s.kthSmallest(arr, 0, 6, 7) == 100); 63 | } 64 | -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/minmax.c: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: minmax.c 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Sat May 23 23:04:35 2015 7 | ************************************************************************/ 8 | #include 9 | 10 | #define maxf(a,b) ((a) >= (b) ? (a) : (b)) 11 | #define minf(a,b) ((a) <= (b) ? (a) : (b)) 12 | 13 | void minmax(int *arr, int n, int *maximum, int *minium) 14 | { 15 | int i = 0; 16 | if(n % 2 == 1) 17 | { 18 | *maximum = arr[0]; 19 | *minium = arr[0]; 20 | i = 1; 21 | } else { 22 | if(arr[1] >= arr[0]) 23 | { 24 | *maximum = arr[1]; 25 | *minium = arr[0]; 26 | } else { 27 | *maximum = arr[0]; 28 | *minium = arr[1]; 29 | } 30 | i = 2; 31 | } 32 | 33 | for(;i < n;i += 2) 34 | { 35 | if(arr[i] >= arr[i+1]) 36 | { 37 | *maximum = maxf(*maximum, arr[i]); 38 | *minium = minf(*minium, arr[i+1]); 39 | } else { 40 | *maximum = maxf(*maximum, arr[i+1]); 41 | *minium = minf(*minium, arr[i]); 42 | } 43 | } 44 | } 45 | 46 | int main() 47 | { 48 | int arr[5] = {3,5,-1,0,2}; 49 | int maximum = 0,minium = 0; 50 | minmax(arr, 5, &maximum, &minium); 51 | printf("max=%d min=%d/n", maximum, minium); 52 | } 53 | -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/problems/i-largest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from Queue import PriorityQueue 5 | 6 | def sort1(items, i): 7 | items = sorted(items,reverse=True) 8 | return items[:i] 9 | 10 | def sort2(items, i): 11 | pq = PriorityQueue() 12 | for element in items: 13 | pq.put((-element, element)) 14 | array = [] 15 | for k in range(i): 16 | array.append(pq.get()[1]) 17 | return array 18 | 19 | 20 | 21 | items = [3,0,7,8,-2,12] 22 | print sort1(items, 3) 23 | print sort2(items, 3) -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/randomized-select.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: randomized-select.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Sun May 24 11:46:39 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | class Solution { 13 | 14 | int kthSmallest(vector& arr, int l, int r, int k) 15 | { 16 | 17 | if (k > 0 && k <= r - l + 1) 18 | { 19 | int pos = randomPartition(arr, l, r); 20 | 21 | if (pos-l == k-1) 22 | return arr[pos]; 23 | else if(pos-l > k-1) 24 | return kthSmallest(arr, l, pos-1, k); 25 | else 26 | return kthSmallest(arr, pos+1, r, k-pos+l-1); 27 | } 28 | return INT_MAX; 29 | } 30 | 31 | int partition(vector& arr, int l, int r) 32 | { 33 | int x = arr[r], i = l; 34 | for(int j = l; j <= r - 1; j++) 35 | { 36 | if (arr[j] <= x) 37 | { 38 | swap(arr[i], arr[j]); 39 | i++; 40 | } 41 | } 42 | swap(arr[i], arr[r]); 43 | return i; 44 | } 45 | 46 | int randomPartition(vector& arr, int l, int r) 47 | { 48 | int n = r-l+1; 49 | int pivot = rand() % n; 50 | swap(arr[l + pivot], arr[r]); 51 | return partition(arr, l, r); 52 | } 53 | 54 | public: 55 | int findKthLargest(vector& nums, int k) { 56 | return kthSmallest(nums, 0, nums.size()-1, nums.size()-k+1); 57 | } 58 | }; 59 | 60 | int main() 61 | { 62 | int arr[5] = {2,4,0,-2,8}; 63 | vectorv(arr, arr+5); 64 | Solution s; 65 | cout << s.findKthLargest(v, 2) << endl; 66 | } -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/oil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/oil.png -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/p/o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/p/o.png -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s1/gif-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s1/gif-1.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s1/gif-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s1/gif-2.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s1/gif-3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s1/gif-3.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s1/gif-4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s1/gif-4.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s1/gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s1/gif.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s2/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s2/1.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s3/1.png -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s3/2.png -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s3/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s3/3.gif -------------------------------------------------------------------------------- /C09-Medians-and-Order-Statistics/repo/s3/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C09-Medians-and-Order-Statistics/repo/s3/4.gif -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/README.md: -------------------------------------------------------------------------------- 1 | Problem 10.2 & 10.3 remain 2 | -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/exercise_code/af-obj.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_SIZE 10 5 | 6 | typedef int list_t; 7 | typedef int obj_t; 8 | 9 | int empty_list = -1; 10 | int cells[MAX_SIZE * 3]; 11 | int free_list; 12 | 13 | #define NEXT(i) cells[(i) + 1] 14 | #define PREV(i) cells[(i) + 2] 15 | #define KEY(i) cells[i] 16 | 17 | void init_storage() { 18 | int i; 19 | for (i = 0; i < (MAX_SIZE - 1) * 3; i += 3) 20 | NEXT(i) = i + 3; 21 | 22 | NEXT(i) = -1; 23 | free_list = 0; 24 | } 25 | 26 | list_t allocate_object() { 27 | if (free_list == -1) { 28 | fprintf(stderr, "Storage depleted\n"); 29 | exit(1); 30 | } 31 | 32 | list_t new = free_list; 33 | free_list = NEXT(free_list); 34 | return new; 35 | } 36 | 37 | void free_object(list_t list) { 38 | NEXT(list) = free_list; 39 | free_list = list; 40 | } 41 | 42 | list_t cons(obj_t key, list_t list) { 43 | list_t new = allocate_object(); 44 | 45 | NEXT(new) = list; 46 | PREV(new) = empty_list; 47 | KEY(new) = key; 48 | 49 | if (list != empty_list) { 50 | PREV(list) = new; 51 | } 52 | 53 | return new; 54 | } 55 | 56 | void delete(list_t list) { 57 | if (PREV(list) != empty_list) { 58 | NEXT(PREV(list)) = NEXT(list); 59 | } 60 | 61 | if (NEXT(list) != empty_list) { 62 | PREV(NEXT(list)) = PREV(list); 63 | } 64 | 65 | free_object(list); 66 | } 67 | 68 | obj_t get(list) { 69 | if (list == empty_list) return -1; 70 | return KEY(list); 71 | } 72 | 73 | list_t next(list) { 74 | if (list == empty_list) return -1; 75 | return NEXT(list); 76 | } 77 | 78 | int main() 79 | { 80 | init_storage(); 81 | list_t new_list = cons(5, empty_list); 82 | new_list = cons(4, new_list); 83 | printf("%d\n", get(new_list)); 84 | printf("%d\n", get(next(new_list))); 85 | delete(new_list); 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/exercise_code/deque.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | class Deque { 9 | 10 | private: 11 | vector data_; 12 | int size_; 13 | int head_; 14 | int tail_; 15 | int capacity_; 16 | 17 | public: 18 | 19 | Deque(int size) : size_(0), head_(0), tail_(size-1), capacity_(size), data_(size) {} 20 | 21 | void push_front(T v) { 22 | assert(head_ <= tail_); 23 | data_[head_++] = v; 24 | size_++; 25 | } 26 | 27 | void push_back(T v) { 28 | assert(head_ <= tail_); 29 | data_[tail_--] = v; 30 | size_++; 31 | } 32 | 33 | void pop_front() { 34 | assert(head_ > 0); 35 | head_--; 36 | size_--; 37 | } 38 | 39 | void pop_back() { 40 | assert(tail_ < capacity_); 41 | tail_++; 42 | size_--; 43 | } 44 | 45 | T front() const { 46 | assert(head_ > 0); 47 | return data_[head_-1]; 48 | } 49 | 50 | T back() const { 51 | assert(tail_ < capacity_-1); 52 | return data_[tail_+1]; 53 | } 54 | 55 | int size() const { return size_; } 56 | 57 | int empty() const { return size_ == 0; } 58 | 59 | 60 | ~Deque() {} 61 | }; 62 | 63 | int main() { 64 | Deque mydeque(3); 65 | mydeque.push_front(1); 66 | mydeque.push_back(3); 67 | cout << mydeque.front() << " " << mydeque.back() << endl; 68 | cout << mydeque.size(); 69 | } 70 | -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/exercise_code/deque.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | class Deque: 5 | 6 | def __init__(self, size): 7 | self.N = 0 8 | self.head = 0 9 | self.tail = size-1 10 | self.array = [0]*size 11 | self.size = size 12 | 13 | def addFirst(self, item): 14 | self.array[self.head] = item 15 | self.N += 1 16 | self.head = (self.head+1)%self.size 17 | 18 | def addLast(self, item): 19 | self.array[self.tail] = item 20 | self.N += 1 21 | self.tail = (self.tail-1)%self.size 22 | 23 | def removeFirst(self): 24 | self.N -= 1 25 | self.head = (self.head-1)%self.size 26 | v = self.array[self.head] 27 | return v 28 | 29 | def removeLast(self): 30 | self.N -= 1 31 | self.tail = (self.tail+1)%self.size 32 | v = self.array[self.tail] 33 | return v 34 | 35 | def seeAll(self): 36 | print self.head,self.tail,self.N 37 | print self.array 38 | 39 | myqueue = Deque(10) 40 | myqueue.addFirst(2) 41 | myqueue.addFirst(3) 42 | myqueue.addFirst(4) 43 | myqueue.addLast(5) 44 | myqueue.addLast(6) 45 | myqueue.addLast(6) 46 | myqueue.seeAll() 47 | print myqueue.removeLast() 48 | print myqueue.removeFirst() -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/exercise_code/dict.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: dict.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Tue Jul 7 21:43:43 2015 7 | ************************************************************************/ 8 | #include 9 | using namespace std; 10 | 11 | 12 | struct node_t { 13 | int key; 14 | struct node_t *next; 15 | }; 16 | 17 | struct list_t{ 18 | struct node_t nil; 19 | }; 20 | 21 | void init_list(list_t *list) { 22 | list->nil.key = 0; 23 | list->nil.next = &(list->nil); 24 | } 25 | 26 | void destroy_list(list_t *list) { 27 | node_t *node = list->nil.next; 28 | node_t *next; 29 | 30 | while (node != &(list->nil)) { 31 | next = node->next; 32 | free(node); 33 | node = next; 34 | } 35 | } 36 | 37 | void insert(list_t *list, int key) { 38 | node_t *newnode = (node_t *) malloc(sizeof(node_t)); 39 | newnode->key = key; 40 | newnode->next = list->nil.next; 41 | list->nil.next = newnode; 42 | } 43 | 44 | node_t *search(list_t *list, int key) { 45 | node_t *node = list->nil.next; 46 | list->nil.key = key; 47 | 48 | while (node->key != key) { 49 | node = node->next; 50 | } 51 | 52 | if (node == &(list->nil)) { 53 | return NULL; 54 | } else { 55 | return node; 56 | } 57 | } 58 | 59 | void del(list_t *list, int key) { 60 | node_t *node = &(list->nil); 61 | 62 | while (node->next != &(list->nil)) { 63 | if (node->next->key == key) { 64 | node_t *to_be_deleted = node->next; 65 | node->next = node->next->next; 66 | free(to_be_deleted); 67 | } else { 68 | node = node->next; 69 | } 70 | } 71 | } 72 | 73 | int main() 74 | { 75 | list_t *mydict = new list_t; 76 | init_list(mydict); 77 | insert(mydict, 2); 78 | insert(mydict, 3); 79 | insert(mydict, 4); 80 | node_t *tmp = search(mydict, 3); 81 | cout << tmp->key; 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/exercise_code/traversal.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: travelsal.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Mon Aug 10 19:04:08 2015 7 | ************************************************************************/ 8 | #include 9 | using namespace std; 10 | 11 | struct tree_t { 12 | struct tree_t *left; 13 | struct tree_t *right; 14 | struct tree_t *parent; 15 | int key; 16 | tree_t() {left = 0; right = 0; parent = 0;} 17 | }; 18 | 19 | void print_tree(tree_t *tree) { 20 | tree_t *prev; 21 | prev = 0; 22 | 23 | while (tree) { 24 | if (prev == tree->parent) { 25 | cout << tree->key << endl; 26 | prev = tree; 27 | tree = tree->left ? tree->left : 28 | tree->right ? tree->right : 29 | tree->parent; 30 | } else if (prev == tree->left && tree->right) { 31 | prev = tree; 32 | tree = tree->right; 33 | } else { 34 | prev = tree; 35 | tree = tree->parent; 36 | } 37 | } 38 | } 39 | 40 | 41 | int main() { 42 | tree_t root; 43 | root.key = 1; 44 | 45 | tree_t left; 46 | left.key = 2; 47 | 48 | tree_t right; 49 | right.key = 3; 50 | 51 | root.left = &left; 52 | root.right = &right; 53 | left.parent = &root; 54 | right.parent = &root; 55 | 56 | print_tree(&root); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /C10-Elementary-Data-Structures/repo/s4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C10-Elementary-Data-Structures/repo/s4/1.png -------------------------------------------------------------------------------- /C11-Hash-Tables/11.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 11.1-1 2 | *** 3 | Suppose that a dynamic set S is represented by a direct-address table T of length m. Describe a procedure that finds the maximum element of S. What is the worst-case performance of your procedure? 4 | 5 | 6 | ### `Answer` 7 | 遍历整个table. 最坏情况是O(m) 8 | 9 | 10 | ### Exercises 11.1-2 11 | *** 12 | A **bit vector** is simply an array of bits (0's and 1's). A bit vector of length m takes much less space than an array of m pointers. Describe how to use a bit vector to Represent a Dynamic Set of Distinct Elements with no Satellite Data. Dictionary Operations Should Run in O(1) Time. 13 | 14 | ### `Answer` 15 | 用来表示整数. 1表示该数在集合中,0表示不在集合中. 16 | 17 | ### Exercises 11.1-3 18 | *** 19 | Suggest how to implement a direct-address table in which the keys of stored elements do not need to be distinct and the elements can have satellite data. All three dictionary operations (INSERT, DELETE, and SEARCH) should run in O(1) time. (Don't forget that DELETE takes as an argument a pointer to an object to be deleted, not a key.) 20 | 21 | ### `Answer` 22 | 将每个key分别映射到一个 doubly linked list。 23 | 24 | ### Exercises 11.1-4 25 | *** 26 | We wish to implement a dictionary by using direct addressing on a huge array. At the start, the array entries may contain garbage, and initializing the entire array is impractical because of its size. Describe a scheme for implementing a direct-address dictionary on a huge array. Each stored object should use O(1) space; the operations SEARCH, INSERT, and DELETE should take O(1) time each; and the initialization of the data structure should take O(1) time. (Hint: Use an additional stack, whose size is the number of keys actually stored in the dictionary, to help determine whether a given entry in the huge array is valid or not.) 27 | 28 | ### `Answer` 29 | > 根据提示我们需要一个额外的栈,这个栈用于存储指向大数组中元素的指针,同时大数组的元素是对应栈的下标(top的值)。 30 | 31 | - 向数组中插入时,我们将数组的地址入栈,并将大数组的元素初始化为对应的栈顶指针。 32 | - 执行查找操作时,我们首先通过直接寻址在数组中查找值,然后判断数组元素是不是合法的栈的下标,如果是合法的,那么查找成功,反之,字典中无该元素,返回NULL。 33 | - 执行删除操作时,删除元素后栈中会产生空洞,我们可以通过将栈顶元素和其对应的大数组中存储的栈的下标来填补到产生的这个空洞中,然后再执行出栈操作即可。 34 | 35 | 36 | *** 37 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 38 | 39 | -------------------------------------------------------------------------------- /C11-Hash-Tables/11.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 11.2-1 2 | *** 3 | Suppose we use a hash function h to hash n distinct keys into an array T of length m. Assuming simple uniform hashing, what is the expected number of collisions? More precisely, what is the expected cardinality of {{k, l} : k ≠ l and h(k) = h(l)}? 4 | 5 | 6 | ### `Answer` 7 | ![](http://latex.codecogs.com/gif.latex?%20C_n^2%20\\cdot%20\\frac{1}{m}) 8 | 9 | 10 | ### Exercises 11.2-2 11 | *** 12 | Demonstrate the insertion of the keys 5, 28, 19, 15, 20, 33, 12, 17, 10 into a hash table with collisions resolved by chaining. Let the table have 9 slots, and let the hash function be h(k) = k mod 9. 13 | 14 | ### `Answer` 15 | ![](./repo/s1/1.png) 16 | 17 | ### Exercises 11.2-3 18 | *** 19 | Professor Marley hypothesizes that substantial performance gains can be obtained if we modify the chaining scheme so that each list is kept in sorted order. How does the professor's modification affect the running time for successful searches, unsuccessful searches, insertions, and deletions? 20 | 21 | ### `Answer` 22 | * successful searches:没有影响 23 | * unsuccessful searches:当数据量大可以加速,可以提前判断元素是否在区间内 24 | * insertions:降低了插入的速度,需要遍历链表插入在合适的位置 25 | * deletions:没有影响 26 | 27 | ### Exercises 11.2-4 28 | *** 29 | Suggest how storage for elements can be allocated and deallocated within the hash table itself by linking all unused slots into a free list. Assume that one slot can store a flag and either one element plus a pointer or two pointers. All dictionary and free-list operations should run in O(1) expected time. Does the free list need to be doubly linked, or does a singly linked free list suffice? 30 | 31 | ### `Answer` 32 | 需要双链表.每个slot有一个标识标识是否已分配,如果没有分配指针指向free list的属于自己的那个位置. 删除的时候将标志位清一下,将自己加入链表头,指针指向头;插入时根据指针去取. 33 | 34 | ### Exercises 11.2-5 35 | *** 36 | Show that if |U| > nm, there is a subset of U of size n consisting of keys that all hash to the 37 | same slot, so that the worst-case searching time for hashing with chaining is Θ(n). 38 | 39 | 40 | ### `Answer` 41 | 如果|U| = nm,假设U的全集要均匀分到m个位置上,每个位置期望就有n个元素,因此至少有一个位置是有至少n个元素的,我们选取这个集合,查找操作需要的时间就是Θ(n). 42 | 43 | 44 | *** 45 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 46 | 47 | -------------------------------------------------------------------------------- /C11-Hash-Tables/11.5.md: -------------------------------------------------------------------------------- 1 | ### Exercises 11.5-1 2 | *** 3 | Suppose that we insert n keys into a hash table of size m using open addressing and uniform hashing. Let p(n, m) be the probability that no collisions occur. Show that p(n, m) ≤ e^(-n(n-1)/2m). (Hint: See equation (3.11).) Argue that when n exceeds sqrt(m), the probability of avoiding collisions goes rapidly to zero. 4 | 5 | 6 | ### `Answer` 7 | 下面采用数学归纳法证明p(n,m) ≤ e^((-n(n-1))/2m),1≤n≤m: 8 | 9 | 1).当n=1时,因为只有一个关键字不会有冲突,所以p(1,m)=1 ≤ e^((-1(1-1))/2m) = 1成立; 10 | 11 | 2).假设n=k时,p(k,m) ≤ e^((-k(k-1))/2m),k < m-1成立。 12 | 13 | 因为第k+1个关键字的探查序列等可能为0,1,…,m-1的所有排列中的任何一种,所以第k+1个关键字的探查序列的第一个探查位置h(k+1,0)等可能为0,1,…,m-1中的任何一个。故在前k个关键字无冲突的条件下,第k+1个关键字的探查序列的第一个探查位置,h(k+1,0)不与前面的k个关键字中的任何一个关键字冲突,那么这k+1个关键字也没有冲突。 14 | 15 | 所以: 16 | 17 | p(k+1,m) = p(k,m)*(m-k)/m 18 | 19 | ≤ e^((-k(k-1))/2m)*(1-k.m) 20 | 21 | ≤ e^((-k(k-1))/2m) * e^(-k/m) 22 | 23 | = e^((-(k+1)k)/2m) 24 | 25 | 即p(k+1,m) = e^((-(k+1)k)/2m)。 26 | 27 | 3)综上,p(n,m) ≤ e^((-n(n-1))/2m),对于1≤n≤m成立。 28 | 29 | 30 | *** 31 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 32 | 33 | -------------------------------------------------------------------------------- /C11-Hash-Tables/README.md: -------------------------------------------------------------------------------- 1 | UNSOLVED 2 | 3 | [11.3.5](./11.3.md#exercises-113-5) 4 | [11.3.6](./11.3.md#exercises-113-6) 5 | 6 | [11.5.1](./11.5.md#exercises-115-1) 7 | -------------------------------------------------------------------------------- /C11-Hash-Tables/problem.md: -------------------------------------------------------------------------------- 1 | ### Problems 1 : Longest-probe bound for hashing 2 | *** 3 | A hash table of size m is used to store n items, with n ≤ m/2. Open addressing is used for collision resolution. 4 | 5 | **a.**Assuming uniform hashing, show that for i=1,2,…,n, the probability is at most 2^−k that the ith insertion requires strictly more than k probes. 6 | 7 | 8 | **b.**Show that for i=1,2,…,n, the probability is O(1/n^2) that the ith insertion requires more than 2lgn probes. 9 | 10 | Let the random variable Xi denote the number of probes required by the ith insertion. You have shown in part (b) that 11 | ![](http://latex.codecogs.com/gif.latex?%0d%0a\\Pr\\{X_i%20>%202\\lg{n}\\}%20=%0d%0aO\(1/n^2\)%20) 12 | . Let the random variable 13 | ![](http://latex.codecogs.com/gif.latex?%0d%0aX%20=%20max_{1%20\\le%20i%20\\le%20n}X_i) 14 | denote the maximum number of probes required by any of the n insertions. 15 | 16 | **c.**Show that Pr{X > 2lgn}=O(1/n). 17 | 18 | **d.**Show that the expected length E[X] of the longest probe sequence is O(lgn). 19 | 20 | ### `Answer` 21 | **a.** 22 | 23 | P = (n/m)^k < (1/2)^k = 2^-k 24 | 25 | **b.** 26 | 27 | 代入a中的结论即可 28 | 29 | **c.** 30 | 31 | ![](http://latex.codecogs.com/gif.latex?P%20=%20\\prod_{i=0}^{2\\lg{n}}\\frac{m/2-i}{m}%20<%20\\prod_{i=0}^{2\\lg{n}}%20\\frac{1}{2}%20=%20\\frac{1}{2}^{2\\lg{n}}%20=%20\\frac{1}{4}^{\\lg{n}}%20=%204^{\\lg{n^{-1}}}%20=%20O\(n^{-1}\)%20) 32 | 33 | **d.** 34 | 35 | 该题可以参考5.4.2节的关于**球与盒子**的结论和5.4.3节的关于**序列**的结论. 36 | 37 | 我们把每次的概率放大为1/2(实际上是≤ 1/2的) 38 | 39 | 所以是O(lgn) 40 | 41 | 42 | 43 | ### Problems 2 : Slot-size bound for chaining 44 | *** 45 | Suppose that we have a hash table with n slots, with collisions resolved by chaining, and suppose that n keys are inserted into the table. Each key is equally likely to be hashed to each slot. Let M be the maximum number of keys in any slot after all the keys have been inserted. Your mission is to prove an O(lg n/lg lg n) upper bound on E[M], the expected value of M. 46 | 47 | **a.** 48 | Argue that the probability Qk that exactly k keys hash to a particular slot is given by 49 | 50 | ![](http://latex.codecogs.com/gif.latex?%20Q_k%20=%20\(\\frac{1}{n}^k%20\)%20\(1-\\frac{1}{n}\)^{n-k}%20C_k^n) 51 | 52 | 53 | ### `Answer` 54 | 55 | 56 | 57 | *** 58 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 59 | 60 | -------------------------------------------------------------------------------- /C11-Hash-Tables/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C11-Hash-Tables/repo/s1/1.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/12.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 12.1-1 2 | *** 3 | For the set of keys {1, 4, 5, 10, 16, 17, 21}, draw binary search trees of height 2, 3, 4, 5, and 6. 4 | 5 | ### `Answer` 6 | ![image](./repo/s1/1.png)1 7 | 8 | 9 | ### Exercises 12.1-2 10 | *** 11 | What is the difference between the binary-search-tree property and the min-heap property (see page 129)? Can the min-heap property be used to print out the keys of an n-node tree in sorted order in O(n) time? Explain how or why not. 12 | 13 | ### `Answer` 14 | 做不到,因为基于比较的排序的上限是nlgn。堆排序建堆时间是 O(n), 但是每次 拿出去后要用 lg n 的时间去调整。 15 | 16 | It is impossible. Because the lower bound based on comparision is nlgn. Although it takes O(n) to build a heap. But each time we take the top, we have to adjust the heap whcih takes O(lgn) time. 17 | 18 | 19 | ### Exercises 12.1-3 20 | *** 21 | Give a nonrecursive algorithm that performs an inorder tree walk. (Hint: There is an easy solution that uses a stack as an auxiliary data structure and a more complicated but elegant solution that uses no stack but assumes that two point- ers can be tested for equality.) 22 | 23 | ### `Answer` 24 | ![image](./repo/s1/2.png) 25 | 26 | 27 | ### Exercises 12.1-4 28 | *** 29 | Give recursive algorithms that perform preorder and postorder tree walks in Θ (n) time on a tree of n nodes. 30 | 31 | ### `Answer` 32 | ![image](./repo/s1/3.png) 33 | 34 | ### Exercises 12.1-5 35 | *** 36 | Argue that since sorting n elements takes Ω(nlgn) time in the worst case in the comparison model, any comparison-based algorithm for constructing a binary search tree from an arbitrary list of n elements takes Ω(nlgn) time in the worst case. 37 | 38 | ### `Answer` 39 | 如果下界不是nlgn, 就会产生矛盾。我们之前知道可以用 O(n) 的时间按序遍历输 出 BST 中的元素,如果基于比较的 BST 构造下界不是 n lg n, 那我们就可以利用这 个方法产生基于比较的速度优于 n lg n 的排序算法,矛盾. 40 | 41 | If it is not O(nlgn), we can find a conflict. We know it takes O(n) time to inorder print elements in a BST. If the lower bound in the worst case in the comparison model is better than O(nlgn), then we can utilize this to give a better algorithm. 42 | 43 | *** 44 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 45 | 46 | -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/12.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 12.3-1 2 | *** 3 | Give a recursive version of the TREE-INSERT procedure. 4 | 5 | ### `Answer` 6 | ![image](./repo/s3/1.png) 7 | 8 | 9 | ### Exercises 12.3-2 10 | *** 11 | Suppose that a binary search tree is constructed by repeatedly inserting distinct values into the tree. Argue that the number of nodes examined in searching for a value in the tree is one plus the number of nodes examined when the value was first inserted into the tree. 12 | 13 | ### `Answer` 14 | 多检查一次是否相等. 15 | 16 | We should check one more time of this node, obviously. 17 | 18 | ### Exercises 12.3-3 19 | *** 20 | We can sort a given set of n numbers by first building a binary search tree containing these numbers (using TREE-INSERT repeatedly to insert the numbers one by one) and then printing the numbers by an inorder tree walk. What are the worst-case and best-case running times for this sorting algorithm? 21 | 22 | ### `Answer` 23 | 退化成链表就是最坏情况. 24 | 25 | If it's Degenerated into a list, then the worst situation. 26 | 27 | 28 | ### Exercises 12.3-4 29 | Suppose that another data structure contains a pointer to a node y in a binary search tree, and suppose that y's predecessor z is deleted from the tree by the procedure TREE-DELETE. What problem can arise? How can TREE-DELETE be rewritten to solve this problem? 30 | ### `Answer` 31 | 当要删除的节点有两个子节点时,节点y会被删除. 如果指向的是节点y,那么就出问题的.在这种情况下应该修改成指向节点z. 32 | 33 | If the node being deleted has two child nodes, then y will be deleted. If the pointer point to y, there will be problem. Under such situation, the pointer should point to node z. 34 | 35 | 36 | ### Exercises 12.3-5 37 | *** 38 | Is the operation of deletion "commutative" in the sense that deleting x and then y from a binary search tree leaves the same tree as deleting y and then x? Argue why it is or give a counterexample. 39 | 40 | ### `Answer` 41 | NO. 42 | ![image](./repo/s3/2.png) 43 | 44 | 45 | ### Exercises 12.3-6 46 | *** 47 | When node z in TREE-DELETE has two children, we could splice out its predecessor rather than its successor. Some have argued that a fair strategy, giving equal priority to predecessor and successor, yields better empirical performance. How might TREE-DELETE be changed to implement such a fair strategy? 48 | 49 | ### `Answer` 50 | 51 | * Randomly choose one 52 | * Assign each node with an attribute **height**, choose the higher one. 53 | 54 | 55 | 56 | 57 | *** 58 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 59 | 60 | -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/12.4.md: -------------------------------------------------------------------------------- 1 | ### Exercises 12.4-1 2 | *** 3 | Prove equation (12.3). 4 | 5 | ### `Answer` 6 | This is basic property of permutations and combinations. You can use Pascal triangle to prove 7 | ![](http://latex.codecogs.com/gif.latex?%20%0d%0a\\mathrm{C}_n^k+\\mathrm{C}_n^{k-1}%20=%20\\mathrm{C}_{n+1}^{k}) 8 | 9 | 10 | ### Exercises 12.4-2 11 | *** 12 | Describe a binary search tree on n nodes such that the average depth of a node in the tree is Θ(lg n) but the height of the tree is w(lg n). Give an asymptotic upper bound on the height of an n-node binary search tree in which the average depth of a node is Θ(lg n). 13 | 14 | ### `Answer` 15 | 满二叉树就满足n个节点平均高度为 Θ(lg n), 树高 lg n (w = 1) 16 | 17 | 渐进上界为 Θ(lg n) 18 | 19 | 20 | ### Exercises 12.4-3 21 | *** 22 | Show that the notion of a randomly chosen binary search tree on n keys, where each binary search tree of n keys is equally likely to be chosen, is different from the notion of a randomly built binary search tree given in this section. 23 | 24 | ### `Answer` 25 | a randomly built binary search tree, 随机构建二叉搜索树, 指的是构建过程的随机, 也就是通过依次插入的方式构建采用的初始序列随机, 这个序列有 n! 种排列方式, 因此随机构建的过程有 n! 种不同的情况 26 | 27 | a randomly chosen binary search tree, 随机选择二叉搜索树, 指的是对于 n 个元素构成的所有二叉树进行选择的过程随机, 由于随机构建过程的初始序列没有任何要求, 因此排列情况是 n! 种, 而二叉搜索树要求有一定的大小关系 (一个节点的左孩子关键字不大于该节点关键字, 右孩子关键字不小于该节点关键字), 这意味着 n 个元素构成的二叉搜索树的个数肯定小于等于 n! (等号只在 n = 1 时取得) 28 | 29 | 30 | ### Exercises 12.4-4 31 | Show that the function f(x) = 2^x is convex. 32 | ### `Answer` 33 | 首先, 有 (a + b)^2 = a^2 + b^2 + 2ab >= 4ab (等号仅在 a = b时取得) 34 | 35 | 设 x1 < x2, 有 (2^x1 + 2^x2)^2 / 4 > 2^(x1 + x2) 36 | 37 | 因此, (2^x1 + 2^x2) / 2 > 2^[(x1 + x2) / 2] 38 | 39 | 因此 f(x) = 2^x 是严格凸的 40 | 41 | 42 | ### Exercises 12.4-5 43 | *** 44 | Consider RANDOMIZED-QUICKSORT operating on a sequence of n distinct input numbers. Prove that for any constant k > 0, all but O(1/(n^k)) of the n! input permutations yield an O(nlgn) running time. 45 | 46 | ### `Answer` 47 | 欲证明题等价于: n! 种输入排列运行时间不是 O(nlgn) 的排列个数 p(n) 一定满足 O(1/(n^k)) (对任意常数 k > 0 成立) 48 | 49 | 根据渐进上界的定义, 存在 c > 0 和 n0 > 0, 使得对所有 n >= n0, 有 0 <= p(n) <= c/(n^k) (任意常数 k > 0) 50 | 51 | 因此, p(n) 一定是常数 52 | 53 | 又因为只有当输入序列有序(最坏情况)时, 排序所需时间不为 O(nlgn), 这种排列只有常数个 54 | 55 | 56 | 57 | *** 58 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 59 | 60 | -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: main.cpp 4 | > Author: Louis1992 5 | > Mail: zhenchaogan@gmail.com 6 | > Blog: http://gzc.github.io 7 | > Created Time: Sun May 3 00:05:14 2015 8 | ************************************************************************/ 9 | 10 | #include "BSTree.h" 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | int main() 16 | { 17 | BSTree intBST; 18 | cout << "Constructing empty BST\n"; 19 | cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n"; 20 | 21 | int number; 22 | for (;;) 23 | { 24 | cout << "Item to insert (-999 to stop):"; 25 | cin >> number; 26 | if (number == -999) break; 27 | intBST.insert(number); 28 | } 29 | intBST.inorder(cout); 30 | cout << endl; 31 | intBST.graph(cout); 32 | 33 | //测试find 34 | for (;;) 35 | { 36 | cout << "Item to find (-999 to stop):"; 37 | cin >> number; 38 | if (number == -999) break; 39 | bool found = intBST.find(number); 40 | cout << boolalpha << found << endl; 41 | } 42 | 43 | //测试remove 44 | for (;;) 45 | { 46 | cout << "Item to remove (-999 to stop):"; 47 | cin >> number; 48 | if (number == -999) break; 49 | intBST.remove(number); 50 | cout << endl; 51 | intBST.graph(cout); 52 | cout << endl; 53 | } 54 | intBST.inorder(cout); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/makefile: -------------------------------------------------------------------------------- 1 | sample : main.o 2 | g++ -o sample main.o;rm main.o 3 | main.o : main.cpp BSTree.h 4 | g++ -c main.cpp 5 | 6 | clean : 7 | rm sample main.o 8 | -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s1/1.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s1/2.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s1/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s1/3.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s2/1.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s2/2.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s2/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s2/3.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s2/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s2/4.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s3/1.png -------------------------------------------------------------------------------- /C12-Binary-Search-Trees/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C12-Binary-Search-Trees/repo/s3/2.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/13.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 13.3-1 2 | *** 3 | In line 16 of RB-INSERT, we set the color of the newly inserted node z to red. Notice that if we had chosen to set z's color to black, then property 4 of a red-black tree would not be violated. Why didn't we choose to set z's color to black? 4 | 5 | ### `Answer` 6 | 性质5会被破坏,黑节点多出来了. 7 | 8 | 9 | ### Exercises 13.3-2 10 | *** 11 | Show the red-black trees that result after successively inserting the keys 41, 38, 31, 12, 19, 8 into an initially empty red-black tree. 12 | 13 | ### `Answer` 14 | 盗图感谢[psu](http://test.scripts.psu.edu/users/d/j/djh300/cmpsc465/notes-4985903869437/solutions-to-some-homework-exercises-as-shared-with-students/3-solutions-clrs-13.pdf) 15 | 16 | ![image](./repo/s3/1.png) 17 | 18 | 19 | ### Exercises 13.3-3 20 | *** 21 | Suppose that the black-height of each of the subtrees α, β, γ, δ, ε in Figures 13.5 and 13.6 is k. Label each node in each figure with its black-height to verify that property 5 is preserved by the indicated transformation. 22 | 23 | ### `Answer` 24 | ![image](./repo/s3/2.png) 25 | ![image](./repo/s3/3.png) 26 | 27 | ### Exercises 13.3-4 28 | *** 29 | Professor Teach is concerned that RB-INSERT-FIXUP might set color[nil[T]] to RED, in which case the test in line 1 would not cause the loop to terminate when z is the root. Show that the professor's concern is unfounded by arguing that RB-INSERT-FIXUP never sets color[nil[T]] to RED. 30 | ### `Answer` 31 | ![image](./repo/s3/4.png) 32 | 33 | 这是RB-INSERT-FIXUP的伪代码.只有第7行和第13行会修改颜色. 34 | 35 | 在第7行这个分支,z.p是红的,因为根不可能为红所以z.p.p肯定不是nil,所以这一行不会设置color[nil[T]]. 同理对于13行也是如此. 36 | 37 | ### Exercises 13.3-5 38 | *** 39 | Consider a red-black tree formed by inserting n nodes with RB-INSERT. Argue that if n > 1, the tree has at least one red node. 40 | ### `Answer` 41 | 观察RB-INSERT-FIXUP的伪代码,一个分支会减少一个红节点,另一个分支则不变. 当n=2时,红节点 = 黑节点 = 1. 之后每次调用RB-INSERT时会插入一个红节点再调用RB-INSERT-FIXUP,如果为情况2或情况3红节点数不会减少. 而对于情况1,必有新插入的结点为红色结点。所以n>2时红色结点个数至少一个 42 | 43 | ### Exercises 13.3-6 44 | *** 45 | Suggest how to implement RB-INSERT efficiently if the representation for red-black trees includes no storage for parent pointers. 46 | ### `Answer` 47 | 用一个hash table去保存 =.= 48 | 49 | 或者每次插入的时候维护一个stack,这样实现起来也比较麻烦. 50 | 51 | *** 52 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 53 | 54 | -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/p/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/p/1.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/p/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/p/2.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/p/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/p/3.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/p/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/p/4.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/p/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/p/5.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s1/1.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s1/2.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s1/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s1/3.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s2/1.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s3/1.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s3/2.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s3/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s3/3.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s3/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s3/4.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s4/1.png -------------------------------------------------------------------------------- /C13-Red-Black-Trees/repo/s4/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C13-Red-Black-Trees/repo/s4/2.png -------------------------------------------------------------------------------- /C14-Augmenting-Data-Structures/exercise_code/m-Josephus.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: m-Josephus.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Wed Jul 15 11:49:42 2015 7 | ************************************************************************/ 8 | #include 9 | using namespace std; 10 | 11 | struct node 12 | { 13 | int no; 14 | node *next; 15 | node(int i){no = i;} 16 | }; 17 | 18 | int main() 19 | { 20 | int m,n; 21 | node *cur,*q,*first; 22 | cout<<"请输入m的初始值 m:"; cin>>m; 23 | cout<<"请输入人数 n:"; cin>>n; 24 | 25 | for(int i = 1;i<=n;i++) 26 | { 27 | if(i == 1) 28 | first = cur = new node(i); 29 | else 30 | { 31 | q = new node(i); 32 | cur->next = q; 33 | cur = q; 34 | } 35 | } 36 | 37 | cur->next = first; 38 | cur = first; 39 | cout<<"出列顺序为: "; 40 | for (int j = 1;j<=n;j++) 41 | { 42 | for(int i = 1; i < m;i++,cur=cur->next); 43 | cout << cur->no <<" "; 44 | cur->no = cur->next->no; 45 | q = cur->next; 46 | cur->next = cur->next->next; 47 | } 48 | 49 | cout< 17 | 当j = k -1时, r(i,k-1) = r(1,k)+r(2,k) = 2^(n-k) + 2^(n-k) = 2^(n-(k-1)) 18 | 19 | 3. 综上所述, 等式成立 20 | 21 | ### Exercises 15.1-3 22 | *** 23 | Using the result of Exercise 15.1-2, show that the total number of references to all fi[j] values, or  24 | 25 | ![](http://latex.codecogs.com/gif.latex?\\sum_{i=1}^{2}\\sum_{j%20=%201}^{n}r_i\(j\)) 26 | , is exactly 2^(n+1) - 2. 27 | 28 | 29 | 30 | ### `Answer` 31 | ![](http://latex.codecogs.com/gif.latex?\\sum_{i=1}^{2}\\sum_{j%20=%201}^{n}r_i\(j\)%0d%0a=%202\(\\sum_{j=1}^{n}2^{n-j}\)%20=%202\(2^n-1\)%20=%202^{n+1}-1) 32 | 33 | 34 | ### Exercises 15.1-4 35 | *** 36 | Together, the tables containing fi[j] and li[j] values contain a total of 4n - 2 entries. Show how to reduce the space requirements to a total of 2n + 2 entries, while still computing f* and still being able to print all the stations on a fastest way through the factory. 37 | 38 | ### `Answer` 39 | It's simple. When we calculate f(n),we just need f(n-1).so we just alloc f1[2] and f2[2]. 40 | 41 | 42 | ### Exercises 15.1-5 43 | *** 44 | Professor Canty conjectures that there might exist some ei, ai,j, and ti,j values for which FASTEST-WAY produces li[j] values such that l1[j] = 2 and l2[j] = 1 for some station number j. Assuming that all transfer costs ti,j are nonnegative, show that the professor is wrong. 45 | 46 | 47 | ### `Answer` 48 | if l1[j] = 2,then f1[j-1]>f2[j-1]+t(2,j-1) ------ @1 49 | 50 | if l2[j] = 1,then f2[j-1]>f1[j-1]+t(1,j-1) ------ @2 51 | 52 | we add @1 and @2,find that t(1,j-1)+t(2,j-1) < 0 wrong !!!!!! 53 | 54 | *** 55 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 56 | 57 | -------------------------------------------------------------------------------- /C15-Dynamic-Programming/15.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 15.2-1 2 | *** 3 | Find an optimal parenthesization of a matrix-chain product whose sequence of dimensions is [5, 10, 3, 12, 5, 50, 6]. 4 | 5 | ### `Answer` 6 | It's very easy.see my [implementation](./Matrix-chain-multiplication.c) 7 | 8 | ### Exercises 15.2-2 9 | *** 10 | Give a recursive algorithm MATRIX-CHAIN-MULTIPLY(A, s, i, j) that actually performs the optimal matrix-chain multiplication, given the sequence of matrices [A1, A2, ..., An], the s table computed by MATRIX-CHAIN-ORDER, and the indices i and j. (The initial call would be MATRIX-CHAIN-MULTIPLY(A, s, 1, n).) 11 | 12 | 13 | ### `Answer` 14 | we should modify PRINT_OPTIMAL_PARENS. 15 | 16 | MATRIX_CHAIN_MULTIPLY(A,s,i,j) 17 | if(i == j) 18 | return A[i] 19 | if(j == i+1) 20 | return A[i]*A[j]; 21 | else 22 | B1 = MATRIX_CHAIN_MULTIPLY(A,s,i,S[i,j]) 23 | B2 = MATRIX_CHAIN_MULTIPLY(A,s,S[i,j]+1,j) 24 | return B1*B2 25 | 26 | ### Exercises 15.2-3 27 | *** 28 | Use the substitution method to show that the solution to the recurrence (15.11) is Ω(2^n). 29 | 30 | ### `Answer` 31 | 当n = 1时, 有p(n) = 1成立 32 | 33 | 假设对任意的k < n都成立,即p(k) >= c2^k,则有 34 | 35 | ![](http://latex.codecogs.com/gif.latex?p\(n\)%20=%20\\sum_{k=1}^{n-1}p\(k\)p\(n-k\)%20\\ge%20\\sum_{k=1}^{n-1}c2^kc2^{n-k}%20=%20c^2\(n-1\)2^n) 36 | 37 | 因此,对于任意的c总有N0 = 1/c+1,使得当n > N0时, 有p(n) >= c2^n. 38 | 39 | ### Exercises 15.2-4 40 | *** 41 | Let R(i, j) be the number of times that table entry m[i, j] is referenced while computing other table entries in a call of MATRIX-CHAIN-ORDER. Show that the total number of references for the entire table is 42 | 43 | ![](http://latex.codecogs.com/gif.latex?\\sum_{i=1}^{n}\\sum_{j=1}^{n}R\(i,j\)=%20\\frac{n^3-n}{3}) 44 | 45 | (Hint: You may find equation (A.3) useful.) 46 | 47 | ### `Answer` 48 | ![](http://latex.codecogs.com/gif.latex?\\sum_{i=1}^{n}\\sum_{j=1}^{n}R\(i,j\)%20=%20\\sum_{l%20=%202}^{n}\(n-l+1\)\(l-1\)2%20=%202\\sum_{l=1}^{n-1}l\(n-l\)=%20\\frac{n^3-n}{3}) 49 | 50 | ### Exercises 15.2-5 51 | *** 52 | Show that a full parenthesization of an n-element expression has exactly n - 1 pairs of parentheses. 53 | 54 | ### `Answer` 55 | In our previous program,wt get ((A1(A2A3))((A4A5)A6)). 56 | 57 | n = 6,and we have 5 parentheses. 58 | 59 | A pair of parentheses musts contain a operator and n elements must have n-1 operators, so a full parenthesization of an n-element expression has exactly n-1 pairs of parentheses. 60 | 61 | *** 62 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 63 | 64 | -------------------------------------------------------------------------------- /C15-Dynamic-Programming/15.5.md: -------------------------------------------------------------------------------- 1 | ### Exercises 15.5-1 2 | *** 3 | 4 | Write pseudocode for the procedure CONSTRUCT-OPTIMAL-BST(root) which, given the table root, outputs the structure of an optimal binary search tree. For the example in Figure 15.8, your procedure should print out the structure 5 | 6 | 7 | * k2 is the root 8 | * k1 is the left child of k2 9 | * d0 is the left child of k1 10 | * d1 is the right child of k1 11 | * k5 is the right child of k2 12 | * k4 is the left child of k5 13 | * k3 is the left child of k4 14 | * d2 is the left child of k3 15 | * d3 is the right child of k3 16 | * d4 is the right child of k4 17 | * d5 is the right child of k5 18 | 19 | ### `Answer` 20 | [implementation](./optimalBST.cpp) 21 | 22 | 23 | 24 | ### Exercises 15.5-2 25 | *** 26 | Determine the cost and structure of an optimal binary search tree for a set of n = 7 keys with the following probabilities: 27 | 28 | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 29 | :---:|:---:|:---:|:---:|:---:|:---:|:---: 30 | pi | | 0.04 | 0.06 | 0.08 | 0.02 | 0.10 | 0.12 | 0.14 31 | qi | 0.06 | 0.06 | 0.06 | 0.06 | 0.05 | 0.05 | 0.05 | 0.05 32 | 33 | ### `Answer` 34 | run my [program](./optimalBST.cpp) you will get the answer. 35 | 36 | ### Exercises 15.5-3 37 | *** 38 | 39 | Suppose that instead of maintaining the table w[i, j], we computed the value of w(i, j) directly from equation (15.17) in line 8 of OPTIMAL-BST and used this computed value in line 10. How would this change affect the asymptotic running time of OPTIMAL-BST? 40 | 41 | ### `Answer` 42 | 43 | 时间复杂度依旧是O(n^3).虽然原来的计算方法计算w只用了O(n^2),但算法有一个三重循环. 44 | 45 | ### Exercises 15.5-4 * 46 | *** 47 | Knuth [184] has shown that there are always roots of optimal subtrees such that root[i, j - 1] ≤ root[i, j] ≤ root[i + 1, j] for all 1 ≤ i < j ≤ n. Use this fact to modify the OPTIMAL-BST procedure to run in Θ(n2) time. 48 | 49 | ### `Answer` 50 | 第9行替换为: 51 | 52 | if i = j 53 | r <- j 54 | else 55 | for r <- root[i,j-1] to root[i+1,j] 56 | 57 | *** 58 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 59 | 60 | -------------------------------------------------------------------------------- /C15-Dynamic-Programming/Assembly-line-sche.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int Fastway(int *a1,int *a2,int *t1,int *t2,int *e,int *x,int n,int *l1,int *l2,int *value) 5 | { 6 | int *f1 = (int*)malloc(n*sizeof(int)); 7 | int *f2 = (int*)malloc(n*sizeof(int)); 8 | 9 | f1[0] = e[0]+a1[0]; 10 | f2[0] = e[1]+a2[0]; 11 | 12 | int i; 13 | for(i = 1;i < n;i++) 14 | { 15 | if(f1[i-1] < (f2[i-1]+t2[i-1])) 16 | { 17 | f1[i] = f1[i-1]+a1[i]; 18 | l1[i-1] = 1; 19 | }else{ 20 | f1[i] = f2[i-1]+t2[i-1]+a1[i]; 21 | l1[i-1]=2; 22 | } 23 | 24 | if(f2[i-1] < (f1[i-1]+t1[i-1])) 25 | { 26 | f2[i] = f2[i-1]+a2[i]; 27 | l2[i-1] = 2; 28 | }else{ 29 | f2[i] = f1[i-1]+t1[i-1]+a2[i]; 30 | l2[i-1] = 1; 31 | } 32 | } 33 | 34 | if((f1[n-1]+x[0]) < (f2[n-1]+x[1])) 35 | { 36 | *value = f1[n-1]+x[0]; 37 | free(f1); 38 | free(f2); 39 | return 1; 40 | }else { 41 | *value = f2[n-1]+x[1]; 42 | free(f1); 43 | free(f2); 44 | return 2; 45 | } 46 | } 47 | 48 | void PRINT_STATIONS(int *l1,int *l2,int way,int n) 49 | { 50 | printf("line%d,station%d\n",way,n); 51 | int i; 52 | for(i=(n-2);i>=0;i--) 53 | { 54 | if(way == 1) 55 | way = l1[i]; 56 | else 57 | way = l2[i]; 58 | 59 | printf("line%d,station%d\n",way,i+1); 60 | 61 | } 62 | } 63 | 64 | void reverse_PRINT_STATIONS(int *l1,int *l2,int way,int n) 65 | { 66 | int new_way; 67 | if(way == 1) 68 | new_way = l1[n-2]; 69 | else 70 | new_way = l2[n-2]; 71 | if(n >= 2) 72 | reverse_PRINT_STATIONS(l1,l2,new_way,n-1); 73 | printf("line%d,station%d\n",way,n); 74 | } 75 | 76 | int main() 77 | { 78 | int n = 6; 79 | int e[2]; 80 | e[0]=2; 81 | e[1]=4; 82 | 83 | int x[2]; 84 | x[0]=3; 85 | x[1]=2; 86 | 87 | int t1[5],t2[5]; 88 | t1[0]=2; 89 | t1[1]=3; 90 | t1[2]=1; 91 | t1[3]=3; 92 | t1[4]=4; 93 | t2[0]=2; 94 | t2[1]=1; 95 | t2[2]=2; 96 | t2[3]=2; 97 | t2[4]=1; 98 | 99 | int a1[6],a2[6]; 100 | a1[0]=7; 101 | a1[1]=9; 102 | a1[2]=3; 103 | a1[3]=4; 104 | a1[4]=8; 105 | a1[5]=4; 106 | a2[0]=8; 107 | a2[1]=5; 108 | a2[2]=6; 109 | a2[3]=4; 110 | a2[4]=5; 111 | a2[5]=7; 112 | 113 | int value; 114 | int *l1 = (int*)malloc((n-1)*sizeof(int)); 115 | int *l2 = (int*)malloc((n-1)*sizeof(int)); 116 | int way = Fastway(a1,a2,t1,t2,e,x,n,l1,l2,&value); 117 | printf("value = %d\n",value); 118 | reverse_PRINT_STATIONS(l1,l2,way,n); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /C15-Dynamic-Programming/Matrix-chain-multiplication.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * according to introduction to algorithm, 6 | * we alloc array(n+1)but make use of the last n 7 | * just for convinence 8 | */ 9 | void MATRIX_CHAIN_ORDER(int *p,int n,int **m,int **s) 10 | { 11 | int i; 12 | int row = n+1; 13 | //initialize our array 14 | for(i=1;i<=n;i++) 15 | *((int*)m+row*i+i) = 0; 16 | 17 | int l; 18 | for(l=2;l<=n;l++) 19 | { 20 | for(i=1;i<=(n-l+1);i++) 21 | { 22 | int j = i+l-1; 23 | *((int*)m+row*i+j) = -1; 24 | int k; 25 | for(k=i;k<=(j-1);k++) 26 | { 27 | int tmp1 = *((int*)m+row*i+k); 28 | int tmp2 = *((int*)m+row*(k+1)+j); 29 | int q = tmp1+tmp2+p[i-1]*p[k]*p[j]; 30 | 31 | int old = *((int*)m+row*i+j); 32 | if(q 2 | using namespace std; 3 | 4 | int find(int *a, int len, int n) 5 | { 6 | int left(0),right(len),mid = (left+right)/2; 7 | while(left <= right) 8 | { 9 | if(n > a[mid]) left = mid + 1; 10 | else if(n < a[mid]) right = mid - 1; 11 | else return mid; 12 | mid = (left + right)/2; 13 | } 14 | return left; 15 | } 16 | 17 | int main() 18 | { 19 | int n, a[100], c[100], i, j, len; 20 | cin >> n; 21 | 22 | for(int i = 0;i < n;i++) 23 | cin >> a[i]; 24 | c[0] = -1; 25 | c[1] = a[0]; 26 | len = 1; 27 | 28 | for(i = 1;i <= n;i++) 29 | { 30 | j = find(c, len, a[i]); 31 | c[j] = a[i]; 32 | if(j > len) 33 | len = j; 34 | } 35 | 36 | cout << len << endl; 37 | return 0; 38 | } -------------------------------------------------------------------------------- /C15-Dynamic-Programming/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C15-Dynamic-Programming/repo/s3/1.png -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/BinaryStdIn.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: BinaryStdIn.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 08:14:15 PM CST 6 | ************************************************************************/ 7 | 8 | #include "BinaryStdIn.h" 9 | 10 | BinaryStdIn::BinaryStdIn(string filename) { 11 | open(filename); 12 | } 13 | 14 | bool BinaryStdIn::open(string filename) 15 | { 16 | fin.open(filename.c_str(), std::ios::binary); 17 | if (!fin.is_open()) { 18 | cout << "Error opening file" << endl; 19 | exit (1); 20 | } 21 | fillBuffer(); 22 | return true; 23 | } 24 | 25 | bool BinaryStdIn::fillBuffer() { 26 | char ch; 27 | fin >> ch; 28 | buffer = ch; 29 | N = 8; 30 | } 31 | 32 | bool BinaryStdIn::readBool() { 33 | N--; 34 | bool bit = ((buffer >> N) & 1) == 1; 35 | if (N == 0) fillBuffer(); 36 | 37 | #ifdef DEBUG 38 | cout << "Function readBool() return : " << bit << endl; 39 | #endif 40 | 41 | return bit; 42 | } 43 | 44 | char BinaryStdIn::readChar() { 45 | if(N == 8) { 46 | char x = buffer; 47 | fillBuffer(); 48 | return x; 49 | } 50 | 51 | char x = buffer; 52 | x <<= (8-N); 53 | int oldN = N; 54 | fillBuffer(); 55 | N = oldN; 56 | 57 | unsigned char tmp = (unsigned char)buffer; 58 | x |= ( tmp >> N); 59 | 60 | #ifdef DEBUG 61 | cout << "Function readChar() return : " << x << endl; 62 | #endif 63 | 64 | return x; 65 | } 66 | 67 | int BinaryStdIn::readInt() { 68 | int x = 0; 69 | for (int i = 0; i < 4; i++) { 70 | char c = readChar(); 71 | x <<= 8; 72 | x |= c; 73 | } 74 | 75 | #ifdef DEBUG 76 | cout << "Function readInt() return : " << x << endl; 77 | #endif 78 | 79 | return x; 80 | } 81 | 82 | void BinaryStdIn::close() { 83 | fin.close(); 84 | } 85 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/BinaryStdIn.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: BinaryStdIn.h 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 08:05:13 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _BINARYSTDIN_H 9 | #define _BINARYSTDIN_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | class BinaryStdIn 18 | { 19 | ifstream fin; 20 | char buffer; 21 | int N; 22 | 23 | bool fillBuffer(); 24 | 25 | public: 26 | BinaryStdIn(){}; 27 | BinaryStdIn(string filename); 28 | bool open(string filename); 29 | bool readBool(); 30 | char readChar(); 31 | int readInt(); 32 | 33 | void close(); 34 | }; 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/BinaryStdOut.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: BinaryStdOut.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 09:18:56 PM CST 6 | ************************************************************************/ 7 | 8 | #include "BinaryStdOut.h" 9 | #include 10 | using namespace std; 11 | 12 | BinaryStdOut::BinaryStdOut(string filename) { 13 | open(filename); 14 | } 15 | 16 | bool BinaryStdOut::open(string filename) { 17 | fout.open(filename.c_str(), ios::out|ios::binary); 18 | if (!fout.is_open()) { 19 | cout << "Error opening file" << endl; 20 | exit (1); 21 | } 22 | } 23 | 24 | void BinaryStdOut::clearBuffer() { 25 | if(N == 0) return; 26 | if (N > 0) buffer <<= (8 - N); 27 | fout << buffer; 28 | N = 0; 29 | buffer = 0; 30 | } 31 | 32 | void BinaryStdOut::writeBit(bool bit) { 33 | buffer <<= 1; 34 | if (bit) buffer |= 1; 35 | N++; 36 | if (N == 8) clearBuffer(); 37 | } 38 | 39 | void BinaryStdOut::writeChar(char ch) { 40 | if (N == 0) { 41 | fout << ch; 42 | return; 43 | } 44 | 45 | for (int i = 0; i < 8; i++) { 46 | bool bit = ((ch >> (8 - i - 1)) & 1 ) == 1; 47 | writeBit(bit); 48 | } 49 | } 50 | 51 | void BinaryStdOut::write(bool x) { 52 | writeBit(x); 53 | } 54 | 55 | void BinaryStdOut::write(char x) { 56 | writeChar(x); 57 | } 58 | 59 | void BinaryStdOut::write(int x) { 60 | writeChar((x >> 24) & 0xff); 61 | writeChar((x >> 16) & 0xff); 62 | writeChar((x >> 8) & 0xff); 63 | writeChar((x >> 0) & 0xff); 64 | } 65 | 66 | void BinaryStdOut::flush() { 67 | clearBuffer(); 68 | fout.flush(); 69 | } 70 | 71 | void BinaryStdOut::close() { 72 | flush(); 73 | fout.close(); 74 | cout << "-------------------- BinaryStdOut Writing Closing --------------------" << endl; 75 | } 76 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/BinaryStdOut.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: BinaryStdOut.h 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 09:12:17 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _BINARYSTDOUT_H 9 | #define _BINARYSTDOUT_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | class BinaryStdOut 18 | { 19 | char buffer; 20 | int N; 21 | ofstream fout; 22 | 23 | void clearBuffer(); 24 | 25 | void writeBit(bool bit); 26 | void writeChar(char ch); 27 | 28 | public: 29 | BinaryStdOut(){}; 30 | BinaryStdOut(string filename); 31 | bool open(string filename); 32 | 33 | void write(bool bit); 34 | void write(char ch); 35 | void write(int i); 36 | 37 | void flush(); 38 | void close(); 39 | }; 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/HUFFMAN.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: HUFFMAN.h 3 | > Author: 4 | > Mail: 5 | > Created Time: Mon 12 Jan 2015 11:20:02 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "BinaryStdIn.h" 15 | #include "BinaryStdOut.h" 16 | 17 | using namespace std; 18 | 19 | #ifndef _HUFFMAN_H 20 | #define _HUFFMAN_H 21 | 22 | struct Htree { 23 | Htree *left; 24 | Htree *right; 25 | int weight; 26 | char ch; 27 | Htree() {left = right = NULL; weight = 0;ch = 0;} 28 | Htree(Htree *l, Htree *r, int v, char c) {left = l; right = r; weight = v; ch = c;} 29 | }; 30 | 31 | 32 | // is the node a leaf node? 33 | static inline bool isLeaf(Htree *node) { 34 | assert ( (node->left == NULL && node->right == NULL) || (node->left != NULL && node->right != NULL) ); 35 | return (node->left == NULL && node->right == NULL); 36 | } 37 | 38 | class myComparision 39 | { 40 | public: 41 | bool operator () (const Htree* t1, const Htree* t2) { 42 | return t1->weight> t2->weight; 43 | } 44 | }; 45 | 46 | class HUFFMAN { 47 | typedef map > huffman_dict; 48 | 49 | Htree *huffman_Tree; 50 | huffman_dict dict; 51 | BinaryStdOut *binaryStdOut; 52 | BinaryStdIn *binaryStdIn; 53 | 54 | void buildTree(string &data, string filename); 55 | void buildDict(Htree *node, vector &code); 56 | void destroy(Htree *node); 57 | void writeTrie(Htree *node); 58 | Htree *readTrie(); 59 | 60 | public: 61 | 62 | HUFFMAN(); 63 | ~HUFFMAN(); 64 | void encode(string &data, string filename); 65 | string decode(string filename); 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binary_test/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 10:49:50 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "../BinaryStdIn.h" 10 | #include "../BinaryStdOut.h" 11 | using namespace std; 12 | 13 | int main() 14 | { 15 | string filename = "data"; 16 | BinaryStdOut binaryStdOut; 17 | binaryStdOut.open(filename); 18 | 19 | 20 | binaryStdOut.write('h'); 21 | binaryStdOut.write('e'); 22 | binaryStdOut.write('l'); 23 | binaryStdOut.write('l'); 24 | binaryStdOut.write('o'); 25 | 26 | binaryStdOut.write(true); 27 | binaryStdOut.write(false); 28 | 29 | binaryStdOut.write(30); 30 | binaryStdOut.write('p'); 31 | 32 | 33 | binaryStdOut.close(); 34 | 35 | BinaryStdIn binaryStdIn(filename); 36 | 37 | 38 | cout << binaryStdIn.readChar() << endl; 39 | cout << binaryStdIn.readChar() << endl; 40 | cout << binaryStdIn.readChar() << endl; 41 | cout << binaryStdIn.readChar() << endl; 42 | cout << binaryStdIn.readChar() << endl; 43 | cout << binaryStdIn.readBool() << endl; 44 | cout << binaryStdIn.readBool() << endl; 45 | cout << binaryStdIn.readInt() << endl; 46 | cout << binaryStdIn.readChar() << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binary_test/makefile: -------------------------------------------------------------------------------- 1 | main : main.o BinaryStdOut.o BinaryStdIn.o 2 | g++ -o main main.o BinaryStdOut.o BinaryStdIn.o 3 | main.o : main.cpp ../BinaryStdOut.h ../BinaryStdIn.h 4 | g++ -c main.cpp 5 | BinaryStdOut.o : ../BinaryStdOut.h ../BinaryStdOut.cpp 6 | g++ -c ../BinaryStdOut.cpp 7 | BinaryStdIn.o : ../BinaryStdIn.h ../BinaryStdIn.cpp 8 | g++ -c ../BinaryStdIn.cpp 9 | 10 | clean : 11 | rm main main.o BinaryStdOut.o BinaryStdIn.o 12 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binarystdin_test/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 08:33:11 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "../BinaryStdIn.h" 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | string filename = "data"; 15 | 16 | BinaryStdIn binaryStdIn(filename); 17 | 18 | cout << binaryStdIn.readInt() << endl; 19 | 20 | binaryStdIn.close(); 21 | 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binarystdin_test/makefile: -------------------------------------------------------------------------------- 1 | test_BinaryStdIn : main.o BinaryStdIn.o 2 | g++ -o test_BinaryStdIn main.o BinaryStdIn.o 3 | main.o : main.cpp ../BinaryStdIn.h 4 | g++ -c main.cpp 5 | BinaryStdIn.o : ../BinaryStdIn.h ../BinaryStdIn.cpp 6 | g++ -c -DDEBUG=1 ../BinaryStdIn.cpp 7 | 8 | clean : 9 | rm test_BinaryStdIn main.o BinaryStdIn.o 10 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binarystdout_test/data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/huffman/binarystdout_test/data -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binarystdout_test/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Wed 14 Jan 2015 08:33:11 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "../BinaryStdOut.h" 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | string filename = "data"; 15 | 16 | BinaryStdOut binaryStdOut(filename); 17 | 18 | //write 8 true 19 | binaryStdOut.write(true); 20 | binaryStdOut.write(true); 21 | binaryStdOut.write(true); 22 | binaryStdOut.write(true); 23 | binaryStdOut.write(true); 24 | binaryStdOut.write(true); 25 | binaryStdOut.write(true); 26 | binaryStdOut.write(true); 27 | 28 | //write 8 false 29 | binaryStdOut.write(false); 30 | binaryStdOut.write(false); 31 | binaryStdOut.write(false); 32 | binaryStdOut.write(false); 33 | binaryStdOut.write(false); 34 | binaryStdOut.write(false); 35 | binaryStdOut.write(false); 36 | binaryStdOut.write(false); 37 | 38 | //4 true , 4 false 39 | binaryStdOut.write(true); 40 | binaryStdOut.write(true); 41 | binaryStdOut.write(true); 42 | binaryStdOut.write(true); 43 | binaryStdOut.write(false); 44 | binaryStdOut.write(false); 45 | binaryStdOut.write(false); 46 | binaryStdOut.write(false); 47 | 48 | binaryStdOut.write('a'); 49 | binaryStdOut.write(false); 50 | binaryStdOut.write(512); 51 | 52 | binaryStdOut.close(); 53 | 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/binarystdout_test/makefile: -------------------------------------------------------------------------------- 1 | test_BinaryStdOut : main.o BinaryStdOut.o 2 | g++ -o test_BinaryStdOut main.o BinaryStdOut.o 3 | main.o : main.cpp ../BinaryStdOut.h 4 | g++ -c main.cpp 5 | BinaryStdOut.o : ../BinaryStdOut.h ../BinaryStdOut.cpp 6 | g++ -c -DDEBUG=1 ../BinaryStdOut.cpp 7 | 8 | clean : 9 | rm test_BinaryStdOut main.o BinaryStdOut.o 10 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/huffman_test/compressed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/huffman/huffman_test/compressed -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/huffman_test/huffman_test_client.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: huffman_test_client.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Tue 13 Jan 2015 07:59:40 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "../HUFFMAN.h" 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | string data = "3248&&&^aaaaaabbbbccccdddeef"; 15 | 16 | string filename = "compressed"; 17 | HUFFMAN huffman; 18 | huffman.encode(data, filename); 19 | string rdata = huffman.decode(filename); 20 | cout << "Recover data : " << rdata << endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/huffman/huffman_test/makefile: -------------------------------------------------------------------------------- 1 | main : huffman_test_client.o HUFFMAN.o BinaryStdIn.o BinaryStdOut.o 2 | g++ -o main huffman_test_client.o HUFFMAN.o BinaryStdIn.o BinaryStdOut.o 3 | huffman_test_client.o : huffman_test_client.cpp ../HUFFMAN.h 4 | g++ -c huffman_test_client.cpp 5 | HUFFMAN.o : ../HUFFMAN.h ../HUFFMAN.cpp ../BinaryStdIn.h ../BinaryStdOut.h 6 | g++ -c -DDEBUG=1 ../HUFFMAN.cpp 7 | BinaryStdIn.o : ../BinaryStdIn.h ../BinaryStdIn.cpp 8 | g++ -c ../BinaryStdIn.cpp 9 | BinaryStdOut.o : ../BinaryStdOut.h ../BinaryStdOut.cpp 10 | g++ -c ../BinaryStdOut.cpp 11 | 12 | clean : 13 | rm main huffman_test_client.o HUFFMAN.o BinaryStdOut.o BinaryStdIn.o 14 | -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/repo/s1/1.png -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/repo/s2/1.png -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/repo/s2/2.png -------------------------------------------------------------------------------- /C16-Greedy-Algorithms/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C16-Greedy-Algorithms/repo/s3/1.png -------------------------------------------------------------------------------- /C17-Amortized-Analysis/17.1.md: -------------------------------------------------------------------------------- 1 | ### Exercise 17.1-1 2 | *** 3 | If the set of stack operations included a MULTIPUSH operation, which pushes k items onto the stack, would the O(1) bound on the amortized cost of stack operations continue to hold? 4 | 5 | ### `Answer` 6 | No.The time complexity of such a series of operations depends on the number of push operation. Since one MULTIPUSH needs Θ(k)time, performing n MULTIPUSH operations, each with k elements, would take Θ(kn)time, leading to amortized cost of Θ(k). 7 | 8 | 9 | ### Exercise 17.1-2 10 | *** 11 | Show that if a DECREMENT operation were included in the k-bit counter example, n operations could cost as much as theta(nk) time. 12 | 13 | ### `Answer` 14 | In the worst case, going from 1[k-1 0's] (ie. 1000 -> 0111) takes k flips. Could do any sequence of increment and decrement from 1000 -> 0111 -> 1000 -> 0111 (n times), which is theta(nk). 15 | 16 | 17 | ### Exercise 17.1-3 18 | *** 19 | A sequence of n operations is performed on a data structure. The ith operation costs i if i is an exact power of 2, and 1 otherwise. Use aggregate analysis to determine the amortized cost per operation. 20 | 21 | ### `Answer` 22 | Look at a sequence of n operations. Let k = floor(lb(n)). All operations cost equal to 1 * (1 - 2^k) / (1 - 2) + n - k = O(n), than each operation cost equal to O(n) / n = O(1). 23 | -------------------------------------------------------------------------------- /C18-B-Trees/18.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 18.1-1 2 | *** 3 | Why don't we allow a minimum degree of t = 1? 4 | 5 | ### `Answer` 6 | According to the definition, minimum degree t means every node other than the root must have at least t – 1 keys, and every internal node other than the root thus has at least t children. So, when t = 1, it means every node other than the root must have 7 | at least t – 1 = 0 key, and every internal node other than the root thus has at least t = 1 child. 8 | 9 | Thus, we can see that the minimum case doesn't exist, because no node exists with 0 key, and no node exists with only 1 child 10 | in a B-tree. 11 | 12 | ### Exercises 18.1-2 13 | *** 14 | For what values of t is the tree of Figure 18.1 a legal B-tree? 15 | 16 | ### `Answer` 17 | According to property 5 of B-tree, every node other than the root must have at least t−1keys and may contain at most 2t−1 keys. In Figure 18.1, the number of keys of each node (except the root) is either 2 or 3. So to make it a legal B-tree, we need 18 | to guarantee that 19 | 20 | t – 1 ≤ 2 and 2 t – 1 ≥ 3, 21 | 22 | which yields 2 ≤ t ≤ 3. So t can be 2 or 3. 23 | 24 | ### Exercises 18.1-3 25 | *** 26 | Show all legal B-trees of minimum degree 2 that represent {1, 2, 3, 4, 5} 27 | 28 | ### `Answer` 29 | The question asks for the legal trees with min degree t=2. So, each node can contain x num of keys while 1 ≤ x ≤ 3 30 | ``` 31 | 2 32 | 1 3 4 5 33 | ``` 34 | 35 | ``` 36 | 4 37 | 1 2 3 5 38 | ``` 39 | 40 | ``` 41 | 3 42 | 1 2 4 5 43 | ``` 44 | 45 | 46 | ### Exercises 18.1-4 47 | *** 48 | As a function of the minimum degree t, what is the maximum number of keys that can be stored in a B-tree of height h? 49 | 50 | ### `Answer` 51 | ![](./repo/s1/2.png) 52 | 53 | ### Exercises 18.1-5 54 | *** 55 | Describe the data structure that would result if each black node in a red-black tree were to absorb its red children, incorporating their children with its own. 56 | 57 | ### `Answer` 58 | After absorbing each red node into its black parent, each black node may contain 1, 2 (1 red child), or 3 (2 red children) keys, and all leaves of the resulting tree have the same depth, according to property 5 of red-black tree (For each node, all paths 59 | from the node to descendant leaves contain the same number of black nodes). Therefore, a red-black tree will become a Btree with minimum degree t = 2, i.e., a 2-3-4 tree. 60 | 61 | *** 62 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 63 | 64 | -------------------------------------------------------------------------------- /C18-B-Trees/18.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 18.3-1 2 | *** 3 | Show the results of deleting C, P, and V , in order, from the tree of Figure 18.8(f). 4 | 5 | ### `Answer` 6 | LPTX 7 | AEJK NO QRS UV YZ 8 | 9 | LQTX 10 | AEJK NO RS UV YZ 11 | 12 | LQX 13 | AEJK NO RSTU YZ 14 | 15 | ### Exercises 18.3-2 16 | *** 17 | Write pseudocode for B-TREE-DELETE. 18 | 19 | ### `Answer` 20 | [implementation](./btree.cpp) 21 | 22 | *** 23 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 24 | 25 | -------------------------------------------------------------------------------- /C18-B-Trees/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C18-B-Trees/repo/s1/1.png -------------------------------------------------------------------------------- /C18-B-Trees/repo/s1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C18-B-Trees/repo/s1/2.png -------------------------------------------------------------------------------- /C18-B-Trees/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C18-B-Trees/repo/s2/1.png -------------------------------------------------------------------------------- /C18-B-Trees/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C18-B-Trees/repo/s2/2.png -------------------------------------------------------------------------------- /C19-Binomial-Heaps/19.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 19.1-1 2 | *** 3 | Suppose that x is a node in a binomial tree within a binomial heap, and assume that sibling[x] ≠ NIL. If x is not a root, how does degree[sibling[x]] compare to degree[x]? How about if x is a root? 4 | 5 | ### `Answer` 6 | * If x is not a root, degree[sibling[x]] < degree[x] 7 | * If x is a root, degree[sibling[x]] > degree[x] 8 | 9 | ### Exercises 19.1-2 10 | *** 11 | If x is a nonroot node in a binomial tree within a binomial heap, how does degree[x] compare 12 | to degree[p[x]]? 13 | 14 | ### `Answer` 15 | degree[p[x]] > degree[x] 16 | 17 | ### Exercises 19.1-3 18 | *** 19 | Suppose we label the nodes of binomial tree Bk in binary by a postorder walk, as in Figure 19.4. Consider a node x labeled l at depth i, and let j = k - i. Show that x has j 1's in its binary representation. How many binary k-strings are there that contain exactly j 1's? Show that the degree of x is equal to the number of 1's to the right of the rightmost 0 in the binary representation of l. 20 | 21 | ### `Answer` 22 | 23 | 24 | *** 25 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 26 | 27 | -------------------------------------------------------------------------------- /C21-Data-Structures-for-Disjoint-Sets/21.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 21.1-1 2 | *** 3 | Suppose that CONNECTED-COMPONENTS is run on the undirected graph G = (V, E), where V = {a, b, c, d, e, f, g, h, i, j, k} and the edges of E are processed in the following order: (d, i), (f, k), (g, i), (b, g), (a, h), (i, j), (d, k), (b, j), (d, f), (g, j), (a, e), (i, d). List the vertices in each connected component after each iteration of lines 3-5. 4 | 5 | ### `Answer` 6 | {a} {b} {c} {d} {e} {f} {g} {h} {i} {j} {k} 7 | 8 | 1. (d,i) => {a} {b} {c} {d i} {e} {f} {g} {h} {j} {k} 9 | 2. (f,k) => {a} {b} {c} {d i} {e} {f k} {g} {h} {j} 10 | 3. (g,i) => {a} {b} {c} {d g i} {e} {f k} {h} {j} 11 | 4. (b,g) => {a} {b d g i} {c} {e} {f k} {h} {j} 12 | 5. (a,h) => {a h} {b d g i} {c} {e} {f k} {j} 13 | 6. (i,j) => {a h} {b d g i j} {c} {e} {f k} 14 | 7. (d,k) => {a h} {b d g i j f k} {c} {e} 15 | 8. (b,j) => {a h} {b d g i j f k} {c} {e} 16 | 9. (d,f) => {a h} {b d g i j f k} {c} {e} 17 | 10. (g,j) => {a h} {b d g i j f k} {c} {e} 18 | 11. (a,e) => {a e h} {b d g i j f k} {c} 19 | 20 | ### Exercises 21.1-2 21 | *** 22 | Show that after all edges are processed by CONNECTED-COMPONENTS, two vertices are in the same connected component if and only if they are in the same set. 23 | 24 | ### `Answer` 25 | If two vertices are not in the same set, meaning that no edge connecting the set of one vertice with the other. So two vertices are in the same connected component if and only if they are in the same set. 26 | 27 | ### Exercises 21.1-3 28 | *** 29 | During the execution of CONNECTED-COMPONENTS on an undirected graph G = (V, E) with k connected components, how many times is FIND-SET called? How many times is UNION called? Express your answers in terms of |V|, |E|, and k. 30 | 31 | ### `Answer` 32 | * FIND-SET : 2|E| 33 | * UNION : |V| - k 34 | 35 | *** 36 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 37 | 38 | -------------------------------------------------------------------------------- /C21-Data-Structures-for-Disjoint-Sets/21.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 21.3-1 2 | *** 3 | Do Exercise 21.2-2 using a disjoint-set forest with union by rank and path compression. 4 | 5 | ### `Answer` 6 | 7 |
 8 | 					1
 9 | 				
10 | 			/		|	\	   				\	
11 | 			2		3    5					9
12 | 			
13 | 					|	/ \			/    /		 \
14 | 					4   6 7		   10   11		 13
15 | 					
16 | 						  |				 |	   /   \
17 | 	   					  8  			12    14   15
18 | 	   					  
19 | 	   					  						    |
20 | 	   					  						    16
21 | 
22 | 23 | ### Exercises 21.3-2 24 | *** 25 | Write a nonrecursive version of FIND-SET with path compression. 26 | 27 | ### `Answer` 28 | [implementation](./uf.cpp) 29 | 30 | ### Exercises 21.3-3 31 | *** 32 | Give a sequence of m MAKE-SET, UNION, and FIND-SET operations, n of which are MAKE-SET operations, that takes Ω(m lg n) time when we use union by rank only. 33 | 34 | ### `Answer` 35 | [reference](http://www.cs.toronto.edu/~avner/teaching/263/A/4sol.pdf) 36 | 37 | ![](./repo/s3/1.png) 38 | 39 | ### Exercises 21.3-4 * 40 | *** 41 | Show that any sequence of m MAKE-SET, FIND-SET, and LINK operations, where all the LINK operations appear before any of the FIND-SET operations, takes only O(m) time if both path compression and union by rank are used. What happens in the same situation if only the path-compression heuristic is used? 42 | 43 | ### `Answer` 44 | UNSOLVED 45 | 46 | *** 47 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 48 | 49 | -------------------------------------------------------------------------------- /C21-Data-Structures-for-Disjoint-Sets/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C21-Data-Structures-for-Disjoint-Sets/repo/s3/1.png -------------------------------------------------------------------------------- /C21-Data-Structures-for-Disjoint-Sets/uf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class UF { 7 | 8 | private: 9 | vector parent; 10 | vector rank; 11 | int count; 12 | int N; 13 | 14 | bool validate(int p) { 15 | return (p >= 0 && p < N); 16 | } 17 | 18 | public: 19 | 20 | UF(int N) : parent(N), rank(N, 0), N(N), count(N) { 21 | for (int i = 0; i < N; i++) { 22 | parent[i] = i; 23 | } 24 | } 25 | 26 | int find(int p) { 27 | if (!validate(p)) return -1; 28 | while (p != parent[p]) { 29 | parent[p] = parent[parent[p]]; // path compression by halving 30 | p = parent[p]; 31 | } 32 | return p; 33 | } 34 | 35 | int getCount() const { 36 | return count; 37 | } 38 | 39 | bool connected(int p, int q) { 40 | return find(p) == find(q); 41 | } 42 | 43 | void Union(int p, int q) { 44 | int rootP = find(p); 45 | int rootQ = find(q); 46 | if (rootP == rootQ) return; 47 | 48 | // make root of smaller rank point to root of larger rank 49 | if (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ; 50 | else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP; 51 | else { 52 | parent[rootQ] = rootP; 53 | rank[rootP]++; 54 | } 55 | count--; 56 | } 57 | 58 | ~UF() {} 59 | }; 60 | 61 | int main() { 62 | UF uf(5); 63 | cout << uf.getCount() << endl; 64 | cout << uf.connected(2, 4) << endl; 65 | uf.Union(1, 2); 66 | uf.Union(3, 4); 67 | cout << uf.getCount() << endl; 68 | uf.Union(1, 3); 69 | cout << uf.connected(2, 4) << endl; 70 | } 71 | -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/README.md: -------------------------------------------------------------------------------- 1 | UNSOLVED 2 | 3 | -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/exercise_code/EulerTour.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: EulerTour.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Thu Jul 16 13:54:43 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | #define MAX_VERTEX 10005 13 | 14 | typedef struct { 15 | int end_vertex; 16 | int visited; 17 | } Edge; 18 | 19 | int Nvertex; 20 | int Nedge; 21 | vector vertex[MAX_VERTEX]; 22 | 23 | static void input() { 24 | int i, u, v; 25 | Edge tmp; 26 | tmp.visited = 0; 27 | cin >> Nvertex >> Nedge; 28 | for (i = 0; i < Nedge; ++i) { 29 | cin >> u >> v; 30 | tmp.end_vertex = u; 31 | vertex[v].push_back(tmp); 32 | tmp.end_vertex = v; 33 | vertex[u].push_back(tmp); 34 | } 35 | } 36 | 37 | static void euler(int x) { 38 | int i; 39 | for (i = vertex[x].size() - 1; i >= 0; --i) { 40 | if (!vertex[x][i].visited) { 41 | vertex[x][i].visited = 1; 42 | euler(vertex[x][i].end_vertex); 43 | } 44 | } 45 | cout << x << endl; 46 | } 47 | 48 | int main() { 49 | input(); 50 | euler(1); 51 | return 0; 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/problem.md: -------------------------------------------------------------------------------- 1 | ### Problems 3 : Euler tour 2 | *** 3 | An Euler tour of a connected, directed graph G = (V, E) is a cycle that traverses each edge of G exactly once, although it may visit a vertex more than once. 4 | 5 | a. Show that G has an Euler tour if and only if in-degree (v) = out-degree (v) for each vertex v in V. 6 | 7 | b. Describe an O(E)-time algorithm to find an Euler tour of G if one exists. (Hint: Merge edge-disjoint cycles.) 8 | 9 | 10 | ### `Answer` 11 | **a.** 12 | 13 | 只有入度=出度,才能进来一次又出去;否则,不对称,是不可能访问全部的边的. 14 | 15 | **b.** 16 | 17 | [implementation](./exercise_code/EulerTour.cpp) 18 | 19 | ### Problems 4 : Reachability 20 | Let G = (V, E) be a directed graph in which each vertex u in V is labeled with a unique integer L(u) from the set {1, 2,..., |V|}. For each vertex u in V, let  be the set of vertices that are reachable from u. Define min(u) to be the vertex in R(u) whose label is minimum, i.e., min(u) is the vertex v such that L(v) = min {L(w) : w in R(u)}. Give an O(V + E)-time algorithm that computes min(u) for all vertices u in V. 21 | 22 | ### `Answer` 23 | 24 | For every vertex v in G 25 | Mark v undiscovered 26 | For every undiscovered vertex v in G, starting with the lowest L-value 27 | R(v) = L(v) 28 | Mark v discovered. 29 | Perform Reverse-DFS from v. 30 | For every undiscovered vertex u we encounter on this DFS: 31 | R(u) = R(v) 32 | Mark u discovered. 33 | 34 | 35 | [reference](http://www.fongboy.com/classes/cs180/hw7-sol.pdf) 36 | 37 | 38 | *** 39 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 40 | 41 | -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s2/1.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s2/2.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s2/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s2/3.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s3/1.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s3/2.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s3/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s3/3.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s3/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s3/4.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s4/1.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s5/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s5/1.png -------------------------------------------------------------------------------- /C22-Elementary-Graph-Algorithms/repo/s5/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C22-Elementary-Graph-Algorithms/repo/s5/2.png -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s1/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s1/1.jpg -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s1/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s1/2.jpg -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s1/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s1/3.jpg -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s1/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s1/4.jpg -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s2/1.png -------------------------------------------------------------------------------- /C23-Minimum-Spanning-Trees/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C23-Minimum-Spanning-Trees/repo/s2/2.png -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/24.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 24.2-1 2 | *** 3 | Run DAG-SHORTEST-PATHS on the directed graph of Figure 24.5, using vertex r as the 4 | source. 5 | 6 | ### `Answer` 7 | 8 | straightforward. 9 | 10 | 11 | ### Exercises 24.2-2 12 | *** 13 | Suppose we change line 3 of DAG-SHORTEST-PATHS to read 3 for the first |V| - 1 vertices, taken in topologically sorted order Show that the procedure would remain correct. 14 | 15 | ### `Answer` 16 | 因为最后一次对结果没有影响. 17 | 18 | ### Exercises 24.2-3 19 | *** 20 | The PERT chart formulation given above is somewhat unnatural. It would be more natural for vertices to represent jobs and edges to represent sequencing constraints; that is, edge (u, v) would indicate that job u must be performed before job v. Weights would then be assigned to vertices, not edges. Modify the DAG-SHORTEST-PATHS procedure so that it finds a longest path in a directed acyclic graph with weighted vertices in linear time. 21 | 22 | ### `Answer` 23 | 24 | PERT(G) 25 | topologically sort the vertices of G 26 | INITIALIZE(G) 27 | for each vertex u, taken in topologically sorted order 28 | do for each vertex v ∈ Adj[u] 29 | do RELAX(u,v) 30 | 31 | INITIALIZE(G) 32 | for each vertex v ∈ V[G] 33 | do d[v] = w[v] 34 | π[v] = NIL 35 | 36 | RELAX(u, v) 37 | if(d[v] < d[u] + w[v]) 38 | d[v] = d[u] + w[v] 39 | u[v] = u 40 | 41 | 42 | ### Exercises 24.2-4 43 | *** 44 | Give an efficient algorithm to count the total number of paths in a directed acyclic graph. Analyze your algorithm. 45 | 46 | ### `Answer` 47 | DAG-PATHS(G, s) 48 | topologically sort the vertices of G 49 | INITIALIZE(G, s) 50 | for each vertex u, taken in topologically sorted order 51 | do for each vertex v ∈ Adj[u] 52 | do c[v] = c[v] + c[u] 53 | 54 | INITIALIZE(G, s) 55 | for each vertex v ∈ V[G] 56 | do c[v] = 0 57 | c[s] = 1 58 | 59 | *** 60 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 61 | 62 | 本节部分答案参考自[这里](http://blog.csdn.net/anye3000/article/details/12091125) 63 | 64 | -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/README.md: -------------------------------------------------------------------------------- 1 | UNSOLVED 2 | 3 | [24.4.4](./24.4.md#exercises-244-4) 4 | [24.4.9](./24.4.md#exercises-244-9) 5 | [24.4.11](./24.4.md#exercises-244-11) 6 | [24.4.12](./24.4.md#exercises-244-12) 7 | 8 | -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C24-Single-Source-Shortest-Paths/repo/s3/1.png -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/repo/s3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C24-Single-Source-Shortest-Paths/repo/s3/2.png -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/repo/s3/24.3-5-equal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C24-Single-Source-Shortest-Paths/repo/s3/24.3-5-equal.png -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/repo/s3/24.3-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C24-Single-Source-Shortest-Paths/repo/s3/24.3-5.png -------------------------------------------------------------------------------- /C24-Single-Source-Shortest-Paths/repo/s3/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C24-Single-Source-Shortest-Paths/repo/s3/3.png -------------------------------------------------------------------------------- /C25-All-Pairs-Shortest-Paths/README.md: -------------------------------------------------------------------------------- 1 | UNSOLVED 2 | 3 | [25.1.4](./25.1.md#exercises-251-4) 4 | [25.1.5](./25.1.md#exercises-251-5) 5 | 6 | [25.2.3](./25.2.md#exercises-252-3) 7 | [25.2.9](./25.2.md#exercises-252-9) 8 | 9 | 10 | -------------------------------------------------------------------------------- /C25-All-Pairs-Shortest-Paths/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C25-All-Pairs-Shortest-Paths/repo/s2/1.png -------------------------------------------------------------------------------- /C25-All-Pairs-Shortest-Paths/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C25-All-Pairs-Shortest-Paths/repo/s2/2.png -------------------------------------------------------------------------------- /C25-All-Pairs-Shortest-Paths/repo/s3/25_3_6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C25-All-Pairs-Shortest-Paths/repo/s3/25_3_6.gif -------------------------------------------------------------------------------- /C26-Flow-networks/26.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 26.3-1 2 | *** 3 | Run the Ford-Fulkerson algorithm on the flow network in Figure 26.8(b) and show the residual network after each flow augmentation. Number the vertices in L top to bottom from 1 to 5 and in R top to bottom from 6 to 9. For each iteration, pick the augmenting path that is lexicographically smallest. 4 | 5 | ### `Answer` 6 | ![](./repo/s3/1.png) 7 | 8 | 9 | ### Exercise 26.3-5 10 | *** 11 | We say that bipartie graph G = (V, E), where V = L ∪ R is d-regular if every vertex v ∈ V has degree exactly d. Every d-regular bipartie graph has |L|=|R|. Prove that every d-regular bipartite graph has a matching of cardinality |L| by arguing that a minimum cut of the corresponding flow network has capacity |L|. 12 | 13 | ### `Answer` 14 | Consider the corresponding network flow graph G' to `k`-regular graph G: 15 | 16 | *** 17 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task. 18 | 19 | -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/FlowEdge.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: FlowEdge.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Fri Nov 13 08:19:03 2015 7 | ************************************************************************/ 8 | 9 | #ifndef FLOW_EDGE_H 10 | #define FLOW_EDGE_H 11 | 12 | #include 13 | using namespace std; 14 | 15 | class FlowEdge { 16 | int v; // from 17 | int w; // to 18 | double capacity; // capacity 19 | double flow; // flow 20 | 21 | public: 22 | FlowEdge() { 23 | this->v = -1; 24 | this->w = -1; 25 | this->capacity = 0; 26 | this->flow = 0.0; 27 | } 28 | 29 | FlowEdge(int v, int w, double capacity) { 30 | this->v = v; 31 | this->w = w; 32 | this->capacity = capacity; 33 | this->flow = 0.0; 34 | } 35 | 36 | FlowEdge(int v, int w, double capacity, double flow) { 37 | this->v = v; 38 | this->w = w; 39 | this->capacity = capacity; 40 | this->flow = flow; 41 | } 42 | 43 | FlowEdge(const FlowEdge &e) { 44 | this->v = e.v; 45 | this->w = e.w; 46 | this->capacity = e.capacity; 47 | this->flow = e.flow; 48 | } 49 | 50 | int from() { 51 | return this->v; 52 | } 53 | 54 | int to() { 55 | return this->w; 56 | } 57 | 58 | double getCapacity() { 59 | return this->capacity; 60 | } 61 | 62 | double getFlow() { 63 | return this->flow; 64 | } 65 | 66 | int other(int vertex) { 67 | if (vertex == v) return this->w; 68 | else return this->v; 69 | } 70 | 71 | double residualCapacityTo(int vertex) { 72 | if (vertex == this->v) return this->flow; // backward edge 73 | else return this->capacity - this->flow; // forward edge 74 | } 75 | 76 | void addResidualFlowTo(int vertex, double delta) { 77 | if (vertex == v) this->flow -= delta; // backward edge 78 | else this->flow += delta; // forward edge 79 | } 80 | 81 | friend ostream& operator << (ostream& out, FlowEdge& fe) 82 | { 83 | out << to_string(fe.v) << "->" << to_string(fe.w) << "\t" 84 | << to_string(fe.flow) << "\t" << to_string(fe.capacity) << endl; 85 | return out; 86 | } 87 | }; 88 | 89 | #endif -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/input.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 10 3 | 0 1 16 4 | 0 2 13 5 | 1 2 10 6 | 2 1 4 7 | 1 3 12 8 | 3 2 9 9 | 2 4 14 10 | 4 3 7 11 | 3 5 20 12 | 4 5 4 13 | -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/makefile: -------------------------------------------------------------------------------- 1 | all: testnetwork testflowedge maxflow 2 | .PHONY:all 3 | 4 | maxflow: FordFulkerson.o 5 | g++ -o maxflow -std=c++11 FordFulkerson.o 6 | 7 | FordFulkerson.o : FordFulkerson.cpp 8 | g++ -c -std=c++11 FordFulkerson.cpp 9 | 10 | testnetwork: testFlowNetwork.o FlowNetwork.o 11 | g++ -o testnetwork -std=c++11 testFlowNetwork.o FlowNetwork.o 12 | 13 | testFlowNetwork.o : testFlowNetwork.cpp 14 | g++ -c -std=c++11 testFlowNetwork.cpp 15 | 16 | FlowNetwork.o : FlowNetwork.cpp 17 | g++ -c -std=c++11 FlowNetwork.cpp 18 | 19 | testflowedge: testFlowEdge.o FlowEdge.o 20 | g++ -o testflowedge testFlowEdge.o FlowEdge.o 21 | 22 | testFlowEdge.o : testFlowEdge.cpp 23 | g++ -c testFlowEdge.cpp 24 | 25 | FlowEdge.o : FlowEdge.cpp 26 | g++ -c FlowEdge.cpp 27 | 28 | clean: 29 | rm testflowedge 30 | rm testFlowEdge.o 31 | rm FlowEdge.o 32 | rm testFlowNetwork.o 33 | rm FlowNetwork.o 34 | rm testnetwork 35 | rm FordFulkerson.o 36 | rm maxflow 37 | -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/readme.md: -------------------------------------------------------------------------------- 1 | [reference](http://algs4.cs.princeton.edu/64maxflow/FordFulkerson.java.html) -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/testFlowEdge.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: testFlowEdge.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Fri Nov 13 08:27:56 2015 7 | ************************************************************************/ 8 | #include 9 | #include "FlowEdge.cpp" 10 | using namespace std; 11 | 12 | int main() { 13 | FlowEdge e(12, 23, 3.14); 14 | cout << e; 15 | return 1; 16 | } -------------------------------------------------------------------------------- /C26-Flow-networks/maxflow/testFlowNetwork.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: testFlowNetwork.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Fri Nov 13 09:16:10 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include "FlowNetwork.cpp" 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | ifstream in("input.txt"); 16 | FlowNetwork G(in); 17 | cout << G; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /C26-Flow-networks/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C26-Flow-networks/repo/s2/1.png -------------------------------------------------------------------------------- /C26-Flow-networks/repo/s2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C26-Flow-networks/repo/s2/2.png -------------------------------------------------------------------------------- /C26-Flow-networks/repo/s3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C26-Flow-networks/repo/s3/1.png -------------------------------------------------------------------------------- /C26-Flow-networks/repo/s3/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C26-Flow-networks/repo/s3/5.png -------------------------------------------------------------------------------- /C31-Number-Theoretic-Algorithms/31.7.md: -------------------------------------------------------------------------------- 1 | ### Exercises 31.7-1 2 | *** 3 | 4 | Consider an RSA key set with `p = 11`, `q = 29`, `n = 319`, and `e = 3`. What 5 | value of `d` should be used in the secret key? What is the encryption of the message `M = 100`? 6 | 7 | ### `Answer` 8 | 9 | We follow the procedure of RSA cryptosystem. 10 | 11 | 1. `n = pq = 319` 12 | 2. `phi(n) = (p-1)(q-1) = 280` 13 | 3. For fixed `e = 3`, apply Euclidean algorithm to find its inverse modulo `(p-1)(q-1)`. We find `1 = 280 - 3 x 93` and the inverse of `e` is `-93 mod 280 = 187` 14 | 4. Hence, `(e, n) = (3, 319)` is the public key and `(d, n) = (187, 319)` is the private key. 15 | 5. For `M = 100`, the cipher text is `100^3 mod 319 = 254`. 16 | -------------------------------------------------------------------------------- /C31-Number-Theoretic-Algorithms/euclid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def gcd(a, b): 5 | while b != 0: 6 | tmp = b 7 | b = a % b 8 | a = tmp 9 | return a 10 | 11 | 12 | print gcd(69,99) 13 | -------------------------------------------------------------------------------- /C31-Number-Theoretic-Algorithms/exercise_code/binary2decimal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def b2d(binary, base): 5 | l = len(binary) 6 | if l == 1: 7 | return int(binary)*base; 8 | mid = l/2 9 | high = binary[:mid] 10 | low = binary[mid:] 11 | return b2d(high, base*(2**(l-mid)))+b2d(low, base) 12 | 13 | binary = "1111" 14 | print b2d(binary,1) -------------------------------------------------------------------------------- /C31-Number-Theoretic-Algorithms/exercise_code/lcm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def gcd(a, b): 5 | while b != 0: 6 | tmp = b 7 | b = a % b 8 | a = tmp 9 | return a 10 | 11 | 12 | def lcm(items): 13 | while True: 14 | if len(items) == 1: 15 | return items[0] 16 | else: 17 | a = items[-1] 18 | b = items[-2] 19 | del items[-1] 20 | del items[-1] 21 | items.append(a*b/gcd(a,b)) 22 | 23 | print lcm([9,12,15]) 24 | -------------------------------------------------------------------------------- /C31-Number-Theoretic-Algorithms/extended_euclid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | def ee(a, b): 5 | if b == 0: 6 | return (a, 1, 0) 7 | res = ee(b, a % b) 8 | return (res[0], res[2], res[1] - a/b*res[2]) 9 | 10 | print ee(99, 78) 11 | print ee(899, 493) 12 | print ee(2,1) 13 | print ee(3,2) 14 | print ee(5,3) 15 | print ee(8,5) 16 | print ee(13,8) 17 | -------------------------------------------------------------------------------- /C32-String-Matching/32.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 32.1-1 2 | *** 3 | Show the comparisons the naive string matcher makes for the pattern P = 0001 in the text T = 000010001010001. 4 | 5 | ### `Answer` 6 | 7 | straightforward. 8 | 9 | 10 | ### Exercises 32.1-2 11 | *** 12 | Suppose that all characters in the pattern P are different. Show how to accelerate NAIVE- 13 | STRING-MATCHER to run in time O(n) on an n-character text T. 14 | 15 | ### `Answer` 16 | If p[i] dismatch T[j],next time trace back to j+1;That is,compare from p[0] and T[j+1]. 17 | 18 | ### Exercises 32.1-3 19 | *** 20 | Suppose that pattern P and text T are randomly chosen strings of length m and n, respectively, from the d-ary alphabet Σd = {0, 1, . . . , d - 1}, where d ≥ 2. Show that the expected number of character-to-character comparisons made by the implicit loop in line 4 of the naive algorithm is 21 | 22 | ![](./repo/s1/1.png) 23 | 24 | over all executions of this loop. (Assume that the naive algorithm stops comparing characters for a given shift once a mismatch is found or the entire pattern is matched.) Thus, for randomly chosen strings, the naive algorithm is quite efficient. 25 | 26 | ### `Answer` 27 | It's a probability problem. 28 | 29 | assume we have to compare (n-m+1) times. 30 | a(n) b(n) 31 | each time: compare 1 1-1/d 32 | 2 1/d*(1-1/d) 33 | 3 (1/d)^2*(1-1/d) 34 | ... ... 35 | m (1/d)^(m-1)*(1-1/d) 36 | then wo can get the T(time) = (n-m+1)*[a(1)*b(1)+a(2)*b(2)+,,,+a(m)*b(m)] 37 | So we get the answer. 38 | 39 | 40 | 41 | ### Exercises 32.1-4 42 | *** 43 | Suppose we allow the pattern P to contain occurrences of a gap character ⋄ that can match 44 | an arbitrary string of characters (even one of zero length). For example, the pattern ab⋄ba⋄c occurs in the text cabccbacbacab as 45 | 46 | ![](./repo/s1/2.png) 47 | 48 | Note that the gap character may occur an arbitrary number of times in the pattern but is assumed not to occur at all in the text. Give a polynomial-time algorithm to determine if such a pattern P occurs in a given text T , and analyze the running time of your algorithm. 49 | 50 | ### `Answer` 51 | To determine if a pattern P with gap characters exists in T partition P into substrings P1 , . . . , Pk determined by the gap characters. Search for P1 and if found continue searching for P2 and so on. This clearly find a pattern if one exists. 52 | 53 | *** 54 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task 55 | -------------------------------------------------------------------------------- /C32-String-Matching/32.2.md: -------------------------------------------------------------------------------- 1 | ### Exercises 32.2-1 2 | *** 3 | Working modulo q = 11, how many spurious hits does the Rabin-Karp matcher encounter in 4 | the text T = 3141592653589793 when looking for the pattern P = 26? 5 | 6 | ### `Answer` 7 | 8 | 15,59,92. 9 | 10 | So there are 3. 11 | 12 | 13 | ### Exercises 32.2-2 14 | *** 15 | How would you extend the Rabin-Karp method to the problem of searching a text string for an occurrence of any one of a given set of k patterns? Start by assuming that all k patterns have the same length. Then generalize your solution to allow the patterns to have different lengths. 16 | 17 | ### `Answer` 18 | 如果k个模式都是等长的,那么算法修改不大.用这些模式模p.然后跑正常的RK算法.遇到有出现在其中的就去匹配一下. 19 | 20 | 如果不等长,可以按长度划分跑多次RK. 21 | 22 | ### Exercises 32.2-3 23 | *** 24 | Show how to extend the Rabin-Karp method to handle the problem of looking for a given m × m pattern in an n × n array of characters. (The pattern may be shifted vertically and horizontally, but it may not be rotated.) 25 | 26 | ### `Answer` 27 | 核心思想是reduce 2d to 1d. 28 | 29 | 对长度为n每一列,我们都能根据RK算法计算出(n-m+1)个hash值.然后对每一行的连续的m个hash值,又能够根据RK的hash算法新算出一个值. 30 | 31 | 也就是说,原来的RK是把算出长度为m的模式的hash值.而现在是先计算出m个长度为m的hash值,再对这m个hash值再一次hash. 32 | 33 | ### Exercises 32.2-4 34 | *** 35 | Alice has a copy of a long n-bit file A = , and Bob similarly has an n-bit file B = . Alice and Bob wish to know if their files are identical. To avoid transmitting all of A or B, they use the following fast probabilistic check. Together, they select a prime q > 1000n and randomly select an integer x from {0, 1, . . . , q - 1}. Then, Alice evaluates 36 | 37 | ![](./repo/s2/1.png) 38 | 39 | and Bob similarly evaluates B(x). Prove that if A ≠ B, there is at most one chance in 1000 that A(x) = B(x), whereas if the two files are the same, A(x) is necessarily the same as B(x). (Hint: See Exercise 31.4-4.) 40 | 41 | ### `Answer` 42 | UNSOLVED 43 | 44 | *** 45 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task 46 | -------------------------------------------------------------------------------- /C32-String-Matching/32.3.md: -------------------------------------------------------------------------------- 1 | ### Exercises 32.3-1 2 | *** 3 | Construct the string-matching automaton for the pattern P = aabab and illustrate its operation on the text string T = aaababaabaababaab. 4 | 5 | ### `Answer` 6 | run my program [FA.c](./FA.c) you will get the answer. 7 | 8 | 9 | ### Exercises 32.3-2 10 | *** 11 | Draw a state-transition diagram for a string-matching automaton for the pattern ababbabbababbababbabb over the alphabet Σ = {a, b}. 12 | 13 | ### `Answer` 14 | run my program [FA.c](./FA.c) then you can draw the diagram. 15 | 16 | ### Exercises 32.3-3 17 | *** 18 | We call a pattern P nonoverlappable if Pk ⊐ Pq implies k = 0 or k = q. Describe the state- transition diagram of the string-matching automaton for a nonoverlappable pattern. 19 | 20 | ### `Answer` 21 | 这样子的模式产生的要么指向下一个状态,要么重新回到状态0. 22 | 23 | ### Exercises 32.3-4 * 24 | *** 25 | Given two patterns P and P′, describe how to construct a finite automaton that determines all 26 | occurrences of either pattern. Try to minimize the number of states in your automaton. 27 | 28 | ### `Answer` 29 | UNSOLVED 30 | 31 | ### Exercises 32.3-5 32 | *** 33 | Given a pattern P containing gap characters (see Exercise 32.1-4), show how to build a finite 34 | automaton that can find an occurrence of P in a text T in O(n) matching time, where n = |T|. 35 | 36 | ### `Answer` 37 | We can construct the finite automaton corresponding to a pattern P using the same idea as in exercise 32.1−4. Partition P into substrings P1, . . . , Pk determined by the gap characters. Construct finite automatons for each Pi and combine sequentially, i.e., the accepting state of Pi, i ∈ [1, k) is no longer accepting but has a single transition to Pi+1. 38 | 39 | *** 40 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task 41 | -------------------------------------------------------------------------------- /C32-String-Matching/32.4.md: -------------------------------------------------------------------------------- 1 | ### Exercises 32.4-1 2 | *** 3 | Compute the prefix function π for the pattern ababbabbabbababbabb when the alphabet is Σ = {a, b}. 4 | 5 | ### `Answer` 6 | run my program [KMP.c](./KMP.c) you will get the answer. 7 | 8 | 9 | ### Exercises 32.4-2 10 | *** 11 | Give an upper bound on the size of π*[q] as a function of q. Give an example to show that your bound is tight. 12 | 13 | ### `Answer` 14 | Since π[q] < q we trivially have |π∗[q]| <= q. This bound is tight as illustrated by the string a^q. Here π[q] = q − 1, π(1)[q] = q − 2, and so on resulting in π∗[q] = {q − 1, . . . , 0}. 15 | 16 | ### Exercises 32.4-3 17 | *** 18 | Explain how to determine the occurrences of pattern P in the text T by examining the π 19 | function for the string PT (the string of length m + n that is the concatenation of P and T). 20 | 21 | ### `Answer` 22 | The indices in which P occurs in PT can be determined as the set M = {q | m ∈ π∗[q] and q >= 2m}. 23 | 24 | ### Exercises 32.4-4 25 | *** 26 | Show how to improve KMP-MATCHER by replacing the occurrence of π in line 7 (but not 27 | line 12) by π′, where π′ is defined recursively for q = 1, 2, . . . , m by the equation 28 | 29 | 0 if π[q] = 0, 30 | π'[q] = π'[π[q]] if π[q] != 0 and p[π[q]+1] = p[q+1] 31 | π[q] if π[q] != 0 and p[π[q]+1] != p[q+1] 32 | 33 | 34 | 35 | Explain why the modified algorithm is correct, and explain in what sense this modification constitutes an improvement. 36 | 37 | ### `Answer` 38 | 本质上和原算法是一样的,就是可以快速的推进,按最大的距离推进. 39 | 40 | ### Exercises 32.4-5 41 | *** 42 | Give a linear-time algorithm to determine if a text T is a cyclic rotation of another string T′. For example, arc and car are cyclic rotations of each other. 43 | 44 | ### `Answer` 45 | [implementation](./exercise_code/str_spin.c) 46 | 47 | ### Exercises 32.4-6 * 48 | *** 49 | Give an efficient algorithm for computing the transition function δ for the string-matching automaton corresponding to a given pattern P. Your algorithm should run in time O(m |Σ|). (Hint: Prove that δ(q, a) = δ(π[q], a) if q = m or P[q + 1] ≠ a.) 50 | 51 | ### `Answer` 52 | UNSOLVED 53 | 54 | *** 55 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task 56 | -------------------------------------------------------------------------------- /C32-String-Matching/BF.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * if find,return first offset 6 | * else return -1 7 | */ 8 | int BF_match(char *text,char *pattern) 9 | { 10 | size_t n = strlen(text); 11 | size_t m = strlen(pattern); 12 | int i; 13 | int end = n-m; 14 | 15 | for(i = 0; i <= end; i++) 16 | { 17 | int j; 18 | char *p_text = text + i; 19 | for(j = 0;j < m;j++) 20 | { 21 | if(*(p_text+j) == *(pattern+j)) 22 | continue; 23 | else 24 | break; 25 | } 26 | if(j == m) 27 | return i; 28 | } 29 | return -1; 30 | } 31 | 32 | int main() 33 | { 34 | char *s1 = "abcabcabcd"; 35 | char *s2 = "abcd"; 36 | int offset = BF_match(s1,s2); 37 | printf("offset is %d\n",offset); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /C32-String-Matching/BM.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int max(int a,int b) 6 | { 7 | if(a > b) 8 | return a; 9 | return b; 10 | } 11 | 12 | /* 13 | * from http://www.cnblogs.com/dsky/archive/2012/05/04/2483190.html 14 | */ 15 | int BM_match(char* pSrc, int nSrcSize, char* pSubSrc, int nSubSrcSize) 16 | { 17 | 18 | //1.坏字符数组 19 | int bcSkip[256]; 20 | int i; 21 | for( i = 0; i < 256; i++) 22 | { 23 | bcSkip[i] = nSubSrcSize; 24 | } 25 | for (i = 0; i < nSubSrcSize - 1; i++) 26 | { 27 | bcSkip[pSubSrc[i]] = nSubSrcSize - i - 1; 28 | } 29 | 30 | //2.好后缀数组 31 | int* suffix =(int*)malloc(nSubSrcSize*sizeof(int)); 32 | suffix[nSubSrcSize - 1] = nSubSrcSize; 33 | for ( i = nSubSrcSize - 2; i >= 0; i--) 34 | { 35 | 36 | int k = i; 37 | while( k >= 0 && pSubSrc[k] == pSubSrc[nSubSrcSize-1-i+k] ) 38 | { 39 | k--; 40 | } 41 | suffix[i] = i - k; 42 | } 43 | 44 | int* gsSkip = (int*)malloc(nSubSrcSize*sizeof(int)); 45 | for (i = 0; i < nSubSrcSize; i++) 46 | { 47 | gsSkip[i] = nSubSrcSize; 48 | } 49 | for ( i = nSubSrcSize - 1; i >= 0; i--) 50 | { 51 | if (suffix[i] == i + 1) 52 | { 53 | int j; 54 | for (j = 0; j < nSubSrcSize - 1 - i; ++j) 55 | { 56 | if (gsSkip[j] == nSubSrcSize) 57 | gsSkip[j] = nSubSrcSize - 1 - i; 58 | } 59 | } 60 | } 61 | for ( i = 0; i <= nSubSrcSize - 2; ++i) 62 | { 63 | gsSkip[nSubSrcSize - 1 - suffix[i]] = nSubSrcSize - 1 - i; 64 | } 65 | 66 | int nPos = 0; 67 | while (nPos <= nSrcSize - nSubSrcSize) 68 | { 69 | int j = nSubSrcSize - 1; 70 | while(j >= 0 && pSubSrc[j] == pSrc[j + nPos]) 71 | { 72 | j--; 73 | } 74 | if (j < 0) 75 | break; 76 | else 77 | { 78 | nPos += max(gsSkip[j], bcSkip[pSrc[j + nPos]]-(nSubSrcSize - 1 - j) ); 79 | } 80 | } 81 | free(gsSkip); 82 | return (nPos > nSrcSize - nSubSrcSize)? -1 : nPos; 83 | } 84 | 85 | 86 | int main() 87 | { 88 | char *s1 = "abcabcabcd"; 89 | char *s2 = "abcd"; 90 | int l1 = strlen(s1); 91 | int l2 = strlen(s2); 92 | int offset = BM_match(s1,l1,s2,l2); 93 | printf("offset is %d\n",offset); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /C32-String-Matching/FA.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define true 1 6 | #define false 0 7 | 8 | int min(int a,int b) 9 | { 10 | if(a > b) 11 | return b; 12 | return a; 13 | } 14 | 15 | //check whether Pk is suffix of Pq 16 | int suffix(char *pattern,int k,int q,char ch) 17 | { 18 | int i; 19 | if(pattern[k-1] != ch) 20 | return false; 21 | for(i = 0;i < k-1;i++) 22 | if(pattern[i] != pattern[q-k+i+1]) 23 | return false; 24 | return true; 25 | } 26 | 27 | /* 28 | * construct our FA 29 | */ 30 | void compute_transition_function(char *pattern,int *array,int numchars) 31 | { 32 | int m = strlen(pattern); 33 | int q; 34 | 35 | for(q = 0; q <= m; q++) 36 | { 37 | int chars; 38 | for(chars = 0; chars < numchars; chars++) 39 | { 40 | int k = min(m,q+1); 41 | while(k) 42 | { 43 | char ch = 'a'+chars; 44 | if(suffix(pattern,k,q,ch)) 45 | break; 46 | k--; 47 | } 48 | array[q*numchars+chars] = k; 49 | } 50 | } 51 | } 52 | 53 | int FA_match(char *text,int *array,int numchars,int receive) 54 | { 55 | int n = strlen(text); 56 | int q = 0; 57 | int i; 58 | for(i = 0;i < n;i++) 59 | { 60 | int index = numchars*q+text[i]-'a'; 61 | q = array[index]; 62 | if(q == receive) 63 | return i+1-receive; 64 | } 65 | return -1; 66 | } 67 | 68 | int main() 69 | { 70 | char *text = "aaababaabaababaab"; 71 | char *pattern = "aabab"; 72 | const int num_chars_alphabet = 2; 73 | int length = strlen(pattern); 74 | int *array = (int*)malloc(sizeof(int)*num_chars_alphabet*(length+1)); 75 | 76 | compute_transition_function(pattern,array,num_chars_alphabet); 77 | 78 | 79 | //This prints a chart showing present state and next states given 80 | //the corresponding inputs. 81 | printf("This is our chart\nstate\t"); 82 | for(char j = 'a'; j < 'a'+num_chars_alphabet; j++) 83 | printf("%c\t", j); 84 | printf("\n"); 85 | 86 | int i; 87 | for(i = 0;i <= length; i++) 88 | { 89 | printf("%d\t",i); 90 | int j; 91 | for(j = 0; j < num_chars_alphabet; j++) 92 | printf("%d\t",array[i*num_chars_alphabet+j]); 93 | printf("\n"); 94 | } 95 | int offset = FA_match(text,array,num_chars_alphabet,length); 96 | printf("offset is %d\n",offset); 97 | free(array); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /C32-String-Matching/KMP.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | * calculate our next array 7 | */ 8 | int* compute_prefix_function(char *pattern) 9 | { 10 | int m = strlen(pattern); 11 | int *next = (int*)malloc(m*sizeof(int)); 12 | next[0]=0; 13 | int k = 0; 14 | int q; 15 | 16 | for(q = 1;q < m;q++) 17 | { 18 | while(k > 0 && (pattern[k] != pattern[q]) ) 19 | k = next[k-1]; 20 | if (pattern[k] == pattern[q]) 21 | k++; 22 | next[q] = k; 23 | } 24 | return next; 25 | } 26 | 27 | int KMP_match(char *text,char *pattern) 28 | { 29 | int n = strlen(text); 30 | int m = strlen(pattern); 31 | int *next = compute_prefix_function(pattern); 32 | int q = 0; 33 | int i; 34 | 35 | for(i = 0;i < n;i++) 36 | { 37 | while(q > 0 && (pattern[q] != text[i]) ) 38 | q = next[q-1]; 39 | if (pattern[q] == text[i]) 40 | q++; 41 | if(q == m) 42 | return i+1-m; 43 | } 44 | free(next); 45 | return -1; 46 | } 47 | 48 | 49 | int main() 50 | { 51 | char *s1 = "bababaababababca"; 52 | char *s2 = "ababababca"; 53 | int offset = KMP_match(s1,s2); 54 | printf("offset is %d\n",offset); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /C32-String-Matching/README.md: -------------------------------------------------------------------------------- 1 | UNSOLVED 2 | 3 | [32.2.4](./32.2.md#exercises-322-4) 4 | [32.3.4](./32.3.md#exercises-323-4) 5 | [32.4.6](./32.4.md#exercises-324-6) 6 | 7 | 8 | -------------------------------------------------------------------------------- /C32-String-Matching/RK.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //we find a prime 11!+1 a seven-digit prime 6 | int factorial(int n) 7 | { 8 | if(n == 1) 9 | return 1; 10 | else 11 | return n*factorial(n-1); 12 | } 13 | 14 | 15 | /* 16 | * d is the base 17 | * and q is the prime wo choose 18 | * if find,return first offset 19 | * else return -1 20 | */ 21 | int RK_match(char *text,char *pattern,int d,int q) 22 | { 23 | size_t n = strlen(text); 24 | size_t m = strlen(pattern); 25 | size_t h = (size_t)pow(d,m-1); 26 | int p = 0; 27 | int t = 0; 28 | int k = 96; //'a' is 1; 'b' is 2 and so on 29 | 30 | int i; 31 | for(i = 0; i < m; i++) 32 | { 33 | p = (d*p+pattern[i]-k)%q; 34 | t = (d*t+text[i]-k)%q; 35 | } 36 | 37 | for(i = 0; i <= (n-m); i++) 38 | { 39 | /* 40 | * we made it a Las Vegas algorithm 41 | * to check if the string really same? 42 | */ 43 | if(p == t) 44 | { 45 | int j; 46 | char *p_text = text+i; 47 | 48 | for(j = 0;j < m;j++) 49 | { 50 | if(*(p_text+j) == *(pattern+j)) 51 | continue; 52 | else 53 | break; 54 | } 55 | if(j == m) 56 | return i; 57 | } 58 | 59 | //calculate the next num 60 | if(i < (n-m)) 61 | { 62 | int s = (d*(t-(text[i]-k)*h))+text[i+m]-k; 63 | t = s%q; 64 | } 65 | } 66 | 67 | return -1; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /C32-String-Matching/exercise_code/str_spin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define true 1 6 | #define false 0 7 | 8 | int f(char *s1,char *s2) 9 | { 10 | if(strlen(s1) != strlen(s2)) 11 | return false; 12 | int n = strlen(s1); 13 | 14 | char *tmp = (char*)malloc(2*n*sizeof(char)); 15 | strcpy(tmp,s1); 16 | strcpy(tmp+n,s1); 17 | printf("tmp = %s\n",tmp); 18 | if((strstr(tmp,s2)) != NULL) 19 | { 20 | free(tmp); 21 | return true; 22 | } 23 | free(tmp); 24 | return false; 25 | } 26 | 27 | int main() 28 | { 29 | char *s1 = "abc"; 30 | char *s2 = "cab"; 31 | 32 | if(f(s1,s2)) 33 | printf("YES!"); 34 | else 35 | printf("NO!"); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /C32-String-Matching/repo/s1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C32-String-Matching/repo/s1/1.png -------------------------------------------------------------------------------- /C32-String-Matching/repo/s1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C32-String-Matching/repo/s1/2.png -------------------------------------------------------------------------------- /C32-String-Matching/repo/s2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C32-String-Matching/repo/s2/1.png -------------------------------------------------------------------------------- /C33-Computational-Geometry/area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YimingCuiCuiCui/Introduction-to-Algorithms-Solutions/7d683b21857af91418dab4f077766c27a8e54910/C33-Computational-Geometry/area.png -------------------------------------------------------------------------------- /C33-Computational-Geometry/exercise_code/area.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct Point{ 6 | float x,y; 7 | }; 8 | 9 | // O(1) 10 | float area(Point a, Point b, Point c){ 11 | return (a.x*(b.y-c.y) + b.x*(c.y - a.y) + c.x*(a.y - b.y))/2.0f; 12 | } 13 | 14 | // O(N) 15 | float calculateAreaOfHull(Point* hull,int N){ 16 | float sum = 0; 17 | for(int i = 1; i < N - 1; i++) 18 | sum += abs(area(hull[0],hull[i],hull[i+1])); // O(1) 19 | return sum; 20 | } 21 | 22 | int main(){ 23 | // Square with 1 unit area 24 | Point test1[4] = {{0,0},{0,1},{1,0},{1,1}}; 25 | cout< File Name: convex_polygon.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Thu Aug 6 17:03:30 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | class Point 14 | { 15 | public: 16 | float x; 17 | float y; 18 | Point(float _x, float _y):x(_x),y(_y){} 19 | 20 | Point operator +(const Point &that) const 21 | { 22 | return Point(x+that.x, y+that.y); 23 | } 24 | 25 | Point operator -(const Point &that) const 26 | { 27 | return Point(x-that.x, y-that.y); 28 | } 29 | 30 | Point& operator =(const Point &that) 31 | { 32 | if (this == &that) 33 | return *this; 34 | x = that.x; 35 | y = that.y; 36 | return *this; 37 | } 38 | }; 39 | 40 | float crossProduct(const Point &p1, const Point &p2) 41 | { 42 | return p1.x*p2.y - p2.x*p1.y; 43 | } 44 | 45 | float direction(const Point &pi, const Point &pj, const Point &pk) 46 | { 47 | return crossProduct(pk-pi, pj-pi); 48 | } 49 | 50 | bool isConvexPolygon(Point points[], int n) 51 | { 52 | bool f1,f2; 53 | f1 = f2 = false; 54 | 55 | for(int i = 0;i < n;i++) 56 | { 57 | Point p1 = points[i]; 58 | Point p2 = points[(i+1)%n]; 59 | Point p3 = points[(i+2)%n]; 60 | float d = direction(p2, p1, p3); 61 | 62 | if(d > 0 && f2) return false; 63 | if(d < 0 && f1) return false; 64 | if(d > 0) f1 = true; 65 | if(d < 0) f2 = true; 66 | } 67 | if(!f1 && !f2) return false; 68 | 69 | return true; 70 | } 71 | 72 | int main() { 73 | Point p1(0,0); 74 | Point p2(1,1); 75 | Point p3(2,2); 76 | Point points[3] = {p1,p2,p3}; 77 | bool fff = isConvexPolygon(points, 3); 78 | 79 | if(fff) cout << "yes" << endl; 80 | else cout << "no" << endl; 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /C33-Computational-Geometry/exercise_code/polarCMP.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: polarCMP.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Thu Aug 6 17:03:30 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | class Point 14 | { 15 | public: 16 | float x; 17 | float y; 18 | Point(float _x, float _y):x(_x),y(_y){} 19 | 20 | Point operator +(const Point &that) const 21 | { 22 | return Point(x+that.x, y+that.y); 23 | } 24 | 25 | Point operator -(const Point &that) const 26 | { 27 | return Point(x-that.x, y-that.y); 28 | } 29 | 30 | Point& operator =(const Point &that) 31 | { 32 | if (this == &that) 33 | return *this; 34 | x = that.x; 35 | y = that.y; 36 | return *this; 37 | } 38 | 39 | friend ostream& operator << (ostream& os, const Point &p) 40 | { 41 | os << "x: " << p.x << " y: " << p.y << endl; 42 | return os; 43 | } 44 | }; 45 | 46 | bool myfunc(const Point &p1, const Point &p2) 47 | { 48 | if (p1.y > 0 && p2.y < 0) return true; 49 | else if(p1.y < 0 && p2.y > 0) return false; 50 | 51 | if ((p1.x*p2.y - p2.x*p1.y) < 0) 52 | return false; 53 | return true; 54 | } 55 | 56 | int main() { 57 | Point p0(1,1); 58 | Point p1(3,0); 59 | Point p2(2,2); 60 | Point p3(0.5,3); 61 | Point p4(-2,2); 62 | Point p5(-1,-2); 63 | 64 | Point points[5] = {p1,p2,p3,p4,p5}; 65 | for(int i = 0;i < 5;i++) 66 | points[i] = points[i] - p0; 67 | 68 | sort(points, points+5, myfunc); 69 | 70 | for(int i = 0;i < 5;i++) 71 | cout << (points[i]+p0); 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /C33-Computational-Geometry/twoline.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: twoline.cpp 3 | > Author: Louis1992 4 | > Mail: zhenchaogan@gmail.com 5 | > Blog: http://gzc.github.io 6 | > Created Time: Thu Aug 6 17:03:30 2015 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | class Point 14 | { 15 | public: 16 | float x; 17 | float y; 18 | Point(float _x, float _y):x(_x),y(_y){} 19 | 20 | Point operator +(const Point &that) const 21 | { 22 | return Point(x+that.x, y+that.y); 23 | } 24 | 25 | Point operator -(const Point &that) const 26 | { 27 | return Point(x-that.x, y-that.y); 28 | } 29 | 30 | Point& operator =(const Point &that) 31 | { 32 | if (this == &that) 33 | return *this; 34 | x = that.x; 35 | y = that.y; 36 | return *this; 37 | } 38 | }; 39 | 40 | float crossProduct(const Point &p1, const Point &p2) 41 | { 42 | return p1.x*p2.y - p2.x*p1.y; 43 | } 44 | 45 | float direction(const Point &pi, const Point &pj, const Point &pk) 46 | { 47 | return crossProduct(pk-pi, pj-pi); 48 | } 49 | 50 | bool onSegmant(const Point &pi, const Point &pj, const Point &pk) 51 | { 52 | if (min(pi.x, pj.x) <= pk.x && max(pi.x, pj.x) >= pk.x && min(pi.y, pj.y) <= pk.y && max(pi.y, pj.y) >= pk.y) 53 | return true; 54 | return false; 55 | } 56 | 57 | bool segmentsInterect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) 58 | { 59 | float d1 = direction(p3, p4, p1); 60 | float d2 = direction(p3, p4, p2); 61 | float d3 = direction(p1, p2, p3); 62 | float d4 = direction(p1, p2, p4); 63 | if ( ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)) ) 64 | return true; 65 | else if (abs(d1) < 1e-8 && onSegmant(p3, p4, p1)) 66 | return true; 67 | else if (abs(d2) < 1e-8 && onSegmant(p3, p4, p2)) 68 | return true; 69 | else if (abs(d3) < 1e-8 && onSegmant(p1, p2, p3)) 70 | return true; 71 | else if (abs(d4) < 1e-8 && onSegmant(p1, p2, p4)) 72 | return true; 73 | return false; 74 | } 75 | 76 | int main() { 77 | Point p1(0,0); 78 | Point p2(5,0); 79 | Point p3(2,2); 80 | Point p4(2,-2); 81 | cout << segmentsInterect(p1,p2,p3,p4) << endl; 82 | cout << segmentsInterect(p1,p3,p2,p4) << endl; 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /C35-Approximation-Algorithms/35.1.md: -------------------------------------------------------------------------------- 1 | ### Exercises 35.1-1 2 | *** 3 | Give an example of a graph for which APPROX-VERTEX-COVER always yields a suboptimal solution. 4 | 5 | ### `Answer` 6 | 7 | A graph with two node u,v and an edge(u,v). The optimal is either u or v. By running 8 | APPROX-VERTEX-COVER we get u and v. It is always a suboptimal solution. 9 | 10 | ### Exercises 35.1-2 11 | *** 12 | Let A denote the set of edges that were picked in line 4 of APPROX-VERTEX-COVER. 13 | Prove that the set A is a maximal matching in the graph G. 14 | 15 | ### `Answer` 16 | It is obvious. Because in line 4, we randomly choose an edge (u,v) and delete all edges incident on either u or v. The remaining graph becomes a subproblem. 17 | 18 | *** 19 | Follow [@louis1992](https://github.com/gzc) on github to help finish this task 20 | -------------------------------------------------------------------------------- /C35-Approximation-Algorithms/35.2-5.md: -------------------------------------------------------------------------------- 1 | # Exercise 35.2-5 2 | 3 | *** 4 | Suppose that the vertices for an instance of the traveling-salesman problem are points in the plane and that the cost *c(u,v)* is the euclidean distance between points *u* and *v*. Show that an optimaol tour never crosses itself. 5 | 6 | ## Solution 7 | 8 | Cost function based on euclidean distance satisfies the triangle-inequality, s.t.: 9 | 10 | ``` c(u,v) <= c(u,w) + c(w,v) ``` 11 | 12 | Assume: The tour corsses itself. 13 | 14 | Let *(u,v)* and *(w,x)* be corssing edges, *u -> v -> w -> x* the assumed optimal tour and P the crossing point of *(u,v)* and *(w,x)*. 15 | 16 | Based on the triangle-inequality its: 17 | ```c(x,v) <= c(x,P) + c(P,v) ``` 18 | 19 | Thus we can derive: 20 | 21 | ```c(u,P) + c(P,w) + c(x,P) + c(P,v) + c(u,w) + c(w,v) >= c(u,w) + c(x,v) * c(u,x) + c(w,v)``` 22 | 23 | Based on our definition its ```c(u,P) + c(P,v) = c(u,v)``` and ```c(x,P) + c(P,w) = c(x,w)``` 24 | 25 | Therefore its ``` c(u,v) + c(v,w) >= c(u,w) + c(x,v)``` which denotes in combination with (u,x) and (v,w) a shorter tour then the original one. Contradiction. q.e.d 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Zhenchao Gan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /other/Karatsuba/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | string multiply(string &num1, string &num2) { 7 | string sum(num1.size() + num2.size(), '0'); 8 | 9 | for (int i = num1.size() - 1; 0 <= i; --i) { 10 | int carry = 0; 11 | for (int j = num2.size() - 1; 0 <= j; --j) { 12 | int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry; 13 | sum[i + j + 1] = tmp % 2 + '0'; 14 | carry = tmp / 2; 15 | } 16 | sum[i] += carry; 17 | } 18 | 19 | size_t startpos = sum.find_first_not_of("0"); 20 | if (string::npos != startpos) { 21 | return sum.substr(startpos); 22 | } 23 | return "0"; 24 | } 25 | 26 | 27 | int main(int argc, char **argv) { 28 | /* 29 | string str = string(argv[1]); 30 | int k = stoi(str); 31 | k = (int)pow(2,k); 32 | string s(k,'1'); 33 | multiply(s,s); 34 | return 0; 35 | */ 36 | 37 | ifstream in("input.txt"); 38 | ofstream out("output.txt"); 39 | int n; in >> n; 40 | string num1,num2; 41 | in >> num1; 42 | in >> num2; 43 | 44 | string res = multiply(num1,num2); 45 | 46 | out << res; 47 | 48 | in.close(); 49 | out.close(); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /other/Karatsuba/makefile: -------------------------------------------------------------------------------- 1 | all: longmultiplication karatsuba 2 | .PHONY:all 3 | 4 | longmultiplication: main.o 5 | g++ -o longmultiplication main.o; rm main.o 6 | 7 | main.o : main.cpp 8 | g++ -c -O3 main.cpp 9 | 10 | karatsuba: Karatsuba.o 11 | g++ -o karatsuba Karatsuba.o; rm Karatsuba.o 12 | 13 | Karatsuba.o : Karatsuba.cpp 14 | g++ -c -O3 Karatsuba.cpp 15 | -------------------------------------------------------------------------------- /other/segmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct SegmentTreeNode { 7 | int start, end, sum; 8 | SegmentTreeNode *left, *right; 9 | SegmentTreeNode(int start, int end, int sum) { 10 | this->start = start; 11 | this->end = end; 12 | this->sum = sum; 13 | this->left = this->right = nullptr; 14 | } 15 | }; 16 | 17 | class NumArray { 18 | 19 | SegmentTreeNode* root; 20 | 21 | SegmentTreeNode* build(int start, int end, const vector& A) { 22 | if (start > end) return nullptr; 23 | else if (start == end) { 24 | SegmentTreeNode *tree = new SegmentTreeNode(start, end, A[start]); 25 | return tree; 26 | } else { 27 | SegmentTreeNode *left = build(start, (start+end)/2, A); 28 | SegmentTreeNode *right = build((start+end)/2+1, end, A); 29 | SegmentTreeNode *tree = new SegmentTreeNode(start, end, left->sum + right->sum); 30 | tree -> left = left; 31 | tree -> right = right; 32 | return tree; 33 | } 34 | } 35 | 36 | void modify(SegmentTreeNode *root, int i, int val) { 37 | if (root->start == root->end) { 38 | root->sum = val; 39 | return; 40 | } 41 | if (i <= root->left->end) modify(root->left, i, val); 42 | else modify(root->right, i, val); 43 | root->sum = root->left->sum + root->right->sum; 44 | } 45 | 46 | int query(SegmentTreeNode *root, int i, int j) { 47 | if (root->start == root->end) return root->sum; 48 | if (root->start == i && root->end == j) return root->sum; 49 | 50 | if(j <= root->left->end) { 51 | return query(root->left, i, j); 52 | } else if (i >= root->right->start) { 53 | return query(root->right, i, j); 54 | } else { 55 | return query(root->left, i, root->left->end) + query(root->right, root->right->start, j); 56 | } 57 | } 58 | 59 | public: 60 | NumArray(vector &nums) { 61 | root = build(0, nums.size()-1, nums); 62 | } 63 | 64 | void update(int i, int val) { 65 | modify(root, i, val); 66 | } 67 | 68 | int sumRange(int i, int j) { 69 | return query(root, i, j); 70 | } 71 | }; 72 | 73 | int main() { 74 | vector nums{1, 2, 3}; 75 | NumArray numArray(nums); 76 | cout << numArray.sumRange(0, 1) << endl; 77 | numArray.update(1, 10); 78 | cout << numArray.sumRange(1, 2) << endl; 79 | } -------------------------------------------------------------------------------- /other/stringSpilit.cpp: -------------------------------------------------------------------------------- 1 | vector split(const string &s, char delim) { 2 | vector elems; 3 | stringstream ss(s); 4 | string item; 5 | while (getline(ss, item, delim)) { 6 | if (item.length() > 0) { 7 | elems.push_back(item); 8 | } 9 | } 10 | return elems; 11 | } 12 | -------------------------------------------------------------------------------- /other/trie.cpp: -------------------------------------------------------------------------------- 1 | struct TrieNode { 2 | TrieNode *nodes[26]; 3 | bool word; 4 | // Initialize your data structure here. 5 | TrieNode(): word(false) { 6 | memset(nodes, 0, sizeof(nodes)); 7 | } 8 | }; 9 | 10 | class Trie { 11 | 12 | public: 13 | Trie() { 14 | root = new TrieNode(); 15 | } 16 | 17 | // Inserts a word into the trie. 18 | void insert(const string& s) { 19 | TrieNode *tmp = root; 20 | for(char ch : s) { 21 | int index = ch - 'a'; 22 | if(tmp->nodes[index] == nullptr) { 23 | tmp->nodes[index] = new TrieNode(); 24 | } 25 | tmp = tmp->nodes[index]; 26 | } 27 | tmp->word = true; 28 | } 29 | 30 | // Returns if the word is in the trie. 31 | bool search(const string& key) const { 32 | TrieNode *tmp = root; 33 | for(char ch : key) { 34 | int index = ch - 'a'; 35 | if(tmp->nodes[index] == nullptr) { 36 | return false; 37 | } 38 | tmp = tmp->nodes[index]; 39 | } 40 | return tmp->word; 41 | } 42 | 43 | // Returns if there is any word in the trie 44 | // that starts with the given prefix. 45 | bool startsWith(const string& prefix) const { 46 | TrieNode *tmp = root; 47 | for(char ch : prefix) { 48 | int index = ch - 'a'; 49 | if(tmp->nodes[index] == nullptr) { 50 | return false; 51 | } 52 | tmp = tmp->nodes[index]; 53 | } 54 | return true; 55 | } 56 | 57 | private: 58 | TrieNode* root; 59 | }; --------------------------------------------------------------------------------