《算法》第一章部分程序 part 1
▶ 书中第一章部分程序,加上自己补充的代码,包括若干种二分搜索,寻找图上连通分量数的两种算法
● 代码,二分搜索
package package01; import java.util.Arrays;
import edu.princeton.cs.algs4.StdRandom; public class class01
{
public int binarySearch(int [] a, int target) // 非递归实现
{
int lp = 0, rp = a.length - 1;
for(;lp <= rp;) // 含等号的条件,后面修改 lp 和 rp 是使用强的跳跃条件
{
int mp = lp + (rp - lp) / 2;
if (target < a[mp])
rp = mp - 1; // 不要使用 mp 作为跳跃条件,会导致死循环
else if (target > a[mp])
lp = mp + 1;
else
return mp;
}
return -1;
} public int binarySearchRecursion(int [] a, int target)// 递归实现
{
return binarySearchRecursionKernel(a,target,0,a.length-1);
} private int binarySearchRecursionKernel(int [] a, int target, int lp, int rp)
{
for(;lp<=rp;)
{
int mp = lp + (rp - lp) / 2;
if (target < a[mp])
return binarySearchRecursionKernel(a,target,lp,mp - 1);
else if (target > a[mp])
return binarySearchRecursionKernel(a,target,mp + 1, rp);
else
return mp;
}
return -1;
} public static void main(String[] args)
{
int N = 10000;
int [] a = new int [N];
for(int i=0;i<N;i++)
a[i] = i;//(int)(StdRandom.uniform()*10000); // 注释部分留作随机检验
//Arrays.sort(a); int target = 7919;//(int)(StdRandom.uniform()*10000);
int output1 = binarySearch(a,target);
int output2 = binarySearchRecursion(a,target); System.out.printf("\n%d,%d\n",output1,output2);
return;
}
}
● 重复元素二分搜索,包括查找第一次出现、最后一次出现,以及出现多少次
package package01; import java.util.Arrays;
import edu.princeton.cs.algs4.StdRandom; public class class01
{
public int binarySearchFirst(int [] a, int target) // 寻找第一个等于键值的目标
{
return binarySearchFirstKernel(a, target, 0, a.length-1);
} private int binarySearchFirstKernel(int [] a, int target,int lp,int rp) // 添加起点和终点(两端点都包含),为了能与 Count 函数配合
{
for(;lp<=rp;)
{
int mp = lp + (rp - lp) / 2;
if (target < a[mp])
rp = mp - 1;
else if (target > a[mp])
lp = mp + 1;
else if(mp == 0 || target > a[mp-1]) // target == a[mp],找第一个
return mp; // a[mp] 就是第一个
else // a[mp] 前面还有等值的,不能强跳跃,否则可能跨空
rp = mp;
}
return -1;
} public int binarySearchLast(int [] a, int target) // 寻找最后一个等于键值的目标
{
return binarySearchLastKernel(a,target, 0, a.length-1);
} private int binarySearchLastKernel(int [] a, int target,int lp, int rp) // 添加起点和终点(两端点都包含)
{
for(;lp<=rp;)
{
int mp = lp + (rp - lp) / 2;
if (target < a[mp])
rp = mp - 1;
else if (target > a[mp])
lp = mp + 1;
else if(mp == a.length-1 || target < a[mp+1]) // target == a[mp],找最后一个
return mp; // a[mp] 就是第一个
else // a[mp] 后面还有等值的,不能强跳跃,否则可能跨空
lp = mp;
}
return -1;
} public int binarySearchCount(int [] a, int target) // 寻找等于键值的元素个数
{
int lp = 0, rp = a.length-1;
for(;lp<=rp;)
{
int mp = lp + (rp - lp) / 2;
if (target < a[mp])
rp = mp - 1;
else if (target > a[mp])
lp = mp + 1;
else // 找到元素后,搜查首个和最后一个进行计数
return binarySearchLastKernel(a,target,lp,rp) - binarySearchFirstKernel(a,target,lp,rp) + 1;
}
return -1;
} public static void main(String[] args)
{
int N = 10000;
int [] a = new int [N];
for(int i=0;i<N;i++)
a[i] = i/100;//(int)(StdRandom.uniform()*10000); // 用于随机测试
//Arrays.sort(a); int target = 29;//(int)(StdRandom.uniform()*10000); // 可以检验边界 0,99 等情况
int output1 = binarySearchFirst(a,target);
int output2 = binarySearchLast(a,target);
int output3 = binarySearchCount(a,target); System.out.printf("\n%d,%d,%d\n",output1,output2,output3);
return;
}
}
● 数组随机化
package package01; public class class01
{
public static void shuffle(Object[] a)
{
int n = a.length;
for (int i = 0; i < n; i++)// 每次在 a[0] ~ a[i] 中随机挑一个 a[r],交换 a[i] 与a[r]
{
int r = (int)(Math.random() * (i + 1));
Object swap = a[r];
a[r] = a[i];
a[i] = swap;
}
} public static void shuffle2(Object[] a)
{
int n = a.length;
for (int i = 0; i < n; i++)// 每次在 a[i] 右边随机挑一个 a[r],交换 a[i] 与a[r]
{
int r = i + (int)(Math.random() * (n - i));
Object swap = a[r];
a[r] = a[i];
a[i] = swap;
}
} public static void main(String[] args)
{
String[] a = { "0","1","2","3","4","5","6","7","8","9" };
class01.shuffle(a);
for (int i = 0; i < a.length; i++)
System.out.print(a[i]); System.out.print("\n"); String[] b = { "0","1","2","3","4","5","6","7","8","9" };
class01.shuffle2(b);
for (int i = 0; i < a.length; i++)
System.out.print(b[i]); return;
}
}
● 计算图连通分量的算法。输入文件第一行是节点数,后面每行是一个连接的两端节点编号,用 java class01 < inputFile.txt 来运行。
package package01; import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut; public class class01
{
private int[] parent; // 节点祖先标记
private int[] rank; // 树深度,仅根节点有效
private int count; // 节点数 public class01(int n)
{
count = n;
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = i;
rank[i] = 1; // 源代码用的是 0
}
} public int find(int p) // 寻找 p 的根标号
{
for (validate(p); p != parent[p]; p = parent[p]);
return p;
} public int count() // 节点数
{
return count;
} public boolean connected(int p, int q) // 判断 p 与 q 是否连通
{
return find(p) == find(q);
} public void union(int p, int q) // 合并 p 和 q
{
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ)
return; if (rank[rootP] < rank[rootQ]) // 较小树连接到较大树的树根上,树高按最大值计算
parent[rootP] = rootQ;
else if (rank[rootP] > rank[rootQ])
parent[rootQ] = rootP;
else // 两树等大,合并后树高增一
{
parent[rootQ] = rootP;
rank[rootP]++;
}
count--; // 合并后连接分量减少
} public void union2(int p, int q) // 合并 p 和 q,第二种方法,更快
{
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ)
return; if (rank[rootP] < rank[rootQ])
{
parent[rootP] = rootQ;
rank[rootQ] += rank[rootP]; // 树高按加和计算
}
else
{
parent[rootQ] = rootP;
rank[rootP] += rank[rootQ];
}
count--;
} private void validate(int p) // 判断输入的 p 是否合法
{
if (p < 0 || p >= parent.length)
throw new IllegalArgumentException("\np = " + p + "is illegal\n");
} public static void main(String[] args)
{
int n = StdIn.readInt();
class01 uf = new class01(n);
for (; !StdIn.isEmpty();)
{
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q))
continue;
uf.union(p, q);
//StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
《算法》第一章部分程序 part 1的更多相关文章
- 《算法》第一章部分程序 part 2
▶ 书中第一章部分程序,加上自己补充的代码,包括简单的计时器,链表背包迭代器,表达式计算相关 ● 简单的计时器,分别记录墙上时间和 CPU 时间. package package01; import ...
- C语言编程入门之--第一章初识程序
第一章 初识程序 导读:计算机程序无时不刻的影响着人类的生活,现代社会已经离不开程序,程序的作用如此巨大,那么程序到底是什么呢?本章主要讨论程序的概念,唤起读者对程序的兴趣,同时对C语言程序与其它语言 ...
- windows核心编程-第一章 对程序错误的处理
第一章-对程序错误的处理 在开始介绍Microsoft Windows 的特性之前,必须首先了解 Wi n d o w s的各个函数是如何进行错误处理的. 当调用一个Wi n d o w s函数时,它 ...
- 第一章 Python程序语言简介
第一节 Python概述 1. 什么是Python Python是一种 解释型.面向对象.动态数据类型 的高级程序设计语言.由Guido van Rossum与1989年发明,第一个公开发行版本发行于 ...
- ASP.NET本质论第一章网站应用程序学习笔记3-对象化的Http
在.NET环境下,万物皆对象,在HttpRuntime收到请求之后,立即将通过HttpWorkerRequest传递的参数进行分析和分解,创建方便用于网站应用程序处理用的对象,其中主要涉及到两个对象类 ...
- ASP.NET本质论第一章网站应用程序学习笔记2
1.初步走进ASP.NET 上篇笔记我们讲述了服务器监听问题,这篇我们就要讲述具体的请求处理了,ASP.NET所涉及的类大多数定义在System.Web程序集中. 在.NET中,程序集管理的最小逻辑单 ...
- ASP.NET本质论第一章网站应用程序学习笔记1
1.统一资源标示符 1) 格式:协议://主机[.端口号][绝对路径[?参数]],在Http://www.kencery.com/hyl/index/login中,http表示协议的名称,www.ke ...
- 《程序是怎样跑起来的》读书笔记——第一章 对程序员来说CPU是什么
1 程序的运行流程 2 CPU的组成 3 寄存器的主要种类和功能 "程序计数器"--决定程序流程的 4 条件分支和循环机制 4.1 顺序执行 4.2 选择分支 5 函数的调用机制 ...
- 【学习总结】java数据结构和算法-第一章-内容介绍和授课方式
总目录链接 [学习总结]尚硅谷2019java数据结构和算法 github:javaDSA 目录 几个经典算法面试题 算法和数据结构的重要性 几个经典算法面试题 字符串匹配 暴力法:慢 kmp算法:更 ...
随机推荐
- Jquery模板-----JsRender
重新排版与堂堂88 先看下简单示例: <script type="type='text/html'" id="jianren"> <div c ...
- 最短路径算法——Dijkstra算法与Floyd算法
转自:https://www.cnblogs.com/smile233/p/8303673.html 最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1 ADE:2 ...
- sql 语句收集
SELECT type as 'plan cache store', buckets_count FROM sys.dm_os_memory_cache_hash_tables WHERE type ...
- 实现java随机数Random的几招
一,在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,可以产生随机整数.随机float.随机double,随机long,这个也是我们经常用的一个 ...
- 测试教程网.unittest教程.7. 各种断言方法
From: http://www.testclass.net/pyunit/assert/ 背景 unittest支持各种断言方法. 断言列表 官方文档 方法 检查点 assertEqual(a, b ...
- 【java】之java代码的执行机制
要在JVM中执行java代码必须要编译为class文件,JDK是如何将Java代码编译为class文件,这种机制通常被称为Java源码编译机制. 1.JVM定义了class文件的格式,但是并没有定义如 ...
- Hadoop概念学习系列之Hadoop集群动态增加新节点或删除已有某节点及复制策略导向 (四十三)
不多说,直接上干货! hadoop-2.6.0动态添加新节点 https://blog.csdn.net/baidu_25820069/article/details/52225216 Hadoop集 ...
- levenshtein函数
Levenshtein算法已在部分DBMS中实现. (例如:PostgreSQL:http://www.postgresql.org/docs/9.1/Static/fuzzystrmedi.html ...
- ylbtech-Java-Runoob-高级教程-实例-数组:15. Java 实例 – 判断数组是否相等
ylbtech-Java-Runoob-高级教程-实例-数组:15. Java 实例 – 判断数组是否相等 1.返回顶部 1. Java 实例 - 判断数组是否相等 Java 实例 以下实例演示了如 ...
- java 泛型 checkcast
我们来看一段代码 public class Test3 { public static void main(String args[]) throws IllegalAccessException, ...