今天随便翻了翻Java数据结构与算法这本书,写了一些常见的简单算法。当练习一下。当然代码不是十分完善,只是演示算法而已。
/**
* 排序、查找算法
* @author sunlong
*
*/
public class OrderArray {
private int[] arr;
private int length;
public OrderArray(int size){
arr = new int[size];
length = 0;
}
/**
* 未检查边界,有序插入
* @param value
*/
public void insert(int value){
int pos = length;
for(int i=0; i<length; i++){
if(arr[i] > value){
pos = i;
break;
}
}
for(int j = length; j > pos; j--){
arr[j] = arr[j-1];
}
arr[pos] = value;
length++;
}
/**
* 无序插入
* @param value
*/
public void insertNoOrder(int value){
arr[length++] = value;
}
/**
* 二分查找
* @param value
* @return
*/
public int find(int value){
int lower = 0, higher = length-1, current = (lower+higher)/2;
while(lower <= higher){
if(arr[current] == value){
return current;
}else if(arr[current] > value){
higher = current - 1;
}else{
lower = current + 1;
}
current = (lower+higher)/2;
}
return -1;
}
public int find2(int value){
return findDiGui(0, length-1, value);
}
/**
* 递归的二分查找
* @return
*/
public int findDiGui(int lower, int higher, int value){
int current = (lower+higher)/2;
if(lower > higher) return -1;
if(arr[current] == value){
return current;
}else if(arr[current] > value){
higher = current - 1;
}else{
lower = current + 1;
}
return findDiGui(lower, higher, value);
}
public void print(){
for(int i=0; i<length; i++)
System.out.print(arr[i]+",");
System.out.println();
}
/**
* 冒泡排序
* 比较相临的两个元素
*/
public void bubbleSort(){
int tmp;
for(int i=length-1; i>=0; i--){
for(int j=0; j<i; j++){
if(arr[j]>arr[j+1]){
tmp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = tmp;
}
}
}
}
/**
* 选择排序改进了冒泡排序,使得交换次数从o(n*n)降到o(n)
* 选择排序是第一遍扫描选择最小的值,然后和0位置交换,接着再选择次小的值和1位置交换,直到全部完成
*/
public void selectSort(){
if(length == 0) return ;
int min = 0, tmp;
for(int j=0; j<length; j++){
for(int i=j+1; i<length; i++){
if(arr[min] > arr[i]){
min = i;
}
}
tmp = arr[min];
arr[min] = arr[j];
arr[j] = tmp;
}
}
/**
* 插入排序,通常比冒泡和选择排序要好,虽然比较o(n*n)
* 它以局部有序为前提
* 假设标记的左边全部有序,则要在左边插入这个标记的值。
*/
public void insertSort(){
int tmp;
for(int i=1; i<length; i++){
tmp = arr[i];
int j = i;
while(j>0 && arr[j-1]>tmp){
arr[j] = arr[j-1];
j--;
}
arr[j] = tmp;
}
}
/**
* 归并排序o(n*logN),比冒泡、选择、插入排序要好
* 思想是归并两个已经有序的数组,把一个数组一分为二,再一分为二……
*/
public void mergeSort(){
int[] workspace = new int[length];
recMerge(workspace, 0, length-1);
}
private void recMerge(int[] workspace, int lower, int higher){
if(lower == higher) return;
else{
int mid = (lower + higher)/2;
recMerge(workspace, lower, mid);
recMerge(workspace, mid+1, higher);
merge(workspace, lower, mid, higher);
}
}
/**
* 合并两个数组,分别是arr数组中的lower至mid,还有一个是mid+1至higher
* 合到workspace中,然后把workspace中数据复制到lower至higher中
* @param workspace
* @param lower
* @param mid
* @param higher
*/
private void merge(int[] workspace, int lower, int mid, int higher){
int left = lower;
int right = mid+1;
int index = 0;
while(left<=mid && right<=higher){
if(arr[left] < arr[right]){
workspace[index++] = arr[left++];
}else{
workspace[index++] = arr[right++];
}
}
//有可能left部分的数组没有考完,但是right已经结束了,所以不需要再比较,直接把
//left部分剩余的数复制过去即可
while(left<=mid){
workspace[index++] = arr[left++];
}
//同上分析
while(right<=higher){
workspace[index++] = arr[right++];
}
int n = higher-lower+1;
for(int i=0; i<n; i++){
arr[lower+i] = workspace[i];
}
}
/**
* 希尔排序是对插入排序的一种改进,它使用n-增量法,首先对间隔n的数进行排序,然后逐渐减少间隔n直到变成1,此时
* 数组基本有序,那么再进行插入排序,将大大提高插入排序的效率
* 间隔算法可以用Knuth提出的算法,间隔以1开始,逆向使用。
* 算法为n=3*n+1,n初始为1,递归生成
* 比如1,然后n=3*1+1=4,然后n=3*4+1=13……
*
* 举例来说10个数,h=4,则(0,4,8) (1,5,9) (2,6) (3,7)
* 在排序时每组先比较前两个数,排完返回,再对第三个数处理,所以实际上是
* (0,4) (1,5) (2,6) (3,7) (0, 4, 8) (1, 5, 9)
* 当然个人觉得可以按小组来排完再说,我的写法是基于此方式
*/
public void shellSort(){
/*个人按理解写的希尔排序*/
int h = 1;
while(h<=length/3){
h = h*3 + 1;
}
int tmp;
while(h>0){
for(int span=0; span<h; span++){
for(int i=(h+span); i<length; i+=h){//每组进行插入排序
tmp = arr[i];
int index = i;//index用于向前遍历
while(index>=h && arr[index-h]> tmp){
arr[index] = arr[index-h];//向右移动数据
index -= h;
}
arr[index] = tmp;
}
}
h = (h-1)/3;
}
/*以下是Java数据结构与算法中的写法
int inner, outer;
int temp;
int h = 1;
while (h <= length/3){
h = h*3 + 1;
}
while (h > 0) {
for (outer = h; outer < length; outer++) {
temp = arr[outer];
inner = outer;
while (inner > h - 1 && arr[inner - h] >= temp) {
arr[inner] = arr[inner - h];
inner -= h;
}
arr[inner] = temp;
}
h = (h - 1) / 3;
}*/
}
}
分享到:
相关推荐
在项目中,"Sortshow"可能是一个包含所有相关代码的类或包,其中包含了用于创建GUI界面、启动线程、更新界面显示以及具体实现三种排序算法的函数。使用Java多线程可以确保排序过程的动态展示不影响主程序的运行,...
在Java编程语言中,接口(Interface)是一种定义行为规范的关键概念。它允许我们定义一组抽象方法,供不同的类实现,从而实现多态性。在这个"java接口练习作业"中,我们将会探讨接口的使用,以及如何将其应用于集合...
这份"java基础各部分小程序练习题"集合,无疑为初学者提供了一个绝佳的学习和实践平台。作者无私地分享了他在学习过程中所做的练习,这是一份宝贵的资源,可以帮助学习者检验和巩固自己的Java知识。 首先,我们要...
### Java冒泡排序知识点解析 #### 一、冒泡排序基本概念 冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,依次...通过上述几种实现方式的对比,我们可以更好地理解和掌握冒泡排序的核心思想及其优化方法。
**题目描述**: 公鸡五钱一只,母鸡三钱一只,小鸡一钱三只,现有百钱欲买百鸡,共有多少种买法? **知识点**: 通过穷举法解决实际问题。使用三层嵌套循环分别表示三种鸡的数量,通过条件判断找到符合条件的组合。 ...
### Java基础练习题知识点解析 #### 程序1:兔子繁殖问题 - **知识点**: - 数列计算:本题涉及一个典型的斐波那契数列问题,即每个月的兔子数量形成一个数列,从第三个月开始,每月的兔子总数等于前两个月兔子...
Java的主要特点和优势包括以下几个方面: 跨平台性(Write Once, Run Anywhere): Java的代码可以在不同的平台上运行,只需编写一次代码,就可以在任何支持Java的设备上执行。这得益于Java虚拟机(JVM),它充当了...
以下是对标题和描述中提到的几种排序算法的详细解释: 1. **插入排序**: - **直接插入排序**:将未排序的元素逐个插入到已排序的序列中,每次插入都需要与已排序的部分进行比较,找到合适的位置插入。 - **折半...
【程序1】涉及的知识点是斐波那契数列,这是一种经典的递归序列,每项数字是前两项数字的和...以上这些题目覆盖了基础的算法、逻辑控制、数学运算以及数据类型处理等多个Java编程的基础知识点,是很好的编程练习题目。
上述文件中的几个数组练习涵盖了数组定义、初始化、遍历、复制和排序等基本操作。 1. **数组定义和创建**: 在Java中,数组通过`类型[] 名称`的形式定义。例如,`int arr[]`定义了一个整型数组。数组的创建是通过`...
在初学者的Java分页练习中,通常会涵盖以下几个方面: 1. 学习和理解分页的基本原理。 2. 实现简单的SQL查询分页,理解`LIMIT`和`OFFSET`的用法。 3. 掌握如何在Java中执行SQL查询并处理分页结果。 4. 学习使用...
Java是一种广泛使用的面向对象的编程语言,这些练习题涵盖了Java的基础知识,包括语法、类与对象、访问修饰符、线程以及异常处理等方面。以下是对这些知识点的详细解释: 1. **编译Java程序**:Java程序的编译是...
Java课程设计练习题涵盖了几种不同的编程挑战,旨在帮助学习者深入理解和应用Java语言的关键概念。下面是这些练习题的详细解析: 1. **排序算法动画**:这个练习要求设计一个程序,通过动画形式展示各种排序算法...
冒泡排序和链表是两种基础且重要的数据处理方法,它们在计算机科学,尤其是Java编程中扮演着关键角色。 冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们...
【程序 15】排序问题,可以使用冒泡排序、选择排序等基础排序算法,也可以用更高效的算法如快速排序、归并排序,但这里最简单的是两两比较并交换。 【程序 16】打印9乘法口诀表是简单的双重循环应用,外层循环控制...
Java 是一种广泛应用于企业级开发的编程语言,以下是 Java 练习经典题型的知识点总结: 1. 递归函数:在程序 1 中,我们使用递归函数来解决兔子繁殖问题。递归函数是一种函数调用自身的函数,通过不断调用自身来...
描述中没有给出具体信息,但从标签和部分内容来看,我们可以深入探讨以下几个Java编程相关的知识点: 1. **排序算法的动画实现**: - 快速排序:基于分治策略的高效排序算法,通过选取一个基准元素并将其与其他...
Java编程基础练习题涵盖了许多核心概念,这些概念是学习Java编程的基础。以下是对这些练习题中涉及知识点的详细解释: 1. **斐波那契数列**:在第一题中,要求计算兔子数量,这涉及到斐波那契数列。斐波那契数列是...
这个"java 编的小程序 作业"集合包含了几个基本的编程概念和算法,是学习Java编程的良好实践。 首先,我们来看看"有阶乘"这个标签。阶乘是一个数学概念,表示一个正整数n的所有小于等于n的正整数的乘积,通常用n!...
在实现冒泡排序时,需要注意以下几点: 1. 内部循环用于控制比较和交换的过程,外部循环用于控制整个排序过程的迭代次数。 2. 使用一个标志变量来检查在某次遍历中是否发生了交换,如果没发生交换,则说明序列已有序...