几种简单排序

package com.shine.sort;
/**
* 排序算法 <br>
* @说明:<br>
* 排序算法分为三种:插入排序、交换排序、选择排序 <br>
* 1.插入排序:直接插入排序、折半插入排序、希尔排序 <br>
* 2.交换排序:冒泡排序、快速排序 <br>
* 3.选择排序: 直接选择排序、堆排序 <br>
*/
public class MySort {

/**
* 直接插入排序<br>
* @描述:<br>
* 1. 直接插入排序是第i趟把第i个元素放的前面已经排好序的序列中去<br>
* 2. 重复上述操作。n个元素共需n-1趟扫描,每趟将一个元素插入到它前面的子序列中 <br>
* @复杂度分析:<br>
* 1.时间复杂度:<br>
* 最好情况:当数据序列已排序,时间复杂度为o(n) <br>
* 最坏情况:数据序列反序,时间复杂度为o(n*n) <br>
* 随机:o(n*n) <br>
* 2.空间复杂度:o(1) <br>
* @稳定性:稳定
*/
public static void insertSort(int[] table){
for(int i=1;i<table.length;i++){//n-1趟扫描
int temp=table[i],j;//每趟将table[i]插入到前面排序序列中
for(j=i-1;j>=0&&temp<table[j];j--)
table[j+1]=table[j];//将较大元素向后移动
table[j+1]=temp;//temp到达插入位置
}
}
/**
* 希尔排序 <br>
* @描述: <br>
* 1.将一个数据序列分成若干组,每组由若干相隔一段距离的元素组成,这段距离称为增量,
* 在一组内采用直接插入排序算法进行排序 <br>
* 2.当增量为1时,只有一组,元素是整个序列,再进行一次直接插入排序即可 <br>
* @复杂度分析:
* 1.时间复杂度:时间复杂度比较复杂,具体时间取决于具体增量的序列 <br>
* 2.空间复杂度:o(1)
* @稳定性:不稳定
*/
public static void shellSort(int[] table){
for(int delta=table.length/2;delta>0;delta/=2)//进行若干趟扫描,控制增量,增量减半
for(int i=delta;i<table.length;i++){//一趟分若干组,每组进行直接插入排序
int temp=table[i],j;
for(j=i-delta;j>=0&&temp<table[j];j-=delta)
table[j+delta] = table[j];
table[j+delta] = temp;
}
}
/**
* 冒泡排序 <br>
* @说明: <br>
* 比较两个相邻元素的关键值,如果反序,则交换。若按升序排序,每一趟将被扫描的数据序列中的最大元素交换到
* 最后位置,就像气泡从水里冒出一样。 <br>
* @复杂度分析:<br>
* 1.时间复杂度分析:o(n)-o(n*n)
* 2.空间复杂度分析:o(1)
* @稳定性:稳定
*/
public static void bubleSort(int[] table){
boolean exchange = true;
for(int i=1;i<table.length&&exchange;i++){//有交换时才进行下一趟排序
exchange = false;//假定元素没有交换
for(int j=0;j<table.length-i;j++)
if(table[j]>table[j+1]){
int temp = table[j];
table[j] = table[j+1];
table[j+1] = temp;
exchange = true;
}
}
}
/**
* 快速排序算法 <br>
* @说明: <br>
* 在数据序列中选择一个值作为比较的基准值,每趟从数据序列的两端开始交替进行,将小于基准值的元素交换到序列
* 前段,大于基准值的元素交换到序列后端,介于两者之间的位置则称为基准值的最终位置。同时序列被划分成两个子
* 序列,在用同样的方法对两个子序列进行排序,直到子序列长度为1,则完成排序。
* @复杂度分析: <br>
* 时间复杂度:<br>
* 最好情况:每趟排序将序列分成长度相近的两个子序列。 o(nlog2n) <br>
* 最坏情况:每趟排序将序列分成长度差异很大的两个子序列 o(n*n) <br>
* 空间复杂度:<br>
* 最好情况: o(log2n)
* 最坏情况: o(n)
* @稳定性:不稳定<br>
*/
public static void quickSort(int[] table){
quickSort(table,0,table.length-1);
}
private static void quickSort(int[] table,int begin,int end){
if(begin<end){
int i=begin,j=end;
int vot=table[i];//基准值
while(i!=j){//一趟排序
while(i<j&&vot<=table[j])
j--;
if(i<j)//如果有小元素(当有table[j]<vot的时候,该条件恒成立)
table[i++]=table[j];//把后面的小元素向前移动
while(i<j&&table[i]<=vot)
i++;
if(i<j)
table[j--]=table[i];//把大元素向后移动
}
table[i]=vot;//基准值到达最终位置
quickSort(table,begin,j-1);//前段子序列进行排序
quickSort(table,i+1,end);//后端子序列进行排序
}
}
/**
* 直接选择排序 <br>
* @说明:<br>
* 第一趟从n个元素的数据中选出关键字最小或最大的元素放到最前或最后位置,下一趟再从n-1个元素……。直接选择排序
* 算法可用顺序表和单链表实现。 <br>
* @复杂度: <br>
* 时间复杂度:o(n*n) <br>
* 空间复杂度:o(1) <br>
* @稳定性:不稳定 <br>
*/
public static void selectSort(int[] table){
for(int i=0;i<table.length-1;i++){
int min=i;
for(int j=i+1;j<table.length;j++)
if(table[j]<table[min])
min=j;
if(min!=i){
int temp=table[i];
table[i]=table[min];
table[min]=temp;
}
}
}
/**
* 堆排序
* @说明: <br>
* 1.堆:这里的堆不是数据结构里面的堆栈,而是一种数据结构。堆可以视为一颗完全二叉树,完全二叉树的一个优秀的性质是
* 除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个节点对应数组中的一个元素。二叉堆一般分
* 为两种,最小堆和最大堆。<br>
* 2.最大堆:堆中每个父节点的值都大于等于其孩子节点,这样的堆就是一个最大堆。<br>
* 最小堆:对中的每个父节点都小于等于其孩子节点,这样的堆就是一个最小堆。 <br>
* 3.堆排序:堆排序分两个阶段。首先将一个数据序列建成堆序列,根节点值是最小(大)值;然后采用选择排序思路,每趟将
* 根结点值交换到最后,再将其余值调整成堆,依次重复,直到排序完成。<br>
* @复杂度:<br>
* 时间复杂度:o(n*log2n) <br>
* 空间复杂度:o(1) <br>
* @稳定性:不稳定
*/

public static void heapSort(int[] table){//堆排序
int n=table.length;
for(int j=n/2-1;j>=0;j--) //创建最小堆
sift(table,j,n-1);
for(int j=n-1;j>0;j--){ //每趟将最小值交换到后面,再调整成堆
int temp=table[0];
table[0]=table[j];
table[j]=temp;
sift(table,0,j-1);
}
}
//将以begin为根的子树调整成最小堆,begin、end是序列下届和上届
private static void sift(int[] table,int begin,int end){
int i=begin,j=2*i+1;//i为子树的根,j为i节点的左孩子
int temp=table[i];//获得第i个元素的值
while(j<=end){ //沿较小值孩子节点向下筛选
if(j<end&&table[j]>table[j+1]) //数组元素比较
j++; //j为左右孩子的较小者
if(temp>table[j]){ //若父母结点值较大
table[i]=table[j]; //孩子节点中的较小者上移
i=j; //i,j向下一层
j=2*i+1;
}
else break;
}
table[i]=temp;//当前子树的原根值调整后的位置
}
/**
* 归并排序
* @param args
*/
//一次归并方法: m和r分别是两个相邻的两个已排序的子序列的起始下标
private static void merge(int[] X,int[] Y,int m,int r,int n){ //一次归并
int i=m,j=r,k=m;
while(i<r&&j<r+n&&j<X.length){ //将X中两个相邻子序列归并到Y中
if(X[i]<X[j]) //较小值复制到Y中
Y[k++]=X[i++];
else Y[k++]=X[j++];
while(i<r) //将前一个子序列剩余元素复制到Y中
Y[k++]=X[i++];
while(j<r+n&&j<X.length) //将后一个子序列剩余元素复制到Y中
Y[k++]=X[j++];
}
}
//一趟归并
private static void mergepass(int[] X,int[] Y,int n){//一趟归并
int i=0;
while(i<X.length-2*n+1){
merge(X,Y,i,i+n,n);
i+=2*n;
}
if(i+n<X.length)
merge(X,Y,i,i+n,n); //再一次归并
else
for(int j=i;j<X.length;j++) //将X剩余元素复制到Y中
Y[j]=X[j];
}
public static void mergeSort(int[] X){ //归并排序
int[] Y = new int[X.length];
int n=1;
while(n<X.length){
mergepass(X,Y,n);
n*=2;
if(n<X.length){
mergepass(Y,X,n);
n*=2;
}
}
}
public static void main(String[] args) {
int[] table = {22,11,65,33,21,23,10};
System.out.println("直接插入排序:");
insertSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n希尔排序:");
shellSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n冒泡排序:");
bubleSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n快速排序:");
quickSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n直接选择排序:");
selectSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n堆排序:");
heapSort(table);
for(int x: table)
System.out.print(x+"\t");

System.out.println("\n归并排序:");
mergeSort(table);
for(int x: table)
System.out.print(x+"\t");

}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值