1、冒泡排序
在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序。
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int a = in.nextInt();
int[] array = new int[a];
for(int i = 0; i < a; i++){
array[i] = in.nextInt();
}
for(int i = 0; i < array.length-1; i++){
for(int j = 0; j < array.length -1-i;j++){
if(array[j] > array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
String cur = Arrays.toString(array);
System.out.println(cur);
}
2、插入排序
a、默认从第二个数据开始比较。
b、如果第二个数据比第一个小,则交换。然后在用第三个数据比较,如果比前面小,则插入(狡猾)。否则,退出循环
c、说明:默认将第一数据看成有序列表,后面无序的列表循环每一个数据,如果比前面的数据小则插入(交换)。否则退出。
d、代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4};
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0 ; j--) {
if(arr[j] < arr[j-1]){
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}else{
break;
}
}
}
}
3、希尔排序
a、基本上和插入排序一样的道理
b、不一样的地方在于,每次循环的步长,通过减半的方式来实现
c、说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。
d、代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4};
for (int i = arr.length/2; i > 0 ; i/=2) {
for(int j = i; j < arr.length; j++){
for (int k = j; k > 0 && k-i >= 0; k-=i) {
if (arr[k] < arr[k - i]) {
int temp = arr[k - i];
arr[k - i] = arr[k];
arr[k] = temp;
} else {
break;
}
}
}
}
}
4 、快速排序
a、确认列表第一个数据为中间值,第一个值看成空缺(低指针空缺)。
b、然后在剩下的队列中,看成有左右两个指针(高低)。
c、开始高指针向左移动,如果遇到小于中间值的数据,则将这个数据赋值到低指针空缺,并且将高指针的数据看成空缺值(高指针空缺)。然后先向右移动一下低指针,并且切换低指针移动。
d、当低指针移动到大于中间值的时候,赋值到高指针空缺的地方。然后先高指针向左移动,并且切换高指针移动。重复c、d操作。
e、直到高指针和低指针相等时退出,并且将中间值赋值给对应指针位置。
f、然后将中间值的左右两边看成行的列表,进行快速排序操作。
g、代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4, 1, 7, 9, 6};
int high = arr.length - 1;
int low = 0;
quickSort(arr,low,high);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr,int low, int high){
if(high - low < 1){
return;
}
boolean flag =true;
int start = low;
int end = high;
int midValue = arr[low];
while (true){
if(flag){
if(arr[high] >= midValue){
high--;
}else{
arr[low] = arr[high];
flag = false;
}
}else{
if(arr[low] <= midValue){
low++;
}else{
arr[high] = arr[low];
flag = true;
}
}
if(low == high){
arr[low] = midValue;
break;
}
}
quickSort(arr,start,low-1);
quickSort(arr,low+1,end);
}
5、堆排
public static void main(String[] args) {
int arr[] = { 27,15,19,18,28,34,65,49,25,37};
creatHeap(arr);
for (int i = 0; i < arr.length - 1 ; i++) {
int tmp = arr[arr.length - 1-i];
arr[arr.length - 1-i] = arr[0];
arr[0] = tmp;
adjustdown(arr,0,arr.length - 1- i);
}
System.out.println(Arrays.toString(arr));
}
public static void creatHeap(int[] arr){
for (int i = (arr.length-1-1)/2; i >= 0 ; i--) {
adjustdown(arr,i,arr.length);
}
}
private static void adjustdown(int[] arr, int i, int length) {
int child = 2 * i + 1;
while(child < length){
if(child +1 < length && arr[child] < arr[child +1]){
child++;
}
if(arr[i] < arr[child]){
int tmp = arr[i];
arr[i] = arr[child];
arr[child] = tmp;
i = child;
child = 2 * i + 1;
}else{
break;
}
}
}
6、归并排序
1、原理
归并排序是一种概念上最简单的排序算法,与快速排序一样,归并排序也是基于分治法的。归并排序将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将他们合并成一个子序列。合并两个子序列的过程也就是两路归并。
2、复杂度
归并排序是一种稳定的排序算法,归并排序的主要问题在于它需要一个与待排序数组一样大的辅助数组空间。由于归并排序每次划分时两个子序列的长度基本一样,所以归并排序最好、最差和平均时间复杂度都是nlog2n。
我们可以通过下图非常容易看懂归并排序的过程:
public static void main(String[] args) {
int[] a = { 49, 38, 65, 97, 76, 13, 27, 50 };
mergeSort(a, 0, a.length-1);
System.out.println("排好序的数组:");
for (int e : a)
System.out.print(e+" ");
}
public static void mergeSort(int[] a,int start,int end){
if(start < end){
int mid = (start + end)/2;
int tmp[] = new int [a.length];
mergeSort(a,start,mid);
mergeSort(a,mid+1,end);
merge(a,start,mid,end,tmp);
}
}
private static void merge(int[] a, int start, int mid, int end,int[] tmp) {
int p1 = start;
int p2 = mid +1;
int k = start;
while (p1 <= mid && p2 <= end){
if(a[p1] <= a[p2]){
tmp[k++] = a[p1++];
}else{
tmp[k++] = a[p2++];
}
while (p1 <= mid){
tmp[k++] = a[p1++];
}
while (p2 <= end){
tmp[k++]=a[p2++];
}
for (int i = start; i <= end ; i++) {
a[i] = tmp[i];
}
}
}