`
sunlong
  • 浏览: 85577 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

Java几种排序小练习

阅读更多

今天随便翻了翻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;
		}*/
	}
}
 
0
0
分享到:
评论

相关推荐

    java几种基本排序(动态演示)

    在项目中,"Sortshow"可能是一个包含所有相关代码的类或包,其中包含了用于创建GUI界面、启动线程、更新界面显示以及具体实现三种排序算法的函数。使用Java多线程可以确保排序过程的动态展示不影响主程序的运行,...

    java 接口练习作业

    在Java编程语言中,接口(Interface)是一种定义行为规范的关键概念。它允许我们定义一组抽象方法,供不同的类实现,从而实现多态性。在这个"java接口练习作业"中,我们将会探讨接口的使用,以及如何将其应用于集合...

    java基础各部分小程序练习题

    这份"java基础各部分小程序练习题"集合,无疑为初学者提供了一个绝佳的学习和实践平台。作者无私地分享了他在学习过程中所做的练习,这是一份宝贵的资源,可以帮助学习者检验和巩固自己的Java知识。 首先,我们要...

    java冒泡排序.txt

    ### Java冒泡排序知识点解析 #### 一、冒泡排序基本概念 冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,依次...通过上述几种实现方式的对比,我们可以更好地理解和掌握冒泡排序的核心思想及其优化方法。

    java基础练习题

    **题目描述**: 公鸡五钱一只,母鸡三钱一只,小鸡一钱三只,现有百钱欲买百鸡,共有多少种买法? **知识点**: 通过穷举法解决实际问题。使用三层嵌套循环分别表示三种鸡的数量,通过条件判断找到符合条件的组合。 ...

    java基础练习50题

    ### Java基础练习题知识点解析 #### 程序1:兔子繁殖问题 - **知识点**: - 数列计算:本题涉及一个典型的斐波那契数列问题,即每个月的兔子数量形成一个数列,从第三个月开始,每月的兔子总数等于前两个月兔子...

    Java练习算法代码(排序,数据结构,小算法练习题).zip

    Java的主要特点和优势包括以下几个方面: 跨平台性(Write Once, Run Anywhere): Java的代码可以在不同的平台上运行,只需编写一次代码,就可以在任何支持Java的设备上执行。这得益于Java虚拟机(JVM),它充当了...

    java各种数组排序(插入,交换,选择,归类,基数排序).pdf

    以下是对标题和描述中提到的几种排序算法的详细解释: 1. **插入排序**: - **直接插入排序**:将未排序的元素逐个插入到已排序的序列中,每次插入都需要与已排序的部分进行比较,找到合适的位置插入。 - **折半...

    java必做练习50题

    【程序1】涉及的知识点是斐波那契数列,这是一种经典的递归序列,每项数字是前两项数字的和...以上这些题目覆盖了基础的算法、逻辑控制、数学运算以及数据类型处理等多个Java编程的基础知识点,是很好的编程练习题目。

    java编程基础—数组练习.docx

    上述文件中的几个数组练习涵盖了数组定义、初始化、遍历、复制和排序等基本操作。 1. **数组定义和创建**: 在Java中,数组通过`类型[] 名称`的形式定义。例如,`int arr[]`定义了一个整型数组。数组的创建是通过`...

    分页技术与java练习

    在初学者的Java分页练习中,通常会涵盖以下几个方面: 1. 学习和理解分页的基本原理。 2. 实现简单的SQL查询分页,理解`LIMIT`和`OFFSET`的用法。 3. 掌握如何在Java中执行SQL查询并处理分页结果。 4. 学习使用...

    java练习题练习题集

    Java是一种广泛使用的面向对象的编程语言,这些练习题涵盖了Java的基础知识,包括语法、类与对象、访问修饰符、线程以及异常处理等方面。以下是对这些知识点的详细解释: 1. **编译Java程序**:Java程序的编译是...

    java课程设计练习题.pdf

    Java课程设计练习题涵盖了几种不同的编程挑战,旨在帮助学习者深入理解和应用Java语言的关键概念。下面是这些练习题的详细解析: 1. **排序算法动画**:这个练习要求设计一个程序,通过动画形式展示各种排序算法...

    JAVA:冒泡排序和链表.docx

    冒泡排序和链表是两种基础且重要的数据处理方法,它们在计算机科学,尤其是Java编程中扮演着关键角色。 冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们...

    java算法练习试题

    【程序 15】排序问题,可以使用冒泡排序、选择排序等基础排序算法,也可以用更高效的算法如快速排序、归并排序,但这里最简单的是两两比较并交换。 【程序 16】打印9乘法口诀表是简单的双重循环应用,外层循环控制...

    java练习经典题型

    Java 是一种广泛应用于企业级开发的编程语言,以下是 Java 练习经典题型的知识点总结: 1. 递归函数:在程序 1 中,我们使用递归函数来解决兔子繁殖问题。递归函数是一种函数调用自身的函数,通过不断调用自身来...

    java 课程设计练习题.pdf

    描述中没有给出具体信息,但从标签和部分内容来看,我们可以深入探讨以下几个Java编程相关的知识点: 1. **排序算法的动画实现**: - 快速排序:基于分治策略的高效排序算法,通过选取一个基准元素并将其与其他...

    50道JAVA基础编程练习题

    Java编程基础练习题涵盖了许多核心概念,这些概念是学习Java编程的基础。以下是对这些练习题中涉及知识点的详细解释: 1. **斐波那契数列**:在第一题中,要求计算兔子数量,这涉及到斐波那契数列。斐波那契数列是...

    java 编的小程序 作业

    这个"java 编的小程序 作业"集合包含了几个基本的编程概念和算法,是学习Java编程的良好实践。 首先,我们来看看"有阶乘"这个标签。阶乘是一个数学概念,表示一个正整数n的所有小于等于n的正整数的乘积,通常用n!...

    冒泡排序和递归求和实现

    在实现冒泡排序时,需要注意以下几点: 1. 内部循环用于控制比较和交换的过程,外部循环用于控制整个排序过程的迭代次数。 2. 使用一个标志变量来检查在某次遍历中是否发生了交换,如果没发生交换,则说明序列已有序...

Global site tag (gtag.js) - Google Analytics