常见排序算法总结(java实现)

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。常见的排序算法有选择排序,插入排序,希尔排序,归并排序和快速排序

由于在排序的过程中不可避免的要涉及到比较和交换,所以将他们抽取为两个单独的函数,如下所示

//为了排序代码的通用性,这里假定待排序的元素实现了Comparable接口
	private static boolean less(Comparable v ,Comparable w){
			return v.compareTo(w)<0;
	}
	private static void exch(Comparable[] a ,int i,int j){
		Comparable t = a[i];a[i] = a[j]; a[j] = t;
	}

选择排序

算法思想:首先,找到数组中最小的那个元素,然后将其和数组中第一个元素交换位置。再从剩下的元素中找到最小的元素,将其和数组中的第二个元素交换位置,如此这般,直到整个数组全部有序。

算法特点:1.运行时间和输入无关。不管输入的数据是一个已经有序的数组,或者是一个随机的数组,其所需要的比较次数是一样的。

2.数组的移动是最少的。由于每一次都是选择一个最小的元素然后交换其位置,所以每次交换都能排定一个元素,因此总的交换次数是N。

	public static void selectionSort(Comparable[] a){
		int N= a.length;
		for(int i=0;i<N;i++){
			int min =i;			//假定第一个数为最小
			for(int j=i+1;j<N;j++)
				if(less(a[j],a[min]))
					min = j;	//获取最小元素的下标
			exch(a,i,min);		//交换位置
		}
	}

插入排序

算法思想:首先,假定数组中第一个元素是有序的,然后将第二个元素插入到前面有序数组的合适位置,组成一个新的有序数组,再将第三个元素插入到前面的有序数组中,如此这般,知道数组整体有序。

算法特点:运行时间和初始输入有关。如果初始输入的数据已经有序或者部分有序的时候,插入排序的性能会比较好。

	public static void insertionSort(Comparable[] a){
		int N = a.length;
		for(int i=1;i<N;i++){	//待插入的元素下标
			for(int j=i;j>0;j--)	//在前面有序的数组中寻找合适的插入位置
				if(less(a[j],a[j-1]))
					exch(a, j, j-1);
		}
	}

希尔排序

算法思想:希尔排序的思想是使数组中任意间隔为h的元素都是有序的,这样的数组被称之为h-有序数组。我们不断减少h的值,使其最终变为一个1-有序数组。1-有序数组,也就是数组整体有序,这样排序就算完成了。

希尔排序最难的地方在于h序列的选择。目前还没有方法证明某一种序列是最好的。

public static void sort(Comparable[] a){
		int N = a.length;
		int h = 1;		//用来记录步长
		while(h<N/3)	h=3*h+1;	//步长为1,4,13,40……
		while(h>=1){
			for(int i=h;i<N;i++)
				for(int j=i;j>=h;j-=h)	//将a[i]插入到a[i-h],a[i-2*h],a[i-3*h]……之中
					if(less(a[j],a[j-h]))
						exch(a,j,j-h);
			h=h/3;	//将前面记录的步长反过来,最终使其为1-有序数组
		}
	}

归并排序

算法思想:要将一个数组进行排序,可以递归的将其分为两半分别进行排序,最后将结果归并起来,使其整体有序。归并排序基于算法设计中的分治思想。我们将一个大问题分解成小问题分别解决,然后用所有小问题的答案来解决整个大问题。

算法特点:1.任意长度为N的数组排序所需的时间和NlogN成正比。这个可以通过归并排序的排序树得到

2.它所需要的额外空间和N成正比。因为归并过程中需要一个长度为N的辅助数组。

private static Comparable[] temp;	//辅助数组,定义为类的成员变量
	public static void mergeSort(Comparable[] a){
		temp = new Comparable[a.length];
		sort(a,0,a.length-1);
	}
	//将数组a[lo..hi]进行排序
	private static void sort(Comparable[] a,int lo ,int hi){
		if(lo>=hi) return;
		int mid = lo+(hi-lo)/2;
		sort(a,lo,mid);//递归的对左边进行排序
		sort(a,mid+1,hi);	//递归的对右边进行排序
		merge(a,lo,mid,hi); //合并左右两边
	}
	//将两个有序的数组a[lo..mid]和a[mid+1..hi]合并为一个有序的数组,用到一个辅助数组temp
	public static void merge(Comparable[] a,int lo,int mid,int hi){
		int i=lo,j=mid+1;
		for(int k=lo;k<=hi;k++)		//将数组a复制到辅助数组temp中
			temp[k] = a[k];
		for(int k=lo;k<=hi;k++)
			if(i>mid) a[k]=temp[j++];	//左半边取尽,直接复制右半边剩余的元素到数组中
			else if(j>hi)	a[k] = temp[i++];	//右半边取尽,直接复制左半边剩余的元素到数组中
			else if(less(temp[j],temp[i])) a[k]=temp[j++]; //右半边的当前元素比左半边的当前元素小,取右半边
			else	a[k]=temp[i++];		//左半边的当前元素比右半边的当前元素小,取左半边
	}

快速排序

算法思想:快速排序是一种基于分治的排序算法。它通过一种划分,将一个数组划分为两个字数组,并将两个字数组独立的进行排序。

