java 实现多种排序
public class Sort {
//交换两个数
private void swap(int[] arr, int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//普通版冒泡排序,时间复杂度为O(n^2),稳定的排序算法
public void bubbleSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=arr.length-2;j>=i;j--){
if(arr[j] > arr[j+1])
swap(arr, j, j+1);
}
}
}
//改进版的冒泡排序
public void bubble2Sort(int[] arr){
boolean flag = true;
for(int i=0;i<arr.length-1;i++){
flag = false;
for(int j=arr.length-2;j>=i;j--){
if(arr[j] > arr[j+1]){
swap(arr, j, j+1);
flag = true;
}
}
}
}
//简单选择排序,时间复杂度为O(n^2),稳定的排序算法,性能上优于冒泡,移动次数少,最多移动n-1次
public void selectSort(int[] arr){
int min;
for(int i=0;i<arr.length-1;i++){
min = i;
for(int j=i+1;j<arr.length;j++){
if(arr[min] > arr[j])
min = j;
}
if(min != i)
swap(arr,i,min);
}
}
//直接插入排序,稳定的排序算法,比较、移动的时间复杂度为O(n^2)
public void insertSort(int[] arr){
for(int i=1;i<arr.length;i++){
int temp = arr[i];
int j;
for(j=i-1;j>=0&&arr[j]>temp;j--)
arr[j+1] = arr[j];
arr[j+1] = temp;
}
}
//双点直接插入排序,稳定的排序算法,不是从开始进行的排序
public void insertSort2(int[] arr,int left, int right){
for(int i=left;++left<=right;i=++left){
int a1 = arr[i];
int a2 = arr[left];
if(a1<a2){
a2 = a1;
a1 = arr[left];
}
while(a1 < arr[--i]){
arr[i+2] = arr[i];
}
arr[++i + 1] = a1;
while(a2 < arr[--i]){
arr[i+1] = arr[i];
}
arr[i+1] = a2;
}
int last = arr[right];
while(last < arr[--right])
arr[right+1] = arr[right];
arr[right+1] = last;
}
//希尔排序,不是稳定的排序算法,是对插入排序的升级版,最好可以达到O(n^(3/2)),不好可以是O(n^2)
public void shellSort(int[] arr){
for(int gap=arr.length/2;gap>0;gap /= 2){
for(int i=0;i<gap;i++){
for(int j=i+gap;j<arr.length;j += gap){
if(arr[j]<arr[j-gap]){
int temp = arr[j];
int k = j - gap;
while(k>=0 && arr[k]>temp){
arr[k+gap] = arr[k];
k -= gap;
}
arr[k+gap] = temp;
}
}
}
}
}
//堆排序,时间复杂度为O(nlogn),不适合待排列个数较少的情况
public void heapSortAsc(int[] arr){
for(int i=arr.length/2-1;i>=0;i--){
heapAdjust(arr,i,arr.length-1);
}
for(int i=arr.length-1;i>0;i--){
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapAdjust(arr,0,i-1);
}
}
//建堆与调整堆的过程
private void heapAdjust(int[] arr, int start, int end){
int c = start;
int lChild = 2 * c + 1;
int temp = arr[c];
for(; lChild <= end; c = lChild, lChild = 2 * lChild + 1){
if(lChild < end && arr[lChild] < arr[lChild + 1])
lChild++;
if(arr[lChild] < temp){
break;
}
else{
arr[c] = arr[lChild];
arr[lChild] = temp;
}
}
}
//归并排序,稳定的排序方法,比较占内存,时间复杂度为O(nlogn)
//归并排序分为两个部分,分解与合并,从上往下的排序
public void mergeSortUp2Down(int[] arr, int start, int end){
if(arr == null || start >= end)
return;
int mid = (start + end) / 2;
mergeSortUp2Down(arr,start,mid);
mergeSortUp2Down(arr, mid+1, end);
merge(arr,start,mid,end);
}
//归并排序的合并部分
public void merge(int[] arr, int start, int mid, int end){
int i = start;
int j = mid + 1;
int k = 0;
int[] temp = new int[end-start+1];
while(i<=mid && j <= end){
if(arr[i] <= arr[j])
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
}
while(i <= mid)
temp[k++] = arr[i++];
while(j <= end)
temp[k++] = arr[j++];
for(i=0;i<k;i++){
arr[start+i] = temp[i];
}
}
//从下往上的排序,
public void mergeSortDown2Up(int[] arr){
if(arr == null)
return;
for(int i=1;i<arr.length;i *= 2)
mergeGroups(arr, arr.length,i);
}
//对数组进行若干次排序
public void mergeGroups(int[] arr, int len, int gap){
int i;
for(i=0;i+2*gap-1<len;i = i+2*gap){
merge(arr,i,i+gap-1,i+2*gap-1);
}
if(i+gap-1<len-1)
merge(arr,i,i+gap-1,len-1);
}
//快速排序,不稳定的排序算法,时间复杂度为O(nlogn)
public void quickSort(int[] arr, int low, int high){
int pivot;
if(low < high){
pivot = partition(arr,low,high);
quickSort(arr,low,pivot-1);
quickSort(arr,pivot+1,high);
}
}
//快速排序,进行位置交换
private int partition(int[] arr, int low, int high){
int pivot = arr[low];
while(low < high){
while(low < high && arr[high] >= pivot)
high--;
swap(arr,low,high);
while(low < high && arr[low] <= pivot)
low++;
swap(arr,low,high);
}
return low;
}
//双基准的快速排序算法
private void quickSort2(int[] arr, int lowIndex, int highIndex) {
if(lowIndex >= highIndex) return;
int pivot1 = arr[lowIndex];
int pivot2 = arr[highIndex];
if(pivot1 > pivot2){
arr[lowIndex] = pivot2;
arr[highIndex] = pivot1;
pivot1 = arr[lowIndex];
pivot2 = arr[highIndex];
}else if(pivot1 == pivot2){
while(pivot1 == pivot2 && lowIndex <= highIndex){
pivot1 = arr[++lowIndex];
}
}
int i = lowIndex + 1;
int lt = lowIndex + 1;
int gt = highIndex - 1;
while(i<=gt){
if(pivot1 > arr[i]){
swap(arr,lt++,i++);
}else if(pivot2 < arr[i]){
swap(arr,i,gt--);
}else{
i++;
}
}
swap(arr,lowIndex,--lt);
swap(arr,highIndex,++gt);
quickSort2(arr,lowIndex,lt-1);
quickSort2(arr,lt+1,gt-1);
quickSort2(arr,gt+1,highIndex);
}
//桶排序
public void bucketSort(int[] arr, int max){
if(arr == null || max < 1) return ;
int[] buckets = new int[max];
for(int i=0;i<arr.length;i++)
buckets[arr[i]]++;
for(int i=0, j=0;i<max;i++)
while((buckets[i]--)>0)
arr[j++] = i;
}
//计数排序,稳定的排序算法,桶排序另一种,时间复杂度为O(n)
public void countSort(int[] arr, int max){
int[] result = new int[arr.length];
int[] temp = new int[max];
for(int i=0;i<arr.length;i++){
temp[arr[i]]++;
}
for(int i=1;i<temp.length;i++){
temp[i] += temp[i-1];
}
for(int i=0;i<temp.length;i++)
temp[i] -= 1;
for(int i=arr.length-1;i>=0;i--){
result[temp[arr[i]]--] = arr[i];
}
System.arraycopy(result, 0, arr, 0, arr.length);
}
//基数排序,桶排序的升级版,利用计数排序来做
public void radixSort(int[] arr, int max){
for(int exp=1;max/exp>0;exp *= 10){
countSort1(arr,exp);
}
}
//基数排序调用计数排序
public void countSort1(int[] arr, int exp){
int[] temp = new int[10];
int[] result = new int[arr.length];
for(int i=0;i<arr.length;i++)
temp[arr[i]]++;
for(int i=1;i<10;i++)
temp[i] += temp[i-1];
for(int i=0;i<10;i++)
temp[i]--;
for(int i=arr.length-1;i>=0;i--)
result[temp[arr[i]]--] = arr[i];
System.arraycopy(result, 0, arr, 0, arr.length);
}
public static void main(String[] args) {
Sort sort = new Sort();
int[] arr = {1,6,3,5,3,2,4,5,1,6};
sort.radixSort(arr,7);
for(int i=0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
}
}
java 实现多种排序的更多相关文章
- Java中的排序算法(2)
Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...
- Java实现常见排序算法
常见的排序算法有冒泡排序.选择排序.插入排序.堆排序.归并排序.快速排序.希尔排序.基数排序.计数排序,下面通过Java实现这些排序 1.冒泡排序 package com.buaa; import j ...
- Comparable与Comparator,java中的排序与比较
1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如s ...
- Java之List排序出错
Java之List排序出错 Bound mismatch: The generic method sort(List<T>) of type Collections is not appl ...
- Java进阶(三十九)Java集合类的排序,查找,替换操作
Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...
- java过滤器(过滤器排序)
java过滤器(过滤器排序) 定义过滤器顺序是很简单的:匹配请求的过滤器将按照它们出现在部署描述符或者编程式配置中的顺序添加到过滤器链中(记住,如果同时再部署描述符或者编程式配置中设置了一些过滤器,那 ...
- java实现各种排序算法
java实现各种排序算法 import java.util.Arrays; public class SomeSort { public static void main(String[] args) ...
- java中多种方式读文件
转自:http://www.jb51.net/article/16396.htm java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内 ...
- ElasticSearch6.0 Java API 使用 排序,分组 ,创建索引,添加索引数据,打分等(一)
ElasticSearch6.0 Java API 使用 排序,分组 ,创建索引,添加索引数据,打分等 如果此文章对你有帮助,请关注一下哦 1.1 搭建maven 工程 创建web工程 ...
随机推荐
- android软键盘的用法总结
1.软键盘的显示原理 软键盘其实是一个Dialog.InputMethodService为我们的输入法创建了一个Dialog,并且对某些参数进行了设置,使之能够在底部 或者全屏显示.当我们点击输入框时 ...
- cocos2dx实现android的对讯飞语音的合成(语言朗读的实现)
事实上非常easy,只是有些细节须要注意. 关于讯飞语音在android上的应用,大家须要自己去下载SDK,然后依照讯飞语音提供的api在自己的android的Demo上执行成功,那东西也相当的简单. ...
- android 54 播放音视频
mainActivity: package com.sxt.day07_09; import java.util.ArrayList; import java.util.HashMap; import ...
- WebLogic Server的单点登陆功能--转载
在WebLogic 8.1最新的 SP4版本中,最引人注目的要算是在安全方面,提供了用于和Microsoft Windows客户端进行Single Sign-On的Single Pass Negoti ...
- 理解JavaScript的定时器与回调机制
定时器方法 JavaScript是单线程的.虽然HTML5已经开始支持异步js了. JavaScript的setTimeout与setInterval看起来就像已经是多线程的了.但实际上setTime ...
- python----------进程、线程、协程
进程与线程 什么是进程(process)? An executing instance of a program is called a process. Each process provides ...
- HTML5 autocomplete属性、表单自动完成
autocomplete属性 1.定义autocomplete属性规范表单是否启用自动完成功能.自动完成允许浏览器对字段的输入,是基于之前输入的值.2.应用范围autocomplete使用<fo ...
- 关于webservice不支持方法重载的解决办法
今天在写WebService时,出现了这样的错误: Count(Int32, Int32) 和 Count(Int32) 同时使用消息名称“Count”.使用 WebMethod 自定义特性的 Mes ...
- Struts2 单个文件上传/多文件上传
1导入struts2-blank.war所有jar包:\struts-2.3.4\apps\struts2-blank.war 单个文件上传 upload.jsp <s:form action= ...
- 静态方法块 static 以及对象属性&类属性的用法
使用静态块的好处:只要在类被加载时,static块就会被调用,整个过程就调用这么一次,不会在后面的对象处又不断的调用.如果不使用它,就会出现如下问题:new一个对象,我就要调用一次所需的这些内容,重复 ...