`
闫老三
  • 浏览: 100313 次
社区版块
存档分类
最新评论

七种基本的排序

    博客分类:
  • ACM
阅读更多

       排序很多种,其中,七种排序是比较基本的排序方式,这七种排序分别是选择,冒泡,归并,快速,基数,插入,希尔排序。其他排序还有堆排序,桶排序,二叉树排序,图书馆排序,鸡尾酒排序等等,有兴趣的可以去研究。

      一:冒泡排序

      在所有的排序中,冒泡排序是最简单的,每一趟扫描都将最大值或者最小值扫描到队首/队尾,经过n趟扫描,这就可以了。这种排序的时间复杂度是O(n*n),最最理想的情况,可以达到O(1)

程序员都应该去看代码:

private static void bubbleSort(int[] a, int length) {
		boolean flag = true;
		for (int i = 0; i < length && flag; i++) {
			flag = false;
			for (int j = 0; j < length - i - 1; j++) {
				if (a[j] < a[j + 1]) {
					change(a, j + 1, j);
					flag = true;
				}
			}
		}
	}

 代码中,change是改变数组a中两个参数的位置。这个算法需要注意的是定义一个flag标量,当已经排好序但是扫描没有完成的时候,可以提前完成,只有这样,可以将时间复杂度降低到n(1)。

二:选择排序

这中算法的思想也很简单,每一次扫描都选出将未排序的部分的最大or最小值,与预定位置相比较,其时间复杂度也为O(n*n)

代码:

private static void selectionSort(int[] a, int length) {
		for (int i = 0; i < length; i++) {
			int num = a[i];
			int loc = i;
			for (int j = i + 1; j < length; j++) {
				if (a[j] > num) {
					num = a[j];
					loc = j;
				}
			}
			change(a, i, loc);
		}
	}

 与冒泡排序相同,也可以加入一个flag标量,这里就不详细说了。

三and四:归并排序 快速排序

归并排序与快速排序其实上是逆过程,他们都可以采用分治策略来实现。归并排序是将一个数组分为两部分,两部分分别排序好之后,然后将两个已经排序好的数组进行合并;快速排序是先将数组分为两个数组A,B,其中A中的每一个元素的数值都小于B中的元素,然后对A,B两个数组再分别进行排序,就可以了。

代码:

// 快速排序
	private static void quickSort(int[] a, int i, int j) {
		if (i >= j) {
			return;
		}
		if (i + 1 == j) {
			if (a[i] < a[j]) {
				change(a, i, j);
			}
			return;
		}

		int[] first = new int[j - i + 1];
		int[] last = new int[j - i + 1];
		int firstNum = 0;
		int lastNum = 0;
		int sentinel = a[i];
		// System.out.println(i+" "+sentinel);
		for (int n = i + 1; n <= j; n++) {
			if (a[n] > sentinel) {
				first[firstNum++] = a[n];
			} else {
				last[lastNum++] = a[n];
			}
		}
		for (int n = 0; n < firstNum; n++) {
			a[n + i] = first[n];
		}

		a[firstNum + i] = sentinel;
		for (int n = 0; n < lastNum; n++) {
			a[n + firstNum + 1 + i] = last[n];
		}
		quickSort(a, i, firstNum - 1 + i);
		quickSort(a, firstNum + 1 + i, j);

	}

	// 归并排序
	private static void mergeSort(int[] a, int i, int j) {
		if (i >= j) {
			return;
		}
		if (i + 1 == j) {
			if (a[i] < a[j]) {
				change(a, i, j);
			}
			return;
		}
		int middle = (i + j) / 2;
		mergeSort(a, i, middle);
		mergeSort(a, middle + 1, j);
		int[] b = new int[j - i + 1];
		int beforeMiddle = i;
		int afterMiddle = middle + 1;
		int bNum = 0;
		while (beforeMiddle <= middle && afterMiddle <= j) {
			if (a[beforeMiddle] > a[afterMiddle]) {
				b[bNum] = a[beforeMiddle];
				beforeMiddle++;
				bNum++;
			} else {
				b[bNum] = a[afterMiddle];
				afterMiddle++;
				bNum++;
			}
		}
		while (beforeMiddle <= middle) {
			b[bNum] = a[beforeMiddle];
			bNum++;
			beforeMiddle++;
		}
		while (afterMiddle <= j) {
			b[bNum] = a[afterMiddle];
			bNum++;
			afterMiddle++;
		}
		// print(b,0,b.length-1);
		for (int n = i; n <= j; n++) {
			a[n] = b[n - i];
		}
	}

 两种算法的时间复杂度都为O(n*log(n))

五 基数排序

基数排序是一种很有趣的排序方式,它首先将数组中元素的个位数进行排序,然后以此从十位数,百位数进行排序。这种算法很巧妙,其时间复杂度为O(k*n),非常理想是吧?

// 基数排序
	private static void baseSort(int[] array, int redix, int distance) {
		int[] temp = new int[array.length];
		int[] count = new int[redix];
		int divide = 1;
		for (int i = 0; i < distance; i++) {
			System.arraycopy(array, 0, temp, 0, array.length);
			Arrays.fill(count, 0);

			for (int j = 0; j < array.length; j++) {
				int key = (temp[j] / divide) % redix;
				count[key]++;
			}
			for (int j = 1; j < redix; j++) {
				count[j] += count[j - 1];
			}
			for (int j = array.length - 1; j >= 0; j--) {
				int key = (temp[j] / divide) % redix;
				count[key]--;
				array[count[key]] = temp[j];
			}
			divide *= redix;
		}
	}

 该方法中,redix是基数,distance是最大的位数,例如数组{66,77,9834,7812,67,8,673445},redix可以设定为10,distance为6。

六or七:插入排序和希尔排序

希尔排序是插入排序的升级版,所以先讲插入排序。有一个未排序的数组A,则新建一个数组B,B可以认定为有序的,将A中的元素依次插入到B中,那么就可以达到排序的目的。

代码:

private static void insertSort(int[] a, int length) {
		for(int i=1;i<a.length;i++){
			int temp=a[i];
			int j=i-1;
			while(j>=0&&a[j]>temp){
				a[j+1]=a[j];
				j--;
			}
			a[j+1]=temp;
		}
	}

 希尔排序比这个要复杂一点,希尔排序是先设定一个步长,然后再。。。呃。。我讲不清楚,维基百科上讲的不错,我直接复制过来吧。

例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

然后我们对每列进行排序:

10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

排序之后变为:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94

最后以1步长进行排序(此时就是简单的插入排序了)。

代码如下:

//希尔排序
	private static void shellSort(int[] a){
		int gap=0;
		while(gap<a.length){
			gap=gap*3+1;
		}
		while(gap>0){
			for(int i=gap;i<a.length;i++){
				int j=i-gap;
				int temp=a[i];
				while(j>=0&&a[j]>temp){
					a[j+gap]=a[j];
					j-=gap;
				}
				a[j+gap]=temp;
			}
			gap=(gap-1)/3;
		}
	}

 原文地址:http://uwind.iteye.com/blog/1944204

1
1
分享到:
评论

相关推荐

    数据结构中七种最基本的排序算法

    本项目涵盖了数据结构中的七个重要的排序算法,选择,插入,冒泡,归并,希尔,快速和堆排序,可实现任何的List类型和数组类型,进行排序,除String类型外都可以进行排序,为使用开发者和学习者使用这七种经典算法...

    各种常用排序算法的C语言实现

    各种常用排序算法的C语言实现,摘自严蔚敏《数据结构》。

    基于python的七种经典排序算法(推荐)

    一、排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。 排序的稳定性: 经过某种排序后,如果两个...

    VFP中实现选择排序

    我们今天所介绍的这个选择排序也是简单排序中的一种,不过比起泡排序的效率要高,并且也比较容易实现。  这些常用的排序方法多见诸于C/C++方面的资料中,如果要在vfp中实现这些排序方法,原理是一样的,只是在代码...

    数据结构课程——常用排序算法比较

     利用随机函数产生N个随机整数(N = 500,1000,1500,2000,2500,…,30000),利用直接插入排序、折半插入排序,起泡排序、快速排序、选择排序、堆排序,基数排序七种排序方法(可添加其它排序方法)进行排序...

    排序算法比较

    利用随机函数产生8个样本的20000个随机整数(其中之一已经是正序,之一是逆序),利用直接插入排序、折半插入排序,起泡排序、快速排序、选择排序、堆排序,基数排序七种排序方法进行排序(结果为由小到大的顺序),...

    经典算法之七大排序

    自己使用各个途径整理了七大排序的基本思想及部分实现代码,整合了部分动态说明,相对来说比较容易理解

    Java中七大基于比较的排序算法

    目录插入排序直接插入排序基本原理代码实现性能分析折半插入排序代码实现希尔排序基本原理代码实现性能分析选择排序单向选择排序基本原理代码实现性能分析双向选择排序代码实现堆排序基本原理代码实现性能分析冒泡...

    快速排序Quicksort演示

    日本程序员norahiko,写了一个排序算法的动画演示,非常有趣...目前,最常见的排序算法大概有七八种,其中"快速排序"(Quicksort)使用得最广泛,速度也较快。它是图灵奖得主C. A. R. Hoare(1934--)于1960时提出来的

    挑战七大排序算法-04堆排序

    基本原理也是选择排序,只是不再使用遍历的方式查找无序区间的最大数,而是通过堆来选择无序区间的最大数 升序:大顶堆;降序:小顶堆 堆排序的基本思路: a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或...

    初级java笔试题-Sorting-Algorithm-Analysis:七种排序算法的简单分析

    七种排序算法的简单分析 介绍 1998 年,唐纳德·克努斯 (Donald Knuth) 在他的《计算机编程艺术》第 3 卷:排序和搜索中表示,“编程的几乎每个重要方面都出现在排序或搜索的上下文中。” 事实上,在数据的简单化...

    实验二:归并排序的分治策略设计

    基本掌握分治策略的原理方法。 实验原理: 分治策略 实验步骤:利用分治策略编程实现合并排序,教材P21-22; 问题描述:合并排序(MERGE SORT),是用分之策略实现对n个元素进行排序的算法。合并的含义就是将两个或...

    数据结构02331(苏仕华)

    笔记内容非常全,可以不用买课本 第一章 概论 第一节 引言 第二节 基本概念和常用术语 第三节 算法的描述和分析 ...第七节 内部排序方法的分析比较 第八章 查找 第一节 基本概念 第二节 顺序表的查找 第三节 树表的查找

    计算机专业数据结构设计课件

    计算机专业所需,C语言编写,富含例题一、线性表 (一)线性表的定义和基本操作 ...(七)堆排序 (八)二路归并排序(merge sort) (九)基数排序 (十)各种内部排序算法的比较 (十一)内部排序算法的应用

    Excel基本操作技巧培训资料.pptx

    常用快捷键及功能介绍(七) 快捷键:ALT+DFF 功能:筛选 应用举例:部门人员筛选、自定义排序 Excel基本操作技巧培训资料全文共56页,当前为第15页。 填充的其他应用 具体操作:鼠标放在单元格右下角出现十字标志...

    数据结构习题答案(全部算法)严蔚敏版

    9.1 排序基本概念 9.2 插入排序 9.2.1 直接插入排序 9.2.2 折半插入排序 9.2.3 希尔排序 9.3 交换排序 9.3.1 冒泡排序 9.3.2 快速排序 9.4 选择排序 9.4.1 简单选择排序 9.4.2 堆排序 9.5 归并排序 9.6...

    数据结构教案 可供学者学习研究

    数据结构 教案 电子文档 基础学习资料 内容 要求 方法及手段 学时分配 ...3.基数排序、外排序简介 掌握基本内容 多媒体课件 2 2 1 *第十章 文件 0 信息结构、顺序文件、索引文件、散列文件和倒排文件

    C数据结构.ppt(详细讲解C数据结构和算法)

    第二章 ~ 第七章 基本数据结构 从抽象数据类型的角度, 分别讨论线性表、栈和队列、串、数组和广义表、 树、图等基本数据结构及其应用。 第八章 动态存储管理 介绍操作系统和编译程序中涉及的 动态存储管理的...

    数据结构实验

    如何构造一种排序方法,使五个整数至多用七次比较就可以完成排序任务? 实验8:集成实验 一、 实验目的 目的:扩大编程量,完成模块化程序设计的全过程。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 ...

Global site tag (gtag.js) - Google Analytics