public static void sort(Comparable[] a){
		sort(a,0,a.length-1);
	}
	private static void sort(Comparable[] a,int lo, int hi){
		if(hi<=lo) return ;
		int j = partition(a, lo, hi);	//切分
		sort(a,lo,j-1);					//左半部分排序
		sort(a,j+1,hi);					//右半部分排序
	}
	private static int partition(Comparable[] a,int lo,int hi){
		int i=lo,j=hi+1;				//左右扫描指针
		Comparable v = a[lo];			//切分元素,该元素完成切分后位置将固定并返回
		while(true){					//循环扫描左右指针
			while(less(a[++i],v)) if(i==hi) break;
			while(less(v,a[--j]))	if(j==lo) break;
			if(i>=j) break;
			exch(a,i,j);
		}
		exch(a,lo,j);					//将v=a[j]放入正确位置
		return j;					//返回切分元素所在的位置
	}

在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生改变,则称这种排序方法是不稳定的。


排序法


平均时间


最差情形


稳定度


额外空间


备注


选择


O(n2)


O(n2)


不稳定


O(1)


n小时较好


插入


O(n2)


O(n2)


稳定


O(1)


大部分已排序时较好


Shell


O(nlogn)


O(ns) 1<s<2


不稳定


O(1)


s是所选分组


快速


O(nlogn)


O(n2)


不稳定


O(nlogn)


n大时较好


归并


O(nlogn)


O(nlogn)


稳定


O(1)


n大时较好

本算法过程只注重实现,并没有用栈等机制消除递归,

完整程序下载地址:http://download.csdn.net/detail/danchu/7276229

常见排序算法总结(java实现),码迷,mamicode.com

时间: 2024-12-11 12:08:24

常见排序算法总结(java实现)的相关文章

常见排序算法(java实现)

常见排序算法介绍 冒泡排序 代码: public class BubbleSort { public static void sort(int[] array) { int tValue; for (int i = 0; i < array.length; i++) { for (int j = i; j < array.length; j++) { if (array[i] > array[j]) { tValue = array[i]; array[i] = array[j]; ar

常见排序算法及Java实现

先上个总图↓: ①.直接插入排序 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间. 步骤: 1.从第一个元素开始,该元素可以认为已经被排序 2.取出下一个元素,在已经排序的元素序列中从后向前扫描 3.如果该

六种常见排序算法的java实现

package edu.cn.ysw; //八种排序算法的实现与效率分析 /* * 内排序的种类: * 1.插入排序:直接插入排序.希尔排序. * 2.选择排序:简单选择排序.堆排序. 3.交换排序:冒泡排序.快速排序. 4.归并排序 5.基数排序 */ public class SortedMethods { /** * @author ysw * @param args * @throws Exception * @since 6/15/2017 */ // 直接插入排序:1.有哨兵;2.无

【整理】常见排序算法及其时间复杂度总结

原文出处: 1. 白话经典算法系列之八 MoreWindows白话经典算法之七大排序总结篇 2. 面试常用算法总结--排序算法(java版) 3. 常见排序算法小结 本篇主要整理了冒泡排序,直接插入排序,直接选择排序,希尔排序,归并排序,快速排序,堆排序七种常见算法,是从上面三篇博文中摘抄整理的,非原创. 一.冒泡排序 主要思路是: 通过交换相邻的两个数变成小数在前大数在后,这样每次遍历后,最大的数就"沉"到最后面了.重复N次即可以使数组有序. 冒泡排序改进1: 在某次遍历中,如果没有

常见排序算法(一) MergeSort

算法思想灰常重要,常见的用到分治思想的算法包括快速排序,归并,二分搜搜,大整数乘法等(参考 http://blog.csdn.net/com_stu_zhang/article/details/7233761,归纳很到位) 简单用归并对一个数组排序 思路: 简单来说对一个数组,只要他的左右两部分都是有序的,那么简单合并就ok了,那么左右两部分可以进一步划分各自的左右两部分----明显就是要递归了 算法:归并排序 1. 将数组一分为二,subArray1 和subArray2 2. 归并排序sub

几种常见排序算法

几种常见排序算法 几种常见排序算法 写在前面 基础介绍 初级排序算法 selection sort选择排序 insertion sort插入排序 ShellSort希尔排序 shuffing不是排序算法 merge sort归并排序 Abstract in-place merge原地归并的抽象方法 Top-down mergesort自顶向下的归并排序 Bottom-up mergesort自底向上的归并排序 quicksort 三向切分的快速排序 Heapsort堆排序 总结和比较 命题 本文

一文搞定十大经典排序算法(Java实现)

本文总结十大经典排序算法及变形,并提供Java实现. 参考文章: 十大经典排序算法总结(Java语言实现) 快速排序算法—左右指针法,挖坑法,前后指针法,递归和非递归 快速排序及优化(三路划分等) 一.排序算法概述 1.定义 将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序. 2.分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过比较

7种基本排序算法的Java实现

7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 1 /** 2 * 直接插入排序 3 * 不稳定 4 * 时间复杂度:O(n^2) 5 * 最差时间复杂度:O(n^2) 6 * 空间复杂度:O(1) 7 * 使用场景:大部分元素有序 8 * @param elements 9 * @param comparator 10 * @param <T> 11 */ 1

常见排序算法(冒泡、选择、插入、快速、归并C++实现)

常见排序算法(冒泡.选择.插入.快速.归并C++实现) #include <iostream> using namespace std; // 冒泡排序 void bubbleSort (int data[], size_t size) { for (size_t i = 0; i < size - 1; ++i) { bool ordered = true; for (size_t j = 0; j < size - 1 - i; ++j) if (data[j+1] <