十大排序算法源代码(Java版)
参考了网上很多关于原理类的文章、好多篇java版源代码,也有自己写的代码。
//file name: BubbleSort.java
//冒泡排序package cn.study.sort;
public class BubbleSort {
public static int[] bubbleSort(int[] arr){
if(arr == null || arr.length == 0){
return null;
}
for(int i = 0; i < arr.length -1; i++){//控制比较的次数,比较次数为数组长度减一
for(int j = 0; j < arr.length -1; j++){//每次都是相邻两个比较
if(arr[j] > arr[j + 1]){//大于,就交换,代表每次把小的数据往前排,把大的数据往后排
swap(arr, j, j + 1);
}
}
}
return arr;
} private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
bubbleSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}
}
//====
//file name: SelectionSort.java
//选择排序
package cn.study.sort;public class SelectionSort {
public static int[] selectionSort(int[] arr){
if(arr == null || arr.length == 0){
return null;
}
for(int i = 0; i < arr.length - 1; i++){//需要比较的次数,数组长度减一
//先假设每次循环时,最小数的索引为i
int minIndex = i;
//每一个元素都和剩下的未排序的元素比较
for(int j = i + 1; j < arr.length; j++){
if(arr[j] < arr[minIndex]){//寻找最小数
minIndex = j;//将最小数的索引保存
}
}
//经过一轮循环,就可以找出第一个最小值的索引,然后把最小值放到i的位置
swap(arr, i, minIndex);
}
return arr;
} private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
selectionSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}}
//====
//file name: InsertionSort.java
//插入排序
package cn.study.sort;public class InsertionSort {
public static int[] insertionSort(int[] arr){
int preIndex;
int current;
for(int i = 1; i < arr.length; i++){
preIndex = i - 1;
current = arr[i];
while(preIndex >= 0 && arr[preIndex] > current){
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
insertionSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}}
//====
//file name: ShellSort.java
//希尔排序
package cn.study.sort;public class ShellSort {
public static int[] shellSort(int[] arr){
int len = arr.length;
for(int gap = (int)Math.floor(len / 2); gap > 0; gap = (int)Math.floor(gap / 2)){
for(int i = gap; i < len; i++){
int current = arr[i];
int j = i - gap;
while(j >= 0 && arr[j] > current){
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = current;
}
}
return arr;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
shellSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}}
//====
//file name: MergeSort.java
//归并排序
package cn.study.sort;public class MergeSort {
public static int[] mergeSort(int[] arr, int low, int high, int[] tmp){
if(low < high){
int middle = (low + high) / 2;
mergeSort(arr, low, middle, tmp);//对左边序列进行归并排序
mergeSort(arr, middle + 1, high, tmp);//对右边序列进行归并排序
merge(arr, low, middle, high, tmp);//合并两个有序序列
}
return arr;
}
private static void merge(int[] arr, int low, int mid, int high, int[] tmp){
int i = 0;//记录tmp数组的下标位置
int j = low;//左边序列和右边序列起始索引
int k = mid + 1;//右边序列起始索引
while(j <= mid && k <= high){
if(arr[j] < arr[k]){
tmp[i++] = arr[j++];
}else{
tmp[i++] = arr[k++];
}
}
//若左边序列还有剩余,则将其全部拷贝进tmp[]中
while(j <= mid){
tmp[i++] = arr[j++];
}
while(k <= high){
tmp[i++] = arr[k++];
}
for(int t = 0; t < i; t++){
arr[low + t] = tmp[t];
}
}
public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
int[] tmp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, tmp);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:
//2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}}
//====
//file name: QuickSort.java
//快速排序package cn.study.sort;
public class QuickSort {
public static int[] quickSort(int[] arr, int left, int right){
int len = arr.length;
int partitionIndex;
if(left < right){
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex -1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
private static int partition(int[] arr, int left, int right){
int pivot = left;//设定基准值pivot
int index = pivot + 1;
for(int i = index; i <= right; i++){
if(arr[i] < arr[pivot]){
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index - 1;
} private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
quickSort(arr, 0, arr.length - 1);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:
//2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}
}
//====
//file name: HeapSort.java
//堆排序
package cn.study.sort;public class HeapSort {
public static int[] heapSort(int[] arr){
buildMaxHeap(arr);
for(int i = arr.length - 1; i > 0; i--){
swap(arr, 0, i);
heapAdjust(arr, i, 0);
}
return arr;
} private static void buildMaxHeap(int[] arr) {//建立大顶堆,最大值在根节点
for(int i = (int)Math.floor(arr.length / 2); i >= 0; i--){
heapAdjust(arr, arr.length, i);
}
} //length为本次需要调整的一部分数组的长度,不是整个原始数组的长度。也就是说,不要用arr.length。
//i为需要调整的节点的索引
private static void heapAdjust(int[] arr, int length, int i) {//堆调整
int root = i;//按照大顶堆的定义,根节点是最大值。把要进行调整的节点i当做根节点,并且按照最大堆的定义将根节点当做最大值。
int left = 2 * i + 1;//左叶子节点
int right = 2 * i + 2;//右叶子节点
//跟左叶子节点的值进行比较,如果左叶子节点比根节点大,就将根节点指向它。
if(left < length && arr[left] > arr[root]){
root = left;
}
//跟右叶子节点的值进行比较,如果右叶子节点比根节点大,就将根节点指向它。
if(right < length && arr[right] > arr[root]){
root = right;
}
//到这里就找到了根节点、左孩子、右孩子当中的最大值,这个值的索引用root来标记。
if(root != i){//如果最大值的索引与待调整的节点不一致,说明需要调整大顶堆。
swap(arr, i, root);//先将待调整的节点与根节点交换
heapAdjust(arr, length, root);//调整大顶堆
}
} private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
heapSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:
//2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}}
//====
//file name: CountingSort.java
//计数排序package cn.study.sort;
import java.util.*;
public class CountingSort { public static int[] countingSort(int[] arr) {
int[] tempArr = new int[arr.length];//临时数组
int[] timesArr;//统计每个元素出现的次数,放入到对应的桶中
int range;//统计这一组的范围,得出需要多少个桶
//找出待排序的数组中的最大元素和最小元素
int max = arr[0];
int min = arr[0];
for (int element : arr) {
if (element > max)
max = element;
if (element < min)
min = element;
}
range = max - min + 1;// 得出极值差,为了减小临时数组(统计各元素出现的次数)的长度
timesArr = new int[range];
for (int i = 0; i < arr.length; i++) {
timesArr[arr[i] - min]++;
}
for (int i = 1; i < timesArr.length; i++) {// 得到所有元素的大小上的总体顺序
timesArr[i] += timesArr[i - 1];
}
for (int i = 0; i < arr.length; i++) {// 将arr中元素的位置顺序对应到临时数组中
int position = timesArr[arr[i] - min];// 得到arr[i]这个元素在整体上的位置
tempArr[--position] = arr[i];// 根据上面的位置,将该元素放入到临时数组中
timesArr[arr[i] - min]--;
}
for (int i = 0; i < arr.length; i++) {
arr[i] = tempArr[i];
}
return arr;
}
public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
countingSort(arr);
for(int i = 0; i < arr.length; i++){
if(i == arr.length - 1){
System.out.println(arr[i]);
continue;
}
System.out.print(arr[i] + ", ");
}
//排序后的数据:
//2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50
}
}
//====
//file name: BucketSort.java
//桶排序
package cn.study.sort;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class BucketSort {
public static List bucketSort(int[] arr) {
int max = arr[0];
int min = arr[0];
//找出数组中最大最小值
for (int i = 1; i < arr.length; i++) {
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
//计算桶的数量
int bucketCount = (max - min) / arr.length + 1;
//创建桶数组
ArrayList<ArrayList<Integer>> bucketArray = new ArrayList<ArrayList<Integer>>(bucketCount);
for (int i = 0; i < bucketCount; i++) {
bucketArray.add(new ArrayList<Integer>());
}
//把数据放入桶中
for (int i = 0; i < arr.length; i++) {
bucketArray.get((arr[i] - min) / arr.length).add(arr[i]);
}
//对每个桶中的数据排序
for (int i = 0; i < bucketArray.size(); i++) {
Collections.sort(bucketArray.get(i));
}
return bucketArray;
} public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
ArrayList list = (ArrayList) bucketSort(arr);
System.out.println(list.toString());
//排序后的数据:
//[[2, 3, 4, 5, 15], [19, 26, 27], [36, 38, 44, 46], [47, 48, 50]]
}}
//====
//file name: RadixSort.java
//基数排序
package cn.study.sort;import java.util.Arrays;
public class RadixSort {
public static void radixSort(int[] arr) {
//待排序列最大值
int max = arr[0];
int exp;//指数 //计算最大值
for (int element : arr) {
if (element > max) {
max = element;
}
} //从个位开始,对数组进行排序
for (exp = 1; max / exp > 0; exp *= 10) {
//存储待排元素的临时数组
int[] temp = new int[arr.length];
//分桶个数
int[] buckets = new int[10]; //将数据出现的次数存储在buckets中
for (int value : arr) {
//(value / exp) % 10 :value的最低位(个位)
buckets[(value / exp) % 10]++;
} //更改buckets[i],
for (int i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
} //将数据存储到临时数组temp中
for (int i = arr.length - 1; i >= 0; i--) {
temp[buckets[(arr[i] / exp) % 10] - 1] = arr[i];
buckets[(arr[i] / exp) % 10]--;
} //将有序元素temp拷贝给arr
System.arraycopy(temp, 0, arr, 0, arr.length);
} }
public static void main(String[] args) {
int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
radixSort(arr);
System.out.println(Arrays.toString(arr));
//排序后的数据:
//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
}}