1.冒泡排序
public static void bubul(int arr[]){ for(int i = 0;i<arr.length;i++){ for(int j = 0;j<arr.length-1-i;j++){ //最后i个元素顺序不用改变 if(arr[j] > arr[j+1]){ int t; t = arr[j]; arr[j] = arr[j+1]; arr[j+1] = t; } } } }
第二层循环将数组从头开始两两比较,交换最后得到一个最大值在数组最后,再在第一层循环里循环n次。
2.堆排序
//维护堆的性质 public static void heapify(int[] arr,int n,int i) { int largest = i; int lson = i*2 + 1; int rson = i*2 + 2; if((lson < n)&&(arr[largest]<arr[lson])) { largest = lson; } //可能lson和rson的值会大于n因此if里要先判断 if((rson < n)&&(arr[largest]<arr[rson])) { largest = rson; } if(largest != i) { int temp = arr[largest]; arr[largest] = arr[i]; arr[i] = temp; //当位置改变时其后面堆的性质可能也会发生改变 heapify(arr,n,largest); } } //堆排序的入口 public static void heap_sort(int[] arr,int n) { //从最后一个父节点开始向上维护堆的性质 for(int i = n/2-1;i>=0;i--) { heapify(arr,n,i); } //将堆顶元素和堆底元素交换,将最大值放在数组最后,并从堆顶开始维护堆的性质 for(int i = n-1;i>=0;i--) { int demo = arr[0]; arr[0] = arr[i]; arr[i] = demo; heapify(arr,i,0); } }
分两步,其一建立一个函数用来维护堆的性质,然后开始建堆,将最大值放在数组最后。
3.快排
public static void sort(int arr[],int left,int right) { //递归出口 if(left >= right) { return; } //定义变量保存基准数 int base = arr[left]; //定义i和j的游标 int i = left; int j = right; while(i != j) { //j从后往前找比基准数小的,找到后停下 while(arr[j] >= base&&i<j) { j--; } //i从前往后找比基准数大的,找到后停下 while(arr[i] <= base&&i<j) { i++; } //i和j交换 int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } //i和j相遇后基准数和相遇位置数据进行交换 arr[left] = arr[i]; arr[i] = base; //拆分左边 sort(arr,left,i-1); //拆分右边 sort(arr,i+1,right); }
快排要以第一个元素为基准数,分成左右两波比基准数小和大,最后将i和j相等位置的数据和基准数交换,之后不断递归新基准数的左侧和右侧。
4.选择排序
public static void sort(int[] arr) { for(int i = 0;i<arr.length;i++) { int min = arr[i];//记录最小值 int minIndex = i;//记录最小值下标 for(int j = i+1;j<arr.length;j++) { if(arr[j]<min) { min = arr[j]; minIndex = j; } } //最小值和待排序数组和第一个进行交换 arr[minIndex] = arr[i]; arr[i] = min; } } }
将第一个元素当作最小值,遍历之后的元素当找到最小的值后将其与之交换,之后不断重复。
5.插入排序
public static void sort(int[] arr) { for(int i = 1;i<arr.length;i++) { for(int j = i-1;j>=0;j--) { if(arr[j]>arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; }else { break; } } } } }
将每个插入元素都与前面排好序的数组进行比较插入。(但越小的数在后面移动的越多,改良希尔排序)。
6.希尔排序
public static void sort(int[] arr) { for(int grp = arr.length/2;grp>=1;grp/=2) { for(int i = grp;i<arr.length;i++) { for(int j = i-grp;j>=0;j-=grp) { if(arr[j+grp]<arr[j]) { int temp = arr[j]; arr[j] = arr[j+grp]; arr[j+grp] = temp; }else { break; } } } } }
将数组不断按照组长的一半(一半的一半....)为间隔进行分组,每组进行插入排序。
7.基数排序
适用于数据量远远大于每个数据本身
public static void sort(int[] arr) { //找数组当中最大值 int max = arr[0]; for(int j = 0;j<arr.length;j++) { if(arr[j]>max) { max = arr[j]; } } //获取最大值的位数 int maxLength = (max+"").length(); //定义桶 int[][] bucket = new int[10][arr.length]; //定义桶记录工具 int[] bucketCounts = new int[10]; int n = 1; for(int h = 0;h<maxLength;h++) { //将输入放入桶内 for(int i = 0;i<arr.length;i++) { //放到那个桶 int element = arr[i]/n%10;//获取个位数值 element代表个位或十位或百位数值,也代表要放入那号桶 //读取桶记录工具,确定放入桶哪个位置 int count = bucketCounts[element]; //数据放入 bucket[element][count] = arr[i]; //桶记录+1 bucketCounts[element]++; } //数据取出 //遍历数组 int index = 0; //遍历桶记录 for(int k = 0;k<bucketCounts.length;k++) { if(bucketCounts[k]!=0) { for(int l = 0;l<bucketCounts[k];l++) { arr[index] = bucket[k][l]; index++; } } bucketCounts[k] = 0; } n*=10; } }
8.归并排序
//拆分 public static void split(int[] arr,int left,int right) { if(left == right) { return; } int i = (left+right)/2; //向左递归 split(arr,left,i); //向右递归 split(arr,i+1,right); //合并 merge(arr,left,i,right); } //合并 public static void merge(int[] arr,int left,int mid,int right) { int s1 = left; int s2 = mid+1; //临时数组 int temp[] = new int[right-left+1]; //临时数组下标 int index = 0; while(s1<=mid&&s2<=right) { if(arr[s1]<arr[s2]) { temp[index] = arr[s1]; index++; s1++; }else { temp[index] = arr[s2]; index++; s2++; } } //判断s1当中是否有数据 while(s1<=mid) { temp[index] = arr[s1]; index++; s1++; } //判断s2当中是否有数据 while(s2<=right) { temp[index] = arr[s2]; index++; s2++; } //临时数组当中的数值放回原数组 for(int j = 0;j<temp.length;j++) { arr[left+j] = temp[j]; } }