文档章节

排序

自由的角马
 自由的角马
发布于 2015/01/10 13:58
字数 2285
阅读 16
收藏 0

直接插入排序

排序过程

整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序

算法描述

折半插入排序

排序过程

用折半查找方法确定插入位置的排序叫折半插入排序.

算法描述

算法评价

时间复杂度:T(n)=O(n²)

空间复杂度:S(n)=O(1)

希尔排序(缩小增量法)

排序过程

先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止

算法描述

希尔排序特点

子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列

希尔排序可提高排序速度,因为

分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体上看是减小了

关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序

增量序列取法

无除1以外的公因子

最后一个增量值必须为1

冒泡排序

排序过程

将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上

对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置

重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止

算法描述

快速排序

基本思想

通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序

排序过程

r[s……t]中记录进行一趟快速排序,附设两个指针ij,设枢轴记录rp=r[s]x=rp.key

初始时令i=s,j=t

首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换

再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换

重复上述两步,直至i==j为止

再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止

算法描述

简单选择排序

排序过程

首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换

再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换

重复上述操作,共进行n-1趟排序后,排序结束

算法描述

堆排序

堆的定义

n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆

排序过程

将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列.

算法描述

排序方法的性能的比较

方法

平均时间

时间

附加空间

稳定性

直接插入

O(n2)

O(n2)

O(1)

稳定的

Shell排序

O(n1.3)

O(1)

不稳定的

直接选择

O(n2)

O(n2)

O(1)

不稳定的

堆排序

O(nlog2n)

O(nlog2n)

O(1)

不稳定的

冒泡排序

O(n2)

O(n2)

O(1)

稳定的

快速排序

O(nlog2n)

O(n2)

O(log2n)

不稳定的

归并排序

O(nlog2n)

O(nlog2n)

O(n)

稳定的

基数排序

O(d(n+r))

O(d(n+r))

O(n+r)

稳定的


排序类的实现

package datastructure.sorter;

import datastructure.common.Strategy;

/**
 * 排序
 * @author luoweifu
 *
 */
public class Sorter implements Strategy {
	/**
	 * 直接插入排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void insertSort(Object[] r, int low, int high) {
		for(int i=low +1; i<=high; i++) {
			//Object strategy;
			if(compare(r[i],r[i-1]) < 0) {
				Object temp = r[i];
				r[i] = r[i-1];
				int j = i-2;
				for(; j>=low && compare(temp, r[j])<0; j--)
					r[j+1] = r[j];
				r[j+1] = temp;
			}
		}
	}
	
	/**
	 * 折半排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void  binInsetSort(Object[] r, int low, int high) {
		for(int i=low+1; i<=high; i++) {
			Object temp = r[i];				//保持待插入元素
			int hi = i-1; int lo = low;		//设置初始区间
			while(lo <= hi) {				//折半确定插入位置
				int mid = (lo + hi)/2;
				if(compare(temp, r[mid])<0) 
					hi = mid -1;
				else lo = mid +1;
			}
			for(int j=i-1; j>hi; j--) r[j+1] = r[j];//移动元素
			r[hi+1] = temp;							//插入
		}
	}
	
	/**
	 * 尔排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 * @param delta 增量
	 */
	public void shellSort(Object[] r, int low, int high, int[] delta) {
		for(int k=0; k<delta.length; k++) {
			shellInsert(r, low, high, delta[k]);
		}
	}
	private void shellInsert(Object[] r, int low, int high, int deltaK) {
		for(int i=low+deltaK; i<=high; i++) {
			if(compare(r[i], r[i-deltaK])<0) {
				Object temp = r[i];
				int j=i-deltaK;
				for(; j>=low && compare(temp, r[j])<0; j=j-deltaK) 
					r[j+deltaK] = r[j];
				r[j+deltaK] = temp;
			}
		}
	}
	
	/**
	 * 冒泡排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void bubbleSort(Object[] r, int low, int high) {
		int n = high - low +1;
		for(int i=1; i<n; i++) {
			for(int j=low; j<=high -i; j++) {
				if(compare(r[j],r[j+1])>0) {
					Object temp = r[j];
					r[j] = r[j+1];
					r[j+1] = temp;
				}
			}
		}
	}
	
	/**
	 * 快速排序
	* @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void quickSort(Object[] r, int low, int high) {
		if(low < high) {
			int pa = partition(r, low, high);
			quickSort(r, low, pa-1);
			quickSort(r, pa+1, high);
		}
	}
	private int partition(Object[] r, int low, int high) {
		Object pivot = r[low];
		while(low < high) {
			while(low<high && compare(r[high], pivot)>=0) high--;
			r[low] = r[high];
			while(low<high && compare(r[low],pivot)<=0) low++;
			r[high] = r[low];
		}
		r[low] = pivot;
		return low;
	}
	
	/**
	 * 简单选择排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void selectSort(Object[] r, int low, int high) {
		for(int k=low; k<high; k++) {
			int min = k;
			for(int i=min+1; i<=high; i++)
				if(compare(r[i], r[min])<0) min = i;
			if(k != min) {
				Object temp = r[k];
				r[k] = r[min];
				r[min] = temp;
			}
		}
	}
	
	/**
	 * 堆排序
	 * 该方法有点错误,有时间再解决,也希望读者能帮忙解决
	 * @param r 要排序的数组
	 */
	public void heapSort(Object[] r) {
		int n = r.length - 1;
		for(int i=n/2; i>=1; i--)	//初始化键堆
			heapAdjust(r, i, n);
		for(int i=n; i>1; i--) {	//不断输出堆顶元素并调整人r[1....i-1]为新堆
			Object temp = r[1];		//交换堆顶与堆底元素
			r[1] = r[i];
			r[i] = temp;
			heapAdjust(r,1,i-1);//调整
		}
	}
	private void heapAdjust(Object[] r, int low, int high) {
		Object temp = r[low];
		for(int j=2*low; j<=high; j=2*j) {	//沿关键字较大的元素向下进行筛选
			//指向关键字较大的元素
			if(j<high && compare(r[j],r[j+1])<0) j++;
			//若temp比其孩子都大,则插入到low所指位置
			if(compare(temp, r[j])>=0) break;
			r[low] = r[j];
			low = j;	//向下删选
		}
		r[low] = temp;
	}
	
