Skip to content

Commit a685810

Browse files
committed
Initial commit
0 parents  commit a685810

File tree

12 files changed

+412
-0
lines changed

12 files changed

+412
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

Chapter1/Chapter1.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<notice>教程读者请不要直接阅读本文件,因为诸多功能在此无法正常使用,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)学习完整教程。如果您喜欢我们的教程,请在右上角给我们一个“Star”,谢谢您的支持!</notice>
2+
递归
3+
======
4+
5+
从这里开始学习吧!💖
6+
7+
递归方法
8+
------
9+
**递归方法**(recursion methods)简单地说就是直接或间接地调用自己的方法。比如这就是一个最简单的递归方法:
10+
```java
11+
public void recursion()
12+
{
13+
recursion();
14+
}
15+
```
16+
17+
千万别运行这个函数!因为如果我们主动调用了`recursion()`,然后在这个方法里`recursion()`会再调用,然后又再次调用……一直这样下去,导致电脑卡住,最后还会导致Java报错(实际上是一个叫做“栈”的结构存不下了),程序被迫退出。
18+
19+
递归的最简形式
20+
-----
21+
22+
要理解递归,我们要先理解****(stack)这个概念。栈就像烤串的签,我们往里插东西(叫压栈或者入栈,push),先插进去的在下,后插进去的在上,并且最后拿(叫出栈,pop)的时候,只有上面拿出来了才能拿出下面的。在Java里,每调用一个函数都是往栈里面存储了一个新的状态,就像往签上插了东西一样。
23+
24+
在Java里,每调用一个函数都会先暂停当前函数的状态,然后用一个新的状态来从头执行这个函数。这两个函数中定义的变量可以是不相同的。
25+
26+
知道了栈的定义,接下来让我们来看一个递归的小例子:
27+
28+
<lab lang="java" parameters="filename=Hello.java">
29+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
30+
public class Hello {
31+
public static void main(String[] args) {
32+
recursion(3);
33+
}
34+
public static void recursion(int val) {
35+
System.out.println(val);
36+
if(val>0){
37+
recursion(val-1);
38+
}
39+
}
40+
}
41+
</lab>
42+
43+
运行以后我们会发现输出了3、2、1和0。这是因为首先我们调用了`recursion`函数并给了参数3,根据上面的说明,在栈上压入了`recursion`这个状态,并且里面的`val`是3,然后输出3。然后又调用了一次`recursion`,参数为`2`,又压栈,输出2。一直这样下去,直到最后状态中的`val`值为0,`if`语句不执行为止。然后我们碰到了函数的末尾,释放出来,最后结束,依次反过来释放三个栈中的状态。
44+
45+
除了上面的那个会一直运行下去的递归函数,每个递归函数都有两个部分:
46+
1. 一个基本的条件来终止递归的继续调用
47+
2. 非基本条件使递归向基本条件运行
48+
也就是说,递归的最终目的是遇到那个我们需要的“基本条件”,然后就不继续递归了。
49+
50+
在上面的例子中,让`val`不再大于0就是我们所需要达到的目的,达到目的之后我们就会终止调用本身了,我们在这个方法的结尾调用了`recursion`,后面就没有内容了,这样的递归就是结尾递归(tail recursion)。
51+
52+
分析递归函数
53+
------
54+
比如我们有如下的一个递归函数:
55+
```java
56+
public static int fib(int n){
57+
if(n == 1||n == 2){
58+
return 1;
59+
} else {
60+
return fib(n - 1) + fib(n - 2);
61+
}
62+
```
63+
于是我们就要开始展开分析工作了,首先我们可以发现,在n == 1或n == 2的时候这个方法会返回1,其他时候会返回fib(n - 1) + fib(n - 2),也就可以写成如下函数(n是正整数):
64+
![Pic1](Pic1.png)
65+
然后我们开始计算函数的返回值,从fib(5)开始,通过对数学函数的分析我们可以画出如下的分析图。
66+
![Pic2](Pic2.png)
67+
因为每一个函数都会调用两个函数,所以树状分析图看起来会比栈图简洁明了,从下往上,把下面的两个小树枝(子节点)的数值计算出来,相加就得到上面的数值,最后就能计算出fib(5)了,结果是5
68+
69+
递归的注意事项
70+
------
71+
从上面的分析图可以看出,函数`fib`每一次递归都需要调用两个子函数,而这两个子函数又会调用其它函数。刚才我们说过,函数调用的时候需要使用栈来存储当前函数和调用的函数的状态,因此在有大量函数调用的情况下,就要频繁访问栈来存取函数的状态,这样就会消耗掉大量的时间。因此如果有简单的循环能解决这个问题,就尽量不要使用递归来解决。另外递归还有如下需要注意的地方:
72+
1. 在递归中尽量不要使用过多局部变量、局部数组,因为在函数调用时计算机要再次初始化局部变量、局部数组,而这样会消耗大量时间
73+
2. 只在递归可以大量简化代码的时候使用,如果能用循环等简单解决就不要使用递归
74+
3. 递归在以下两个方面很有用:分支树的处理和二进制等分支搜索
75+
4. 可以使用帮助方法(helper method)来调用递归,这样可以使代码更简洁
76+
77+
小练习
78+
------
79+
让我们来练习一下我们刚学习的知识吧。
80+
<lab lang="java" parameters="filename=Hello.java">
81+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
82+
public class Hello {
83+
public static void main(String[] args) {
84+
// 在这里输入代码
85+
}
86+
}
87+
</lab>

