直接插入排序
排序过程
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序
算法描述
折半插入排序
排序过程
用折半查找方法确定插入位置的排序叫折半插入排序.
算法描述
算法评价
时间复杂度:T(n)=O(n²)
空间复杂度:S(n)=O(1)
希尔排序(缩小增量法)
排序过程
先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
算法描述
希尔排序特点
l子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列
l希尔排序可提高排序速度,因为
u分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体上看是减小了
u关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序
l增量序列取法
u无除1以外的公因子
u最后一个增量值必须为1
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上
对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置
重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止
算法描述
快速排序
基本思想
通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序
排序过程
对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key
l初始时令i=s,j=t
l首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换
l再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换
l重复上述两步,直至i==j为止
l再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止
算法描述
简单选择排序
排序过程
l首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换
l再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换
l重复上述操作,共进行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
分享到:
相关推荐
(1) 完成5种常用内部排序算法的演示,5种排序算法为:快速排序,直接插入排序,选择排序,堆排序,希尔排序; (2) 待排序元素为整数,排序序列存储在数据文件中,要求排序元素不少于30个; (3) 演示程序开始,...
本主题将深入探讨四种常见的排序算法:堆排序、快速排序以及两种未在标题中明确提到但同样重要的排序方法——基数排序和计数排序。 首先,让我们详细了解一下堆排序。堆排序是一种基于比较的排序算法,利用了数据...
以下是关于"冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序"这七种常见排序算法的源码实现及相关知识点的详细解释: 1. **冒泡排序**:冒泡排序是一种简单的排序算法,它重复地遍历待排序的...
本文将详细讲解六种经典的排序算法——合并排序、插入排序、希尔排序、快速排序、冒泡排序以及桶排序,并结合提供的文件名(sort.c、set.c、main.c、set.h、sort.h)推测出每个文件可能包含的代码实现。 1. **合并...
下面将详细讲解这7种排序算法:快速排序、归并排序、插入排序、选择排序、冒泡排序、堆排序以及希尔排序。 1. **快速排序**:由C.A.R. Hoare提出的,采用分治策略。基本思想是选取一个基准元素,通过一趟排序将待...
直接插入排序、冒泡排序、快速排序、直接选择排序、堆排序和二路归并排序是计算机科学中经典的排序算法,它们在数据处理和算法学习中占有重要地位。这些排序算法各有特点,适用场景不同,下面将逐一详细介绍,并结合...
提供五种排序算法的C++实现方法,输入(待排序元素个数、排序码上界(采用随机生成数组方式)),可选择输出(原始数组、排序后数组、原始数组有序度和无序度、排序过程中数据比较次数与数据移动次数、数组中出现...
本文将深入探讨四种在C++中实现的常见排序算法:插入排序、冒泡排序、堆排序和快速排序。这些算法各有特点,适用于不同的场景,理解并掌握它们对于提升编程能力至关重要。 1. **插入排序**: 插入排序是一种简单的...
实现以下常用的内部排序算法并进行性能比较:"直接插入排序"," 折半插入排序"," 2—路插入排序"," 表插入排序"," 希尔排序"," 起泡排序"," 快速排序"," 简单选择排序"," 树形选择排序"," 堆排序"," 归并排序"," 链式...
本主题将详细探讨希尔排序、冒泡排序、堆排序等经典的排序算法,这些都是数据结构与算法学习中的核心内容,尤其对于北邮数据结构课程来说,理解并掌握这些排序方法至关重要。 1. **插入排序**: 插入排序是一种...
本文将深入探讨Java编程语言中实现的七种主要排序算法:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序以及归并排序。每种算法都有其独特性,适用于不同的场景和数据特性。 1. **直接插入排序**:...
本主题涵盖了六种经典的排序算法:希尔排序、堆排序、快速排序、简单选择排序、插入排序和冒泡排序。这些算法各有特点,适用于不同的场景,下面将逐一详细介绍。 1. **希尔排序**:希尔排序是由Donald Shell提出的...
排序算法是计算机科学中至关重要的一部分,它涉及到如何有效地组织和排列数据。无论是处理数据库记录、优化数据结构还是解决复杂问题,排序算法都是基础工具。在本文中,我们将深入探讨内部排序算法,包括它们的工作...
根据提供的文件信息,我们可以深入探讨几种经典的排序算法:冒泡排序、直接插入排序、快速排序以及希尔排序。这些算法在数据结构与算法课程中是非常重要的基础内容,它们各自有着独特的特性和应用场景。 ### 1. ...
本资源包含了几种常见的排序算法,包括堆排序、选择排序、冒泡排序、归并排序和插入排序。这些排序算法各有特点,适用于不同的场景,并且在理解它们的工作原理后,能够帮助初学者更好地掌握编程基础。 1. **堆排序*...
本话题主要探讨六种内部排序算法:直接插入排序、希尔排序、冒泡排序、快速排序、选择排序以及堆排序。这六种排序算法各有优劣,适用于不同的场景,接下来我们将逐一进行详细阐述。 1. **直接插入排序**: 直接...
全面的排序算法实现,包括插入排序、合并排序、堆排序、快速排序。 堆排序:HeapSort 讲解详见http://blog.csdn.net/fly_yr/article/details/8550701 插入排序:InSertion_Sort 讲解详见...
冒泡排序、选择排序和插入排序是三种基本的排序算法,它们都是在计算机科学中用于组织数据的关键技术。这些算法的实现通常用作教学示例,帮助初学者理解排序过程和时间复杂性。 **冒泡排序(Bubble Sort)**: 冒泡...
本文将深入探讨三种常见的高效排序算法:堆排序、快速排序和归并排序。它们都是基于不同的原理和策略,具有各自的优势和适用场景。 首先,堆排序是一种基于比较的排序算法,利用了二叉堆的数据结构。二叉堆是一个...
本资源提供了七大经典排序算法的实现程序,包括快速排序、冒泡排序、选择排序、归并排序、插入排序、希尔排序和堆排序。下面将逐一详细介绍这些排序算法及其原理。 1. 快速排序:由C.A.R. Hoare提出,是一种采用...