冒泡排序算法:
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
快速排序算法:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为基准数,赋值给pivot,即pivot=A[0]=A[i];
3)由后向前搜索(j--),找到第一个小于pivot的值A[j],将A[j]和A[i]的值交换;
4)由前向后搜索(i++),找到第一个大于pivot的A[i],将A[i]和A[j]的值交换;
5)重复第3、4步,直到i==j;
插入排序算法:
把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
希尔排序算法:
希尔排序是把记录按照下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,整个元素恰被分成一组,算法便终止。
选择排序算法:
以由小到大排序为例,首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
堆排序算法:
1)根据初始数组去构造初始堆。
2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆,再进行交换第一个元素和最后一个元素,再调整大顶堆,重复执行,直到整个数组排序完成。
归并排序算法:
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列。
计数排序算法:
桶排序算法:
- 根据待排序集合中的数据,确定映射规则和桶的数量;
- 遍历待排序集合,将每一个元素根据映射规则,移动到对应的桶中;
- 对每一个桶中元素进行排序。
- 依次输出每个桶中的数据,得到整个有序的集合。
package main;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class main {
public static void main(String[] args) {
//冒泡排序
int[] arr = {9,8,5,4,2,3};
bubbleSort(arr);
System.out.println("冒泡排序:"+Arrays.toString(arr));
//快速排序
int[] arr1 = {9,8,5,4,2,3};
quickSort(arr1,0,arr1.length-1);
System.out.println("快速排序:"+Arrays.toString(arr1));
//插入排序
int[] arr2 = {9,8,5,4,2,3};
insertSort(arr2);
System.out.println("插入排序:"+Arrays.toString(arr2));
//希尔排序
int[] arr3 = {9,8,5,4,2,3};
shellSort(arr3);
System.out.println("希尔排序:"+Arrays.toString(arr3));
//选择排序
int[] arr4 = {9,8,5,4,2,3};
selectionSort(arr4);
System.out.println("选择排序:"+Arrays.toString(arr4));
//堆排序
int[] arr5 = {9,8,5,4,2,3};
heapSort(arr5);
System.out.println("堆排序:"+Arrays.toString(arr5));
//归并排序
int[] arr6 = {9,8,5,4,2,3};
mergeSort(arr6,0,arr6.length-1);
System.out.println("归并排序:"+Arrays.toString(arr6));
//计数排序
int[] arr7 = {9,8,5,4,2,3};
countSort(arr7);
System.out.println("计数排序:"+Arrays.toString(arr7));
//桶排序
int[] arr8 = {9,8,5,4,2,3};
bucketSort(arr8);
System.out.println("桶排序:"+Arrays.toString(arr8));
}
//交换方法
public static void swap(int arr[],int i ,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//冒泡排序
public static void bubbleSort (int arr[]){
for(int i=1;i<arr.length;i++){
for(int j=0;j<arr.length-i;j++){
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
}
//快速排序
public static void quickSort(int arr[],int low,int high){
if(low<high){
int i = low;
int j = high;
while (i<j){
//从后往前
while (j>i && arr[j]>=arr[i]){
j--;
}
//交换
swap(arr,i,j);
//从前往后
while (j>i && arr[i]<=arr[j]){
i++;
}
//交换
swap(arr,i,j);
}
//向左边递归
quickSort(arr,low,j-1);
//向右边递归
quickSort(arr,j+1,high);
}
}
//插入排序
public static void insertSort(int arr[]){
for(int i=1;i<arr.length;i++){
for(int j=i;j>0;j--){
if(arr[j]<arr[j-1]){
swap(arr,j,j-1);
}else{
break;
}
}
}
}
//希尔排序(不稳定)
public static void shellSort(int arr[]){
//增量gap,并逐渐缩小增量
for(int gap=arr.length/2;gap>0;gap=gap/2){
//从第gap个元素开始,逐渐对其所在的组进行插入排序
for (int i=gap;i<arr.length;i++){
for (int j=i;j>=gap;j=j-gap){
//如果后面的元素大于前面的元素==》交换
if(arr[j]<arr[j-gap]){
swap(arr,j,j-gap);
}else{
break;
}
}
}
}
}
//选择排序(不稳定)
public static void selectionSort(int arr[]){
for (int i=0;i<arr.length-1;i++){
int min_index = i;
for (int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min_index]){
min_index = j ;
}
}
swap(arr,i,min_index);
}
}
//堆排序(不稳定)
public static void heapSort(int[] arr){
//初始建堆
for (int i=arr.length/2-1;i>=0;i--){
heapify(arr,i,arr.length-1);
}
//堆排序的过程
for (int i=arr.length-1;i>0;i--){
swap(arr,0,i);
heapify(arr,0,i-1);
}
}
public static void heapify(int arr[] ,int i,int last_index){
int max = i;
//判断是否有左孩子,如果有--》与最大节点比较
if(2*i+1<=last_index && arr[2*i+1]>arr[max]){
max = 2*i+1;//记左节点为最大值
}
//判断是否有右节点,如果有--》与最大节点比较
if (2*i+2<=last_index && arr[2*i+2]>arr[max]){
max = 2*i+2;//记右节点为最大值
}
//如果最大节点发生交换,就交换两个节点的位置
if(max!=i){
swap(arr,i,max);
//交换破坏堆结构,递归调用使堆结构回复
heapify(arr,max,last_index);
}
}
//归并排序(稳定)
public static void mergeSort(int arr[],int low,int high){
if(low<high){
//分两部分
int mid = (low+high)/2;
//1、对左边进行归并排序
mergeSort(arr,low,mid);
//2、对右边进行归并排序
mergeSort(arr,mid+1,high);
//3、3合并左右两个有序集合
merge(arr,low,mid,high);
}
}
public static void merge(int arr[],int low,int mid,int high){
//创建一个临时数组
int temp[] = new int[arr.length];
int i = low;
int j = mid+1;
int k = 0;
while (i<=mid && j<=high){
if (arr[i]<=arr[j]){
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
//左边有剩余
while (i<=mid){
temp[k++] = arr[i++];
}
//右边有剩余
while (j<=high){
temp[k++] = arr[j++];
}
k = 0;
while (low<=high){
arr[low++] = temp[k++];
}
}
//计数排序(稳定,空间换时间)
public static void countSort(int[] arr){
//max
int max = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
max = arr[i];
}
}
//min
int min = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]<min){
min = arr[i];
}
}
//创建计数数组
int count[] = new int[max-min+1];
//遍历arr
for (int i=0;i<arr.length;i++){
count[arr[i]-min]++;
}
//遍历计数数组
int k = 0;
for (int i=0;i<count.length;i++){
while (count[i]>0){
arr[k++] = i + min;
count[i]--;
}
}
}
//桶排序(稳定性取决于桶内的排序算法)
public static void bucketSort(int arr[]){
//max
int max = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
max = arr[i];
}
}
//min
int min = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]<min){
min = arr[i];
}
}
//确定桶的数量
ArrayList<ArrayList<Integer>> buckets = new ArrayList<>();
int count = (max -min)/arr.length +1;
for (int i=0;i<count;i++){
buckets.add(new ArrayList<Integer>());
}
//遍历arr,把对应数据放在桶里
for (int i=0;i<arr.length;i++){
buckets.get((arr[i]-min)/arr.length).add(arr[i]);
}
//对每个桶分别排序
for (int i=0;i<buckets.size();i++){
Collections.sort(buckets.get(i));
}
//把桶里的内容输出
int k = 0;
for (int i=0;i<buckets.size();i++){
ArrayList<Integer> list = buckets.get(i);
for (int j=0;j<list.size();j++){
arr[k++] = list.get(j);
}
}
}
}