Chapter1/Pic1.png

18.9 KB
Loading

Chapter1/Pic2.png

35.7 KB
Loading

Chapter2/Chapter2.md

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<notice>教程读者请不要直接阅读本文件,因为诸多功能在此无法正常使用,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)学习完整教程。如果您喜欢我们的教程,请在右上角给我们一个“Star”,谢谢您的支持!</notice>
2+
排序
3+
======
4+
5+
在这一章,我们要学习几种在计算机算法中极其重要的排序算法,让我们这就开始吧!💖
6+
7+
所谓的**排序**(sorting),就是让一个数组里的数,按照从大到小或者从小到大排列。下面是几种常用的排序算法:
8+
9+
选择排序
10+
------
11+
**选择排序**(selection sort)就是首先在数组中找到最小的一个值放在第一位,然后再找次小的放到第二位,以此类推一直到n-1次排序后,就能够得到一个递增的数列了。
12+
13+
以下是选择排序在Java里的一种实现,大家可以在纸上用一个实验数据来演算一遍:
14+
```java
15+
/*
16+
@param elements an array containing the items to be sorted.
17+
18+
Postcondition: elements contains its original items and items
19+
in elements are sorted in ascending order.
20+
*/
21+
public static void selectionSort(int[] elements){
22+
for (int j = 0; j <elements.length){
23+
int minIndex = j;
24+
for (int k = j+1; k < elements .length;k++){
25+
if (elements[k]<elements[minIndex])
26+
minIndex = k;
27+
}
28+
int temp = elements[j];
29+
elements[j]= elements[minIndex];
30+
elements[minIndex] = temp;
31+
}
32+
}
33+
```
34+
35+
插入排序
36+
-----
37+
**插入排序**(insertion sort)的原本是一个排列好的数组插入一个数组。当我们把第一个数elements[0]看成一个数组时,我们就能够对整个数组进行插入排列。我们是将要插入的数组的第一个数拿出来,一个一个往前推,看哪个合适插在哪里。之后依次类推。
38+
e.g.蓝色是我们已经排好的数组,红色为未排好的。
39+
![Pic1](Pic1.png)
40+
```java
41+
/*
42+
@param elements an array containing the items to be sorted.
43+
44+
Postcondition: elements contains its original items and items
45+
in elements are sorted in ascending order.
46+
*/
47+
public static void insertionSort(int[] elements){
48+
for(int j = 1; j< elements.length; j++){
49+
int temp = elements[j];
50+
int possibleIndex = j;
51+
while(possibleIndex > 0 && temp < elements[possibleIndex - 1]){
52+
elements[possibleIndex] = elements[possibleIndex - 1];
53+
possibleIndex --;
54+
}
55+
elements[possibleIndex] = temp;
56+
}
57+
}
58+
```
59+
60+
归并排序
61+
------
62+
**归并排序** (merge esort)是一种递归排序,它将数组拆成几个小的单元,之后对小的单元进行排序。然后再把小的单元组合在一起再进行排序。
63+
它的缺点十分明显:它需要储存一个跟原始数组一样长的数据。它还有个显著特点,就是排序时间不受原本数据排序的影响,不论是最好的情况还是最坏的情况。
64+
65+
```java
66+
public static void mergeSort(int[] elements){
67+
int n = elements.length;
68+
int[] temp = new int[n];
69+
mergeSortHelper(elements,0,n-1,temp);
70+
}
71+
72+
/*
73+
* @param elements, an array containing the items to be sorted.
74+
* @param from, the begining index of the items in elements to be sorted.
75+
* @param to, the ending index of the itens in elements to be sorted.
76+
* @param temp, a temporary array to use during the merge process.
77+
* Precondition:
78+
* (elements.length == 0 ||
79+
* 0<= from <= to <= elements.length &&
80+
* elements.length == temp.length)
81+
* Postcondition:
82+
* elements contains its original items and the items in
83+
* elements[from]...<= elements[to] are sorted in ascending order
84+
*/
85+
private static void mergeSortHelper(int[] elements, int from, int to, int[] temp){
86+
if (from < to){
87+
int middle = (from + to)/2;
88+
mergeSortHelper(elements, from , middle, temp);
89+
mergeSortHelper(elements, middle+1, to, temp);
90+
merge(elements, from, middle,to,temp);
91+
}
92+
}
93+
94+
private static void merge(int[] elements, int from, int mid, int to, int[] temp){
95+
int i = from;
96+
int j = mid +1;
97+
int k = from;
98+
99+
while(i<=mid && j <=to){
100+
if(elements[i]<elements[j]){
101+
temp[k] = elements[i];
102+
i++;
103+
}
104+
else{
105+
temp[k] = elements[j];
106+
j++
107+
}
108+
k++;
109+
}
110+
while (i <= mid){
111+
temp[k] = elements[i];
112+
i++;
113+
k++;
114+
}
115+
116+
while(j<=to){
117+
temp[k] = elements[j];
118+
j++;
119+
k++
120+
}
121+
122+
for (k = from; k<=to; k++)
123+
elements[k] = temp[k];
124+
}
125+
```
126+
小练习
127+
------
128+
让我们来练习一下我们刚学习的知识吧。
129+
<lab lang="java" parameters="filename=Hello.java">
130+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
131+
public class Hello {
132+
public static void main(String[] args) {
133+
// 在这里输入代码
134+
}
135+
}
136+
</lab>

