Java--十大排序算法
排序数据
package java02;
import java.util.Random;
public class Data {
int num,arr[];
public Data (int n) {
num=n;
arr =new int[num];
Random rand = new Random() ;
for(int i=0;i<num;i++) {
arr[i]=rand.nextInt(10000);
}
}
public void show() {
for(int i=0;i<num;i++) {
System.out.printf("%7d",arr[i]);
if((i+1)%10==0)
System.out.println();
}
}
}
1.冒泡排序BubbleSort
思想:两个相邻元素想比较,不断颠倒位置实现【i,不停的使arr.length-i-1内的最大数的放最后】
-如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动
package java02;
import java.util.Scanner;
public class BubbleSort {
public static void bubblesort(Data array) {
int temp;
for(int i=0;i<array.arr.length-1;i++) {
for(int j=0;j<array.arr.length-i-1;j++) {
if(array.arr[j]>array.arr[j+1]) {
temp=array.arr[j];
array.arr[j]=array.arr[j+1];
array.arr[j+1]=temp;
}
}
}
}
public static void main(String [] argv) {
Scanner sc =new Scanner (System.in);
Data array;
int n;
System.out.print("【冒泡排序】请输入排序个数");
n=sc.nextInt();
array=new Data(n);
System.out.println("排序前数字为");
array.show();
System.out.println("排序后数字为");
bubblesort(array);
array.show();
sc.close();
}
}
2.选择排序SelectSort
思想: 从下标0开始,先设其为最大值max,寻找后面其余数的最大值,若找到则另其在下标0.
package java01;
import java.util.Scanner;
public class SelectSort {
public static void selectSort(Data array) {
int k, max;
for (int i = 0; i < array.arr.length - 1; i++) {
max = array.arr[i];
k = i;
for (int j = i + 1; j < array.arr.length; j++)
if (max < array.arr[j]) {
k = j;
max = array.arr[j];
}
array.arr[k] = array.arr[i];
array.arr[i] = max;
}
}
public static void main(String [] argv)
{
Scanner sc = new Scanner(System.in);
Data array; // 声明一个Data类型的对象
int n;
System.out.print("请输入要排序的元素个数:");
n = sc.nextInt();
array = new Data(n); // 创建一个Data类型的对象
System.out.println("随机生成的数据:");
array.dataShow(); // 调用对象的显示方法(下同)
selectSort(array); // 选择排序
System.out.println("\n排序后的数据:");
array.dataShow();
sc.close();
}
}
3.插入排序
从i1,对每一对相邻元素进行比较,从开始第一对到结尾的最后一对,排在最右的元素就会是最大的数
如果前面的比后面的数大,则交换二者位置。
- 如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动
- 数据有序程度越高,越高效(移动少)
package java02;
import java.util.Scanner;
public class InsertSort {
public static void insertsort(Data array) {
if (array.arr == null || array.arr.length < 2)
return;
for (int i = 1; i < array.arr.length; i++) {
for (int j = i - 1; j >= 0 && array.arr[j] > array.arr[j + 1]; j--) {
int temp = array.arr[j];
array.arr[j] = array.arr[j+1];
array.arr[j+1] = temp;
}
}
}
public static void main(String [] argv) {
Scanner sc =new Scanner (System.in);
Data array;
int n;
System.out.print("【插入排序】请输入排序个数");
n=sc.nextInt();
array=new Data(n);
System.out.println("排序前数字为");
array.show();
System.out.println("排序后数字为");
insertsort(array);
array.show();
sc.close();
}
}
4.希尔排序ShellSort
如果原数组的一个元素如果距离它正确的位置很远的话,则需要与相邻元素交换很多次才能到达正确的位置
希尔排序为插入排序的变形
- 它把较大的数据集合分割成若干个小组(逻辑上分组),然后对每一个小组分别进行插入排序,此时,插入排序所作用的数据量比较小(每一个小组),插入的效率比较高
- 详解
package java02;
import java.util.Scanner;
public class ShellSort {
public static void shellsort(Data array) {
double gap = array.arr.length; //增量长度
int dk,sentinel,k;
while ( true ){
gap = ( int )Math.ceil(gap/ 2 ); //逐渐减小增量长度
dk = ( int )gap; //确定增量长度
for ( int i= 0 ;i<dk;i++){
//用增量将序列分割,分别进行直接插入排序。随着增量变小为1,最后整体进行直接插入排序
for ( int j=i+dk;j<array.arr.length;j = j+dk){
k = j-dk;
sentinel = array.arr[j];
while (k>= 0 && sentinel<array.arr[k]){
array.arr[k+dk] = array.arr[k];
k = k-dk;
}
array.arr[k+dk] = sentinel;
}
}
//当dk为1的时候,整体进行直接插入排序
if (dk== 1 ){
break ;
}
}
}
public static void main(String [] argv) {
Scanner sc =new Scanner(System.in);
int n;
Data array;
System.out.println("【希尔排序】请输入个数");
n= sc.nextInt();
array = new Data(n);
System.out.println("排序前数字为");
array.show();
System.out.println("排序后数字为");
shellsort(array);
array.show();
sc.close();
}
}
5.快速排序QuickSort
package java01;
import java.util.Scanner;
public class QuickSort{
public static void quickSort(Data a, int leftIndex, int rightIndex){
int key, left, right;
left = leftIndex;
right = rightIndex;
if(left >= right)
return;
key = a.arr[left]; // 取出基数
while(left < right){ // 查找数据在列表中的合适位置
while(left < right && a.arr[right] <= key) // 从右往左找,需防止右指针左越界
right--;
a.arr[left] = a.arr[right];
/* 假设此时基数应该存放在此(right)位置,所以它应该大于位于其右边的所有数据 */
while(left < right && a.arr[left] >= key) // 从右往左找,需防止左指针右越界
left++;
a.arr[right] = a.arr[left];
}
a.arr[left] = key; // 确定基数在列表中的位置(数据归位)
quickSort(a, leftIndex, left - 1); // 从确定的基数位置的左边开始归位数据
quickSort(a, right + 1, rightIndex); // 从确定的基数位置的右边开始归位数据
}
public static void main(String[] args){
Data array;
int n;
Scanner sc = new Scanner(System.in);
System.out.print("请输入数组的元素个数:");
n = sc.nextInt();
array = new Data(n);
System.out.println("要排序的数据为:");
array.dataShow();
quickSort(array, 0, n - 1);
System.out.println("排序后的数据为:");
array.dataShow();
sc.close();
}
}
6.堆排序HeapSort
package java02;
import java.util.Scanner;
public class HeapSort {
public static void heapify(Data array,int length,int i){
int left = 2 * i + 1,right = 2 * i + 2;
int largest = i;
if (left < length && array.arr[left] > array.arr[largest]) {
largest = left;
}
if (right < length && array.arr[right] > array.arr[largest]) {
largest = right;
}
if (largest != i){
int temp = array.arr[i];
array.arr[i] = array.arr[largest];
array.arr[largest] = temp;
heapify(array, length,largest);
}
}
public static void heapsort(Data array){
if (array.arr.length == 0) return;
int length = array.arr.length ;
for (int i = length / 2 - 1;i >= 0; i--) {
heapify(array,length,i);
}
for (int i = length - 1; i >= 0;i--){
int temp = array.arr[0];
array.arr[0] = array.arr[i];
array.arr[i] = temp;
heapify(array,i,0);
}
}
public static void main(String [] argv) {
Scanner sc =new Scanner(System.in);
int n;
Data array;
System.out.println("【堆排序】请输入个数");
n= sc.nextInt();
array = new Data(n);
System.out.println("排序前数字为");
array.show();
System.out.println("排序后数字为");
heapsort(array);
array.show();
sc.close();
}}
7.归并排序MergeSort
package java02;
import java.util.Scanner;
public class MergeSort{
public static void merge_Array(int a[], int first, int mid, int last, int temp[]){
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n){
if (a[i] >= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
public static void merge_Sort(int a[], int first, int last, int temp[]){
if (first < last){
int mid = (first + last) / 2;
merge_Sort(a, first, mid, temp); // 左边有序
merge_Sort(a, mid + 1, last, temp); // 右边有序
merge_Array(a, first, mid, last, temp); // 再将二个有序数列合并
}
}
public static void mergeSort(int a[], int n){
int p[] = new int[n];
merge_Sort(a, 0, n - 1, p);
}
public static void main(String[] args){
Data array;
int n;
Scanner sc = new Scanner(System.in);
System.out.print("【归并排序】请输入数组的元素个数:");
n = sc.nextInt();
array = new Data(n);
System.out.println("要排序的数据为:");
array.show();
mergeSort(array.arr, n);
System.out.println("\n排序后的数据为:");
array.show();
sc.close();
}
}
8.基数排序RadioSort
package java02;
import java.util.Arrays;
public class RadioSort {
public static void main(String[] args) {
int[] arr = new int[] { 23, 6, 9, 287, 56, 1, 789, 34, 65, 653 };
System.out.println(Arrays.toString(arr));
radixSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void radixSort(int[] arr) {
// 存数组中最大的数字,为了知道循环几次
int max = Integer.MIN_VALUE;// (整数中的最小数)
// 遍历数组,找出最大值
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
// 计算最大数是几位数,,此方法计较绝妙
int maxLength = (max + "").length();
// 用于临时存储数据的数组
int[][] temp = new int[10][arr.length];
// 用于存储桶内的元素位置
int[] counts = new int[arr.length];
// 第一轮个位数较易得到余数,第二轮就得先除以十再去取余,之后百位除以一百
// 可以看出,还有一个变量随循环次数变化,为了取余
// 循环的次数
for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
// 每一轮取余
for (int j = 0; j < arr.length; j++) {
// 计算余数
int ys = (arr[j] / n) % 10;
// 把便利店数据放在指定数组中,有两个信息,放在第几个桶+数据应该放在第几位
temp[ys][counts[ys]] = arr[j];
// 记录数量
counts[ys]++;
}
// 记录取的数字应该放到位置
int index = 0;
// 每一轮循环之后把数字取出来
for (int k = 0; k < counts.length; k++) {
// 记录数量的数组中当前余数记录不为零
if (counts[k] != 0) {
for (int l = 0; l < counts[k]; l++) {
// 取出元素
arr[index] = temp[k][l];
index++;
}
// 取出后把数量置为零
counts[k] = 0;
}
}
}
}
}
9.计数排序CountSort
package java02;
import java.util.Scanner;
public class CountSort {
public static void countsort(Data array) {
//1.得到数列的最大值
int max = array.arr[0];
for (int i = 0; i < array.arr.length; i++) {
if (array.arr[i] > max) {
max = array.arr[i];
}
}
//2.根据数列最大值确定统计数组的长度
int[] countArray = new int[array.arr.length];
//3.遍历数列,填充统计数组
for (int i = 0; i < array.arr.length; i++) {
countArray[array.arr[i]]++;//每一个整数按照其值对号入座,同时对应数组下标的元素进行加1操作
}
//4.遍历统计数组,输出结果
int index = 0;
int[] sortedArray = new int[array.arr.length];
for (int i = 0; i < array.arr.length; i++) {
for (int j = 0; j < countArray[i]; j++) {
sortedArray[index++] = i;
}
}
return ;
}
public static void main(String [] argv) {
Scanner sc =new Scanner (System.in);
Data array;
int n;
System.out.print("【计数排序】请输入排序个数");
n=sc.nextInt();
array=new Data(n);
System.out.println("排序前数字为");
array.show();
System.out.println("排序后数字为");
countsort(array);
array.show();
sc.close();
}
}
10.桶排序BucketSort
package java02;
import java.util.ArrayList;
import java.util.List;
public class BucketSort {
public static void main(String[] args) {
int a[]= {1,8,7,44,42,46,38,34,33,17,15,16,27,28,24};
List[] buckets=new ArrayList[5];
for(int i=0;i<buckets.length;i++)//初始化
{
buckets[i]=new ArrayList<Integer>();
}
for(int i=0;i<a.length;i++)//将待排序序列放入对应桶中
{
int index=a[i]/10;//对应的桶号
buckets[index].add(a[i]);
}
for(int i=0;i<buckets.length;i++)//每个桶内进行排序(使用系统自带快排)
{
buckets[i].sort(null);
for(int j=0;j<buckets[i].size();j++)//顺便打印输出
{
System.out.print(buckets[i].get(j)+" ");
}
}
}
}