	/**
	 * 归并排序
	* @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void mergeSort(Object[] r, int low, int high) {
		if(low<high) {
			mergeSort(r, low, (high+low)/2);
			mergeSort(r, (high+low)/2+1, high);
			merge(r, low, (high+low)/2, high);
		}
	}
	private void merge(Object[] a, int p, int q, int r) {
		Object[] b = new Object[r-p+1];
		int s = p;
		int t = q+1;
		int k=0;
		while(s<=q && t<=r) {
			if(compare(a[s],a[t])<0)
				b[k++] = a[s++];
			else 
				b[k++] = a[t++];
		}
		while(s<=q)
			b[k++] = a[s++];
		while(t<=r) 
			b[k++] = a[t++];
		for(int i=0; i<b.length; i++)
			a[p+i] = b[i];
	}
	/**
	 * 把int型的数组转换成包装类Integer的数组
	 * @param a
	 * @return
	 */
	public Integer[] intToInteger(int[] a) {
		Integer b[] = new Integer[a.length];
		for(int i=0; i<a.length; i++) {
			b[i] = Integer.valueOf(a[i]);
		}
		return b;
	}
	

	public boolean equal(Object obj1, Object obj2) {
		// TODO Auto-generated method stub
		return false;
	}

	public int compare(Object obj1, Object obj2) {
		Integer a = (Integer)obj1;
		Integer b = (Integer)obj2;
		if(a.compareTo(b)<0) return -1;
		else if(a.compareTo(b) == 0) return 0;
		else return 1;
	}

	
	
}


/*
class Student implements Strategy {
	public  Integer id ;
	public Student(){
		this.id = 0;
	}
	public Student(int id) {
		this.id = id;
	}
	@Override
	public boolean equal(Object obj1, Object obj2) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int compare(Object obj1, Object obj2) {
		Student st1 = (Student)obj1;
		Student st2 = (Student) obj2;
		return st1.id.compareTo(st2.id);
	}
	
}
*/

测试

package datastructure.sorter;
/**
 * 测试
 * @author luoweifu
 *
 */
public class Test {

	public static void main(String[] args) {
		//Object[] a = 
		int a[] = {5,6,8,1,8,88,56,78};
		Sorter sort = new Sorter();
		Integer b[] = sort.intToInteger(a);
		//sort.insertSort(a, 0, a.length-1);
		//sort.binInsetSort(a, 0, a.length-1);
		//int b[] = {3,1};
		//sort.shellSort(a, 0, a.length-1, b );
		//sort.bubbleSort(a, 0, a.length-1);
		//sort.quickSort(a, 0, a.length-1);
		//sort.selectSort(a, 0, a.length-1);
		//sort.heapSort(a);				//堆排序,有点错误,有时间再解决
		sort.mergeSort(b, 0, b.length-1);
		for(int i=0; i<b.length; i++) {
			System.out.print(b[i] + "  ");
		}
	}
	
}

结果:

1  5  6  8  8  56  78  88  

本文转载自:http://blog.csdn.net/luoweifu/article/details/9273067

自由的角马
粉丝 1
博文 269
码字总数 0
作品 0
文山
私信 提问
排序——排序的基本概念

一、排序概念 排序是将一组数据按递增或递减的顺序排列。排序是最一种最基础的、最常用的算法。 二、排序的分类 在计算机中,由于数据形式、数量和保存形式不同,对数据进行排序的方法也不同...

翼动动空
2016/06/02
4.5K
0
看图轻松理解数据结构与算法系列(选择排序)

前言 推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种排序等...

超人汪小建
2018/08/16
0
0
常用的内部排序方法-非比较排序

这篇文章中我们来探讨一下常用的非比较排序算法:计数排序,基数排序,桶排序。在一定条件下,它们的时间复杂度可以达到O(n)。   这里我们用到的唯一数据结构就是数组,当然我们也可以利用...

亮亮-AC米兰
2017/01/22
0
0
MySQL——优化ORDER BY语句

本篇文章我们将了解ORDER BY语句的优化,在此之前,你需要对索引有基本的了解,不了解的老少爷们可以先看一下我之前写过的索引相关文章。现在让我们开始吧。 MySQL中的两种排序方式 1.通过有...

CoderFocus
2018/08/17
0
0
mysql 002 order by的排序算法原理原来是这样的

     前言   平常写业务的时候,我们经常需要对一些业务数据进行排序,例如点赞排名,浏览量排名等等。虽然这个字段很常用了,可能出于对服务器是 MySQL 的原因,使我们会胆怯或不想去...

java进阶架构师
09/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
33分钟前
3
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
36分钟前
3
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0
JAVA 利用时间戳来判断TOKEN是否过期

import java.time.Instant;import java.time.LocalDateTime;import java.time.ZoneId;import java.time.ZoneOffset;import java.time.format.DateTimeFormatter;/** * @descri......

huangkejie
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部