1 冒泡排序:
排序思想是通过依次交换待排序数组的相邻两个元素的值(大数放在后面),进行。对所有的数两两相互比较交换之后,就会实现最终的有序数组。
在这里我们通过两个for循环来实现,首先第一层的for循环i代表每轮要进行交换的边界。第二层for循环j代表真正的实现两两元素的比较。且可以利用flag实现小的时间复杂度。若执行过程中第二层没有发现for循环,就代表排序已经完成,无需下面重复的步骤。
package java基础之数据结构算法.十大排序算法;
import java.util.Arrays;
//冒牌排序的第一种求解的方法
public class BubbleSort {
public static void main(String[] args) {
int[] a ={1,5,7,1,3,3,5,4,8,10};
bubbleSort2(a);
System.out.println(Arrays.toString(a));
}
public static int[] bubbleSort(int[] a){
for(int i = 0; i <a.length-1;i++){
//长度-i-1 是对最后一个数字不进行排序,因为已经排序过了的。
int flag = 0;
for(int j =0;j< a.length-i-1;j++){
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
flag = 1;
}
if(flag == 0 )return a;
}
return a;
}
public static int[] bubbleSort2(int[] a){
for(int i = a.length -1;i>0;i--){
int flag = 0;
for(int j = 0;j < i;j++){
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
flag = 1;
}
if(flag == 0 )return a;
}
return a;
}
}
2 选择排序:
我们在选择排序的思想是利用第一个默认排好顺序的与之后的乱序数组进行元素的交换,当待排序元素大于之后的元素则发生交换。直到排好顺序。
import java.util.Arrays;
//选择排序
//排序思想:从第一个i跟后面小于i的进行一个交换。
public class SelectSort {
public static void main(String[] args) {
int[] a = {1,5,6,1,2,5,7,8,16,2,15,61,1};
selectSort(a);
System.out.println(Arrays.toString(a));
}
public static int[] selectSort(int[] a){
for(int i = 0; i<a.length ;i++ ){
for (int j=i+1; j<a.length; j++){
if(a[i] > a[j]){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a;
}
}
3 插入排序:
插入排序就是将待排序的数组插入到已经排序好的数组中,我们首先默认第一个元素是排好顺序的,因此索引从第二个开始进行,先将待排序的元素的值取出暂存,并将排好顺序的数组元素依次后移,待条件合适,将插入的元素进行插入操作。
import java.util.Arrays;
//插入排序是从无序的序列中找到关键字插入到有序的序列中去;
public class InsertSort {
public static void main(String[] args) {
int[] a = {1,5,6,1,2,5,7,8,36,16,2,15,61,1};
insertSort(a);
System.out.println(Arrays.toString(a));
}
private static int[] insertSort(int[] a) {
//声明初始化的变量
int k ,j = 0;
// 对未排序的字段 从头开始遍历。
for(int i = 1; i < a.length;i++){
//将第一个值取出
k = a[i];
//将 已经排好序的字段 从最后一个索引开始一次往后移一位,直到比排好序的字段大的时候。
for(j = i-1; k<a[j] && j>=0 ; j--){
a[j+1] = a[j];
}
a[j+1] = k;
}
return a;
}
}
4 希尔排序
希尔排序就是在插入排序的基础上,将利用递归的操作将插入排序的步长从1变为一次递归的一个方式,首先是a.length/2 的gap步长,之后一直递归,知道递归的步长为1位置。
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int[] a ={1,5,7,1,3,3,5,4,8,10};
shellSort2(a);
System.out.println(Arrays.toString(a));
}
public static int[] shellSort2(int[] a ) {
int temp,j;
for(int gap = a.length/2; gap>0; gap = gap/2){
//里面嵌套了一个插入排序
for(int i = gap;i<a.length;i++){
temp = a[i];
for( j = i; j >=gap&&temp<a[j-gap]; j-=gap){
a[j] = a[j-gap];
}
a[j] = temp;
}
}
return a;
}
}
5 快速排序
首先取一个pivot 值 ,让小的在pivot左边,大的在右边。重新生成一个Pivot一直递归到结束。
这里利用了首先递归,其次填坑的方法来进行。
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] a = {1,5,6,1,2,5,7,8,36,16,2,15,61,1};
quickSort(a,0,a.length-1);
System.out.println(Arrays.toString(a));
}
//负责快排的填坑部分。
public static int get_mid(int[] a, int low,int high){
int pivot = a[low];
while(low<high){
while(low<high && pivot<= a[high]) high--;
a[low] = a[high];
while(low <high && pivot >=a[low]) low++;
a[high] = a[low];
}
a[low] = pivot;
return low;
}
//负责快排递归的部分,
public static void quickSort(int[] a,int low,int high){
if(low<high) {
int mid = get_mid(a, low, high);
quickSort(a, low, mid - 1);
quickSort(a, mid+1, high);
}
}
}
6 归并排序
import java.util.Arrays;
//java 与 python 关于对象的排序都是利用 归并排序的。快排是不稳定的,
//对象一般要求稳定,
public class MergeSort {
//堆排序的算法 主要merget 进行融合,我们通过对两个已经排序的序列进行一次融合
//后续会用到多次融合,
//归并排序的时间复杂度,
public static void main(String[] args) {
int[] a = {1,5,6,1,2,5,7,8,36,16,2,15,61,1};
sort(a,0,a.length-1);
System.out.println(Arrays.toString(a));
}
//指针的问题,我们可以通过将指针加入相应的操作中,来进行分析。a
// 递归的一个过程 通过不但的拆分,拆分成最小的个体,
static void sort(int[] a, int left, int right){
if(left ==right)return ;
int mid = left +(right-left)/2;
sort(a,left,mid);
sort(a,mid+1,right);
merget(a,left,mid+1,right);
}
//merget实现融合的一个过程,通过建立左右指针以及右边的边界进行定义。
static void merget(int[] a,int left,int right, int rightbound){
int[] temp = new int[rightbound-left+1];
int mid = right-1;
int i= left;
int j= right;
int k = 0;
while(i<=mid && j<=rightbound){
if(a[i]<=a[j]){ temp[k++] = a[i++];}
else{temp[k++] = a[j++];}
}
while(i<=mid){temp[k++]=a[i++];}
while(j<=rightbound)temp[k++]=a[j++];
for(int m =0; m<temp.length;m++) a[left+m] = temp[m];
}
}
7 计数排序
非比较排序,是桶排序的思想,通过计数出现的个数,创立新的数组其下表代表带排序的元素值,通过对新数组的计数,来重现原数组的排序
import java.util.Arrays;
public class CountSort {
//技术排序的主要思想是新建一个跟原数组等长的一个数组。以及新建一个跟原数组的复制范围的一个数组,通过将原数组的
//值作为索引进行计数,计数完毕之后将计数完成的数组放到新的数组当中去。
public static void main(String[] args) {
int[] a={0,1,7,5,3,8,9,6,1,3,5,4,6,7,8,3,6,7,5,6};
int[] ints = countSort(a);
System.out.println(Arrays.toString(ints));
}
public static int[] countSort(int[] a){
int[] result= new int[a.length];
int[] count = new int[10];
int k=0; ;
for(int i = 0;i<a.length;i++){
count[a[i]]++;
}
for(int j = 0;j<10;j++){
while (count[j]-- >0) result[k++] = j;
}
return result;
}
}
后面还剩,桶排序、基数排序、以及堆排。待更...
排序算法以上是手撕的常用的排序的算法,十大排序算法。真正要了解算法,面向面试对象依旧需要不断的进行算法题的练习。
剑指offer:两遍;
Leetcode: 常见的200题待刷;
往后每日更新至少3道算法题目,以及相应的解析。
往下在12.14号结束之前,jvm的更新补全。
接下来,java基础的更新,涉及常用的类的方法,以及面向对象、并发编程、IO、集合、异常、反射。