各种常用排序算法分析
一、选择排序
很简单就是依次从要排序的数据中选择最小(大)的,第二小(大)的.........
看代码:
/**
* 选择排序;
* @param array
* @param left
* @param right
*/
public static void selectSort(int[] array,int left,int right){
for(int i=0;i<right-left+1;i++){
selectMin(array,left+i,right);
}
}
/**
* 选择最小的元素--将数组中的元素移动到第一位;
* @param array
* @param left
* @param right
* @return
*/
public static void selectMin(int[] array,int left,int right){
if(left==right){//只有一个元素;
return;
}else{
for(int i=left+1;i<right;i++){
if(array[i]<array[left]){
//交换元素;
int temp=0;
temp=array[i];
array[i]=array[left];
array[left]=temp;
}
}
}
}
分析一下算法的复杂度:时间O(n2),空间O(1);
二、直接插入排序
我觉得这种排序特别适合链表这种在逻辑上连续在物理上不连续的数据结构,否则需要反复的移动数据;
直接插入排序就是将要插入的元素插入已经排好序的顺序表中,使得插入以后的顺序表任然有序;
代码:
/**
* 插入排序;
* @param array
* @param left
* @param right
*/
public static void insertSort(int[] array,int left,int right){
for(int i=1;i<array.length;i++){
arrayAdjust(array,0,i);
}
}
/**
* 将数组调整--认为数组前n-1个元素是有序的最后一个元素待插入;
* @param array
* @param low
* @param high
*/
public static void arrayAdjust(int[] array,int low,int high){
int e=array[high];
for(int i=low;i<high;i++){
if(e<array[i]){
//移动元素并插入;
for(int j=high-1;j>=i;j--){
array[j+1]=array[j];
}
//赋值;
array[i]=e;
break;
}
}
}
很明显在链表中可以省去移动数据的操作,显得简单了许多。
算法复杂度分析:O(n2);
三、归并排序
归并排序就是将两个已经排好序的序列合并成一个有序的序列;
代码:
/**
* 归并排序;
*
* @param a
* @param left
* @param right
*/
public static void mergeSort(int[] a, int left, int right) {
if (right > left) {
// 取得中间值;
int mid = (left + right) / 2;
// 左归并;
mergeSort(a, left, mid);
// 右归并;
mergeSort(a, mid + 1, right);
// 排序之后再归并;
merge(a, left, mid, right);
}
}
/**
* 归并;
*
* @param array
* @param low
* @param mid
* @param high
*/
public static void merge(int[] array, int low, int mid, int high) {
// 开辟两个数组;
int[] a = new int[mid - low + 1];// 左边数组;
int[] b = new int[high - mid];// 右边数组;
int i, j;
// 拷贝元素;
for (i = 0; i < a.length; i++) {
a[i] = array[i + low];
}
for (j = 0; j < b.length; j++) {
b[j] = array[mid + j + 1];
}
i = j = 0;
int k = 0;
// 归并;
while (i < a.length && j < b.length) {
if (a[i] < b[j]) {
array[low+k++] = a[i++];
} else {
array[low+k++] = b[j++];
}
}
// 剩余拷贝;
if (i < a.length) {
for (; i < a.length; i++) {
array[low+k++] = a[i];
}
} else {
for (; j < b.length; j++) {
array[low+k++] = b[j];
}
}
}
归并排序是一种比较稳定的排序,但是它有一个不好的地方是在归并的时候必须要开辟新的空间来存储数据,所以它的空间复杂度较高,对于内存要求较高的程序来说不推荐使用归并排序。
算法复杂度分析:O(nlogn);
四、快速排序
效率很高的排序方式啊,ACM强烈推荐
/**
* 快速排序;
* @param array
* @param low
* @param high
*/
public static void quickSort(int[] array,int left,int right){
if(left<right){
int flag=partition(array, left, right);
//递归调用快速排序算法;
quickSort(array,left,flag-1);
quickSort(array,flag+1,right);
}
}
/**
* 调整数组;
* @param array
* @param low
* @param high
* @return
*/
public static int partition(int[] array,int low,int high){
//取得标志;
int pivot=array[low];
int temp=0;//临时变量;
while(low<high){
while(low<high&&array[high]>=pivot){
high--;
}
//交换;
temp=array[high];
array[high]=array[low];
array[low]=temp;
while(low<high&&array[low]<=pivot){
low++;
}
//交换;
temp=array[high];
array[high]=array[low];
array[low]=temp;
}
return low;
}
平均效率较高是O(nlogn),不好的地方是它是一种不稳定的排序方式,如果每次划分的元素是有一边只有一个,那么就没有得到很好的划分,所以此时运行时间较高。较好的情况是每次划分都比较均衡,复杂度能达到nlogn;
五、堆排序
堆排序虽然有的时候效率没有快速排序那么高,但是它是一种稳定的排序 ,排序实现利用大根堆(小跟堆)的性质来完成排序,将数组看成一个完全二叉树,然后我们在排序的时候要反复的来建堆。取得堆顶元素,调整到堆的末尾。
代码:
/**
* 堆排序算法;
* @param array
* @param length
*/
public static void heapSort(int[] array,int length){
//先建堆将第一个元素调整为最大的元素;
for(int i=length/2-1;i>=0;i--){
maxHeapfy(array,i,length);
}
int temp=0;
//堆排序;
//反复建堆;
for(int i=length-1;i>0;i--){
//堆顶先和堆的最后一个元素交换;
temp=array[0];
array[0]=array[i];
array[i]=temp;
//在将0-i调整为一个大根堆;
maxHeapfy(array,0,i);
}
}
/**
* 将堆调整为大根堆--以pos为堆顶;
* @param array
* @param pos--起始位置;
* @param len--数组的长度;
*/
public static void maxHeapfy(int[] array,int pos,int len){
//节点孩子的位置
int left=2*pos;
int right=2*pos+1;
int largest=0,temp;
//取得最大元素的位置;
if(left<len&&array[left]>array[pos]){
largest=left;
}
if(right<len&&array[right]>array[largest]){
largest=right;
}else{
largest=pos;
}
if(largest!=pos){//不相等交换堆顶元素;
temp=array[largest];
array[largest]=array[pos];
array[pos]=temp;
//递归调用;
maxHeapfy(array,largest,len);
}
}
各种排序还有很多种应用,今晚累了,且听下回分解!
<!--EndFragment-->
分享到:
相关推荐
本文将深入探讨标题"常用排序算法java演示"中涉及的知识点,包括排序算法的原理、Java实现方式以及其在实际应用中的图形演示。 首先,让我们逐一了解几种常见的排序算法: 1. **冒泡排序(Bubble Sort)**:这是一...
内部排序算法广泛应用于数据库管理系统、数据分析、机器学习等领域,它们是许多高效算法的基础,例如搜索、统计计算和图形处理等。 在《数据结构课程设计》中,你可能需要设计并实现这些排序算法,理解它们的原理...
石家庄铁道大学 刘立嘉 算法与数据结构 实验六 常用排序算法的对比分析
该程序包括常用的排序算法代码:直接插入排序,二分插入排序,...同时通过产生一个指定个数的随机数组,调用各种不同排序算法对其进行排序,记录各种算法的耗时,写入一个文本文件进行对比分析各种排序算法的时间性能。
常用排序算法的动态演示系统 在本系统中,我们主要实现了五种常用的排序算法:冒泡排序法、快速排序法、直接插入排序法、折半插入排序法和树形选择排序法。这些算法都是在计算机科学中最基本和最重要的排序算法,...
在编程领域,排序算法是计算机科学中的核心概念,它们用于对数据进行有序排列。这里我们主要探讨五种常见的排序算法,这些算法的源码你可以在...你可以通过阅读和分析压缩包中的源代码来学习和实践这些经典的排序算法。
《常用排序算法分析与实现》 排序算法是计算机科学中不可或缺的一部分,它们在处理大量数据时扮演着关键角色。本文将深入探讨几种经典的排序算法,包括插入排序、选择排序、堆排序、冒泡排序和快速排序,以及归并...
### 常用排序算法的比较 #### 引言 排序是计算机科学中一项非常重要的基本操作,它涉及将一组数据元素(或记录)按照特定的顺序(通常是递增或递减)重新排列。排序的目的通常是为了提高后续操作如搜索等的效率。...
在计算机科学领域,排序算法是数据结构与算法分析中的核心部分。它们用于对一组数据进行排列,以便于后续处理或优化查找效率。本资源“各种排序算法的实验(源代码+实验报告)”提供了一个全面的平台,用C++语言实现...
1) 对以下6种常用的内部排序算法进行比较:起泡排序,直接插入排序,简单选择排序,快速排序,希尔排序,堆排序。 2) 待排序记录的文件个数不小于1000( 其数据用伪随机数产生),至少用5组不同的输入数据作比较;比较...
插入排序算法同样是基于C语言的一种常用排序算法。插入排序的基本思想是:把待排序的序列分为已排序和未排序两部分,每次将一个未排序的元素,按照其大小插入到已排序序列中的适当位置,直到所有元素都被插入。插入...
这些排序算法在C++中实现时,通常会利用C++的模板机制,使其能够适用于各种数据类型。同时,为了提高效率,可能会采用STL中的迭代器进行操作,以及考虑内存管理、异常安全性和性能优化等高级主题。在实际开发中,...
一、问题描述 本项目旨在实现并比较六...总结,这个项目提供了对C语言实现的排序算法的深入理解和实践,通过对各种排序方法的性能测试,我们可以更好地理解它们在不同场景下的适用性,并为实际问题选择合适的排序算法。
1、本演示程序对以下6种常用的内部排序算法进行实测比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。 2、待排序表的表的元素的关键字为整数,表长不小于100;其中的数据要用伪随机数产生...
在编程领域,排序算法是计算机科学中的重要概念,尤其是在数据处理和算法效率分析方面。C#作为.NET框架下的主要编程语言,提供了丰富的内置方法来实现排序,但理解基本的排序算法原理对于优化代码和提高性能至关重要...
在编程领域,排序算法是计算机科学中的核心概念,它们用于对数据进行有序排列。这里我们主要探讨四个常见的排序算法:快速排序、堆排序、二路归并排序(包括递归和非递归实现)以及多路归并排序。这些算法在实际应用...
本资源"常用各种排序算法Java的实现_差不多了__.rar"显然是一个包含了各种经典排序算法Java实现的压缩文件,对于学习和理解这些算法的开发者来说极具价值。 首先,我们来概述一下常见的排序算法: 1. 冒泡排序:是...