JAVA基本的排序算法
Java实现各种基本的排序算法
冒泡排序
冒泡排序:这种排序方法是通过相邻的两个元素两两比较,根据大小来交换位置,最值元素就像气泡一样从左侧向右侧移动,故名冒泡排序。
public class BubbleSort {
public static void main(String[] args) {
int []a= {9,3,1,4,6,8,7,5,2};
sort(a);
print(a);
}
//冒泡排序
static void sort(int[] a) {
for(int i=a.length-1;i>0;i--)//最大值换到最后以后不要动,前面子数组继续排序,找到最大值排好,以此类推
{
for(int j=0;j<i;j++)
{
if(a[j]>a[j+1]) {
swap(a,j,j+1);
}
}
}
}
static void swap(int []a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
选择排序
选择排序是一种简单直观的排序算法。它与冒泡排序很相似,都是比较 n-1 轮,每轮都是比较 n–1–i 次,每轮找出一个最大值或最小值。只不过,冒泡排序是将每轮找出的最值放到最右边,而选择排序是将每轮找出的最值放到最左边
//选择排序
public class SelectionSort {
public static void main(String[] args) {
int[] arr= {5,3,6,8,1,7,9,4,2};
for(int i=0;i<arr.length-1;i++) {
int minPos=i;
for(int j=i+1;j<arr.length;j++) {
minPos=arr[j]<arr[minPos]? j:minPos;
}
int temp=arr[i];
arr[i]=arr[minPos];
arr[minPos]=temp;
}
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
插入排序
插入排序算法是所有排序方法中最简单的一种算法,其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据。
//插入排序
public class InsertionSort {
public static void main(String[] args) {
int []a= {9,3,1,4,6,8,7,5,2};
sort(a);
print(a);
}
static void sort(int[] a) {
for(int i=1;i<a.length;i++) {
for(int j=i;j>0;j--) {//从二个数开始,与前面相比较,如果小就换位,插入前面的位置
if(a[j]<a[j-1])
swap(a,j,j-1);
}
}
}
static void swap(int []a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
归并排序
归并排序是将两个或两个以上的有序表组合成一个新的有序表。其基本思想是:先将N个数据看成N个长度为1的表,将相邻两个表合并,得到长度为2的N/2个有序表,进一步将相邻的表合并,得到长度为4的N/4个有序表,以此类推。
//归并排序
public class MergeSort {
public static void main(String[] args) {
// int []a= {9,3,1,4,6,8,7,5,2};
int []a= {1,4,7,8,6,3,9};
sort(a,0,a.length-1);
print(a);
}
public static void sort(int[] arr,int left,int right) {
if (left==right) return;
//分成两半
int mid=left+(right-left)/2;
// int mid=(left+right)/2;
//左边排序
sort(arr,left,mid);
//右边排序
sort(arr, mid+1, right);
merge(arr,left,mid+1,right);
}
static void merge(int[] arr,int leftPtr,int rightPtr,int rightBound) {
int mid=rightPtr-1;
int [] temp=new int[rightBound-leftPtr+1];
int i=leftPtr;
int j=rightPtr;
int k=0;
while(i<=mid && j<=rightBound) {
//数组分成两份,一个从开始位置增加,另一个从末尾开始增加,
//然后两个开始比较,哪个小就放到新数组temp中
if (arr[i]<=arr[j]) {
temp[k]=arr[i];
i++;
k++;
}
else {
temp[k]=arr[j];
j++;
k++;
}
}
while(i<=mid) temp[k++]=arr[i++];
while(j<=rightBound) temp[k++]=arr[j++];
//print(temp);
for (int m = 0; m < temp.length; m++) {
arr[leftPtr+m]=temp[m];
}
}
static void swap(int []a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
快速排序
1.先从数组中找一个轴,比如我找到的是数组最后一个数,然后数组起始和末尾同时往中间缩
package 算法学习;
public class QuickSort {
public static void main(String[] args) {
int []a= {3,1,4,5,8,9,21,2};
sort(a, 0, a.length-1);
print(a);
}
public static void sort(int[] arr,int leftBound,int rightBound) {
if (leftBound>=rightBound) return;
int mid=partition( arr, leftBound, rightBound);
sort(arr, leftBound, mid-1);
sort(arr, mid+1, rightBound);
}
static int partition(int[] arr,int leftBound,int rightBound) {
int pivot=arr[rightBound];//轴
int left=leftBound;
int right=rightBound-1;
while(left<=right) {
//一个数组从两边开始,一边从开始位置++,一边从末尾位置--
//如果左边出现了比选择的轴大的跳出循环,然后等右边出现比他大的,两个交换
while(left<=right && arr[left]<=pivot)left++;
while(left<=right && arr[right]>pivot)right--;
if (left<right) {
swap(arr, left, right);
}
}
swap(arr, left, rightBound);
return left;
}
static void swap(int []a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
计数排序
计数排序有局限性,是桶排序的一种,适合元素的“种类”不大的情况,比如元素最大的数是10。因为计数排序会给每一个相同的数建立一个桶,也就是数组的一个位置
import java.util.Arrays;
//计数排序
public class CountSort {
public static void main(String[] args) {
// int []a= {9,3,1,4,6,8,7,5,2};
int []arr= {1,4,7,8,6,3,9,2,2,1,1,0,0,4,4,2};
System.out.println(Arrays.toString(arr));
int[] result=sort(arr);
System.out.println(Arrays.toString(result));
}
static int[] sort(int[] arr) {
int []result=new int[arr.length];
int []count=new int[10];
//用一个计数数组,记录每个数的出现的次数
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++; //数组值固定,如果出现就在每个数组上++
}
System.out.println(Arrays.toString(count));
// for (int j = 0,i=0; j < count.length; j++) {
// while (count[j]-->0) {
// result[i++]=j;
// }
//}
for (int i = 1; i < count.length; i++) {
count[i]=count[i]+count[i-1];
}
System.out.println("将count加起来,就可以知道每个数的位置在哪里,然后从数组最后开始"+Arrays.toString(count));
for (int i = arr.length-1; i >=0; i--) {
result[--count[arr[i]]]=arr[i];
}
return result;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
基数排序
基于计数排序的一种,这里用三位数作为例子,先个位数排序,然后十位数排序,最后百位数排序,最终达到排序好。
package 算法学习;
import java.util.Arrays;
//基数排序
public class RadixSort {
public static void main(String[] args) {
int []a= {224,22,123,678,345,241,255,456,127,987};
sort(a);
print(a);
}
public static int[] sort(int[] arr) {
int[] result=new int[arr.length];
int[]count=new int[10];
//三位数的基数排序,循环使用计数排序
for (int i = 0; i < 3; i++) {
int division =(int)Math.pow(10, i);
for (int j = 0; j < arr.length; j++) {
int num=arr[j]/division%10;
count[num]++;
}
System.out.println(Arrays.toString(count));
for (int m = 1; m < count.length; m++) {
count[m]=count[m]+count[m-1];
}
System.out.println(Arrays.toString(count));
for (int n = arr.length-1; n >=0; n--) {
int num=arr[n]/division%10;
result[--count[num]]=arr[n];
}
System.arraycopy(result, 0, arr,0, arr.length);
Arrays.fill(count, 0);
}
return result;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
希尔排序
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
package 算法学习;
public class ShellSort {
//希尔排序
public static void main(String[] args) {
int []a= {9,3,1,4,6,8,7,5,2};
sort(a);
print(a);
}
public static void sort(int[] arr) {
int h=1;
while(h<=arr.length/3) {
h=h*3+1;
}
for (int gap = h; gap >0; gap=(gap-1)/3) {
for(int i=gap;i<arr.length;i++) {
for(int j=i;j>gap-1;j-=gap) {//从二个数开始,与前面相比较,如果小就换位,插入前面的位置
if(arr[j]<arr[j-gap])
swap(arr,j,j-gap);
}
}
}
}
static void swap(int []a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
static void print (int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}