Chapter2/Pic1.png

197 KB
Loading

Chapter3/Chapter3.md

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<notice>教程读者请不要直接阅读本文件,因为诸多功能在此无法正常使用,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)学习完整教程。如果您喜欢我们的教程,请在右上角给我们一个“Star”,谢谢您的支持!</notice>
2+
搜索
3+
======
4+
**搜索**(searching)在这里指的是从数组中找出指定的内容所在的位置。
5+
6+
顺序搜索
7+
------
8+
**顺序搜索**(sequential searching)就是把数组从头到尾搜索一遍,直到找到所要找的元素或者搜索完所有元素为止。
9+
10+
以下是顺序搜索在Java里的一种实现:
11+
```java
12+
/***
13+
@param elements an array containing the items to be searched
14+
@param target the item to be found in element.
15+
@return an index of target in elements if foun; -1 otherwise;
16+
***/
17+
public static int sequentialSerach(int[] elements, int target){
18+
for (int j = 0; j< elements.length; j++)
19+
if (elements[j == target]) //String uses equals()
20+
return j;
21+
return -1;
22+
}
23+
```
24+
25+
二叉搜索
26+
-----
27+
**二叉搜索**(binary search)是一种高效率的检索方法。将搜索范围逐渐一步一步二分(分为两部分)减小到只剩下一个。
28+
29+
其思想就是我们查看一个数组中间的内容,如果比我们想要的大,那么我就在左边搜索,
30+
如果比我们想要的小,我们就在右边搜索。然后在缩小后的搜索范围查看判断后数组中间的数,就这样依次进行下去,直到找到结果或者全部搜索完成。不过,利用二进制搜索的数组必须是排列好的,否则比如先排序才行。
31+
32+
```java
33+
/*
34+
@param elements an array containing the items to be sorted.
35+
36+
Postcondition: elements contains its original items and items
37+
in elements are sorted in ascending order.
38+
*/
39+
public static void insertionSort(int[] elements){
40+
for(int j = 1; j< elements.length; j++){
41+
int temp = elements[j];
42+
int possibleIndex = j;
43+
while(possibleIndex > 0 && temp < elements[possibleIndex - 1]){
44+
elements[possibleIndex] = elements[possibleIndex - 1];
45+
possibleIndex --;
46+
}
47+
elements[possibleIndex] = temp;
48+
}
49+
}
50+
```
51+
52+
小练习
53+
------
54+
让我们来练习一下我们刚学习的知识吧。
55+
<lab lang="java" parameters="filename=Hello.java">
56+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
57+
public class Hello {
58+
public static void main(String[] args) {
59+
// 在这里输入代码
60+
}
61+
}
62+
</lab>

