第一章 基础
内容总览:
- 算法和数据结构所使用的基本工具
- 基础编程模型
- 模块化编程(数据抽象)(ADT)
- 三种抽象数据类型(背包,栈,队列)
- 算法性能分析方法
- 连通性问题实战
引子:
欧几里得算法
用于求解两个整数的最大公约数
算法描述:
计算2个非负整数p和q 的最大公约数:若q是0,则最大公约数是p。否则,将p除以q得到余数r,p和q的最大公约数即为q和r的最大公约数。
java代码实现,此处使用两种方法实现,分别是递归实现和迭代实现,并且利用对数器来验证了两种方法的正确性
//递归写法
public static int gcd(int p, int q) {
if (q == 0) return p;
int r = p % q;
return gcd(q, r);
}
//迭代写法
public static int gcd2(int p, int q) {
while (q != 0) {
int r = p % q;
p = q;
q = r;
}
return p;
}
对数器验证:
Random r = new Random();
for (int i = 0; i < 10000; i++) {
int p = r.nextInt(10000);
int q = r.nextInt(10000);
if (gcd(p, q) != gcd2(p, q)) {
System.out.println(p + "," + q);
}
}
补充知识:对数器是通过一组正确的数据,来验证另一组数据是否正确的方法。以上述代码为例子,通过验证比较两种欧几里得算法实现的结果的异同,可以确定算法的正确性。递归和迭代都使用了同样的数据,那么结果应该也是一样的,如果有不同的结果,将其输入数据输出,即可纠正算法的错误。
基础编程模型
描述和实现算法所用到的语言特性,软件库和操作系统特性总称为基础编程模型。
完整的java程序示例–二分查找算法
public static int rank(int key, int[] arr) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (arr[mid] == key) {
return mid;
} else if (arr[mid] > key) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
二分查找算法的对数器验证:
首先创建一个DataTools.java ,作为我们的工具类,有些常用的方法和工具,可以生成指定长度的随机数组(无序和有序),并且编写了一个用于整型的对数器。这里我偷了个懒,只能比较整型,熟悉java 的同学,可以利用java 的泛型和比较器接口来实现一个通用的对数器。
DataTools.java
package com.edfeff.algorithm.graph.p01.utils;
import java.util.Arrays;
import java.util.Random;
public class DataTools {
/**
* 随机数生成器
*/
public static int[] randIntArr(int num) {
Random random = new Random();
int[] res = new int[num];
for (int i = 0; i < num; i++) {
res[i] = random.nextInt(10000);
}
return res;
}
/**
* 有序随机数生成器
*
* @param num
* @return
*/
public static int[] randSortIntArr(Integer num) {
Random random = new Random();
int[] res = new int[num];
for (int i = 0; i < num; i++) {
res[i] = random.nextInt(10000);
}
Arrays.sort(res);
return res;
}
/**
* 展示数据
*
* @param arr
*/
public static void showArr(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
/**
* 整数数组比较器
*
* @param arr
* @param brr
* @return
*/
public static boolean compareInts(int[] arr, int[] brr) {
if (arr.length != brr.length) {
return false;
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] != brr[i]) {
return false;
}
}
return true;
}
}
使用暴力查找和对数器验证
public static int rankIter(int key, int[] arr) {
for (int i = 0; i < arr.length; i++) {
if (key == arr[i]) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
int[] ints = DataTools.randSortIntArr(10);
int[] res1 = new int[ints.length];
int[] res2 = new int[ints.length];
for (int i = 0; i < ints.length; i++) {
res1[i] = rank(ints[i], ints);
res2[i] = rankIter(ints[i], ints);
}
boolean com = DataTools.compareInts(res1, res2);
}
这篇博客主要介绍了基础编程模型,包括在Java中实现的完整程序示例——二分查找算法,通过递归和迭代两种方式,并使用对数器验证算法的正确性。此外,还探讨了数据工具类DataTools.java的创建,用于生成随机数组和对数器功能。
1499

被折叠的 条评论
为什么被折叠?



