java实现八大排序
package com.demo01;
import java.util.Arrays;
import java.util.Scanner;
public class Array {
/*
* 冒泡排序冒泡排序:
* 比较相邻的元素。两两对比,如果第一个比第二个数大,就交换位置
* 走第一轮会得到一个最大值/最小值。
* n个数,排好序需要n轮
*/
public static void sortBubbling(int[] arr){
for(int i=0; i<arr.length; i++){
for(int j =i ;j<arr.length; j++){
if(arr[i] > arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.print("排序后的数组:");
for(int i=0; i<arr.length;i++){
System.out.print(arr[i]+",");
}
}
/*
* 快速排序:
* 通过一趟排序将待排序记录分割成独立的两部分,
* 其中一部分记录的关键字均比另一部分关键字小,
* 则分别对这两部分继续进行排序,直到整个序列有序
* 把整个序列看做一个数组,把第零个位置看做中轴,和最后一个比,
* 如果比它小交换,比它大不做任何处理;
* 交换了以后再和小的那端比,比它小不交换,比他大交换。
* 这样循环往复,一趟排序完成,左边就是比中轴小的,
* 右边就是比中轴大的,然后再用分治法,分别对这两个独立的数组进行排序。
*/
public static int getMiddle(int[] numbers, int low,int high){
int temp = numbers[low]; //数组的第一个作为中轴
while(low < high){
while(low < high && numbers[high] >= temp){
high--;
}
numbers[low] = numbers[high];//比中轴小的记录移到低端
while(low < high && numbers[low] < temp){
low++;
}
numbers[high] = numbers[low] ; //比中轴大的记录移到高端
}
numbers[low] = temp ; //中轴记录到尾
return low ; // 返回中轴的位置
}
public static void quickSort(int[] numbers,int low,int high){
if(low < high){
int middle = getMiddle(numbers,low,high); //将numbers数组进行一分为二
quickSort(numbers, low, middle-1); //对低字段表进行递归排序
quickSort(numbers, middle+1, high); //对高字段表进行递归排序
}
}
public static void quick(int[] numbers){
if(numbers.length > 0){ //查看数组是否为空
quickSort(numbers, 0, numbers.length-1);
}
}
/*
* 选择排序:
* 在一组数中,选出最小的一个数与第一个位置交换。
* 在剩下的数中重复上一步
*/
public static void selectSort(int[] numbers){
int size = numbers.length; //数组长度
int temp = 0 ; //中间变量
for(int i = 0 ; i < size ; i++){
int k = i; //待确定的位置
//选择出应该在第i个位置的数
for(int j = size -1 ; j > i ; j--){
if(numbers[j] < numbers[k]){
k = j;
}
}
//交换两个数
temp = numbers[i];
numbers[i] = numbers[k];
numbers[k] = temp;
}
}
/*
* 插入排序:
* 一组数,按其顺序码大小插入到前面已经排序的字序列的合适位置
* (从后向前找到合适位置后),直到全部插入排序完为止。
* 时间复杂度:O(n^2).
*/
public static void insertSort(int[] numbers){
int size = numbers.length;
int temp = 0 ;
int j = 0;
for(int i = 0 ; i < size ; i++){
temp = numbers[i];
//假如temp比前面的值小,则将前面的值后移
for(j = i ; j > 0 && temp < numbers[j-1] ; j --){
numbers[j] = numbers[j-1];
}
numbers[j] = temp;
}
}
/*
* 希尔排序:
* 将序列分割成为若干子序列分别进行直接插入排序,
* 待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
* 拿数组5, 2, 8, 9, 1, 3,4来说,数组长度为7,当increment为7/2=3时,数组分为两个序列
* 5,2,8和9,1,3,4,
* 9和5比较,1和2比较,3和8比较,4和比其下标值小increment的数组值相比较
* 第一次排序后数组为5, 1,3, 9, 2, 8, 4
* 第一次后increment的值变为3/2=1,此时对数组进行插入排序
* O(n^2).
*/
public static void shellSort(int[] data) {
int j = 0;
int temp = 0;
//每次将步长缩短为原来的一半
for (int increment = data.length / 2; increment > 0; increment /= 2){
for (int i = increment; i < data.length; i++) {
temp = data[i];
for (j = i; j >= increment; j -= increment){
if(temp < data[j - increment]){ //如想从小到大排只需修改这里
data[j] = data[j - increment];
}else{
break;
}
}
data[j] = temp;
}
}
}
/*
* 归并排序:
* 将两个(或两个以上)有序表合并成一个新的有序表,
* 即把待排序序列分为若干个子序列,每个子序列是有序的。
* 然后再把有序子序列合并为整体有序序列。
*/
//归并排序
public static void mergeSort(int[] arr){
int[] temp =new int[arr.length];
internalMergeSort(arr, temp, 0, arr.length-1);
}
private static void internalMergeSort(int[] a, int[] temp, int left, int right){
//当left==right的时,已经不需要再划分了
if (left<right){
int middle = (left+right)/2;
internalMergeSort(a, temp, left, middle); //左子数组
internalMergeSort(a, temp, middle+1, right); //右子数组
mergeSortedArray(a, temp, left, middle, right); //合并两个子数组
}
}
// 合并两个有序子序列 arr[left, ..., middle] 和 arr[middle+1, ..., right]。temp是辅助数组。
private static void mergeSortedArray(int arr[], int temp[], int left, int middle, int right){
int i=left;
int j=middle+1;
int k=0;
while ( i<=middle && j<=right){
if (arr[i] <=arr[j]){
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
while (i <=middle){
temp[k++] = arr[i++];
}
while ( j<=right){
temp[k++] = arr[j++];
}
//把数据复制回原数组
for (i=0; i<k; ++i){
arr[left+i] = temp[i];
}
}
/*
* 堆排序:
* 根节点为最大值,大顶堆
*/
//对data数组从0到lastIndex建大顶堆
public static void buildMaxHeap(int[] data, int lastIndex){
//从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)/2;i>=0;i--){
//k保存正在判断的节点
int k=i;
//如果当前k节点的子节点存在
while(k*2+1<=lastIndex){
//k节点的左子节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex<lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}
}
}
//交换
private static void swap(int[] data, int i, int j) {
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int [] arr = {54,75,13,678,23,74,1,67,75,12};
/*for(int i=0; i<arr.length;i++){
System.out.println("请输入第"+i+"个数:");
arr[i] = sc.nextInt();
}*/
// sortBubbling(arr);
// selectSort(arr);
// quick(arr);
// insertSort(arr);
// shellSort(arr);
// mergeSort(arr);
int arrayLength=arr.length;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆
buildMaxHeap(arr,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(arr,0,arrayLength-1-i);
System.out.println(Arrays.toString(arr));
}
printArr(arr);
}
public static void printArr(int[] numbers){
System.out.print("排序后:");
for(int i = 0 ; i < numbers.length ; i ++ ){
System.out.print(numbers[i] + ",");
}
System.out.println("");
}
}
浙公网安备 33010602011771号