Example.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<notice>教程读者请不要直接阅读本文件,因为诸多功能在此无法正常使用,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)学习完整教程。如果您喜欢我们的教程,请在右上角给我们一个“Star”,谢谢您的支持!</notice>
2+
3+
初入编程
4+
======
5+
6+
有的时候我们想知道这个小人在哪里,这样怎么办呢?
7+
8+
条件块
9+
------
10+
拖动左边的条件块,就可以产生条件效果。
11+
12+
其他条件块
13+
------
14+
拖动左边的条件块,就可以产生条件效果。
15+
```java
16+
if (this.successful) {
17+
// We'll succeed
18+
} else {
19+
// No! We won't reach this
20+
}
21+
```
22+
Blocks实验室:
23+
<lab lang="blocks" parameters="logic=false&math=false&loops=false&lists=false&color=false&variables=false&functions=false&text=false">
24+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
25+
</lab>
26+
27+
Java实验室:
28+
<lab lang="java" parameters="filename=Hello.java">
29+
<notice>练习环境在此无法显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>
30+
public class Hello {
31+
public static void main(String[] args) {
32+
System.out.println("Hello Java!");
33+
}
34+
}
35+
</lab>
36+
37+
下面的内容要按一下才会显示:
38+
<cr type="hidden"><notice>隐藏内容功能在此无法正常显示,请移步至[程谱 coderecipe.cn](https://coderecipe.cn/learn/5)查看。</notice>答案已经被显示出来了</cr>

README.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Java算法基础教程 by 程谱 Code Recipe
2+
3+
** 如果你喜欢我们的教程,那么就点击右上角的“Star”给我们贡献一份力量吧~ **
4+
5+
欢迎来到程谱社区!😁 我们是一群留学生,致力于搭建一个系统而又不枯燥的零基础入门编程学习平台。希望大家能多多支持我们,如果发现我们的不足之处也欢迎联系我们~
6+
7+
这个教程给初学编程者使用,是大多数程谱学员学完[Java Array和ArrayList教程](https://coderecipe.cn/learn/4)以后的教程。这个教程主要配合Java介绍编程的基础知识概念,对学习和备考AP以及入门计算机编程都会很有帮助。
8+
9+
最后,谢谢大家对程谱的支持和厚爱~💖
10+
11+
P.S: 教程读者请不要直接阅读本项目的文件,因为诸多功能在此无法正常使用,请移步至[程谱官网](https://coderecipe.cn/learn/5)免费学习这个教程的完整版哦。
12+
13+
目录
14+
------
15+
1. 递归
16+
* 递归方法
17+
* 递归的最简形式
18+
* 分析递归函数
19+
* 递归的注意事项
20+
* 小练习
21+
2. 排序
22+
* 选择排序
23+
* 插入排序
24+
* 归并排序
25+
* 小练习
26+
3. 搜索
27+
* 顺序搜索
28+
* 二叉搜索
29+
* 小练习
30+
31+
看完目录以后,如果你想学习本教程,那么就点击[这里](https://coderecipe.cn/learn/5)里开始吧。
32+
33+
贡献
34+
------
35+
如果你发现教程有错别字或者有不妥之处,欢迎提交issues或者pull requests,成为本教程的contributor,程谱项目组及本教程作者感谢您的支持!
36+
37+
使用本教程
38+
------
39+
本项目为程谱项目组编写,我们推荐教师直接使用程谱网站来作为教学工具。
40+
41+
为了搭建一个友好互助的社区,我们同样也允许您以**在醒目处保留“本教程来源于程谱”并链接到[程谱](https://coderecipe.cn/learn/5)的方式****非商业用途**使用本教程。其他使用方式请[联系我们](mailto:[email protected])获得许可。
42+
43+
一切对本教程的最终解释权归程谱所有。
44+
45+
致谢
46+
------
47+
本教程参考了AP CS A手册的部分内容,在此向作者Tony和刘淼致谢。

0 commit comments

Comments
 (0)