冒泡排序
思路:每一次循环将最大值 / / / 最小值放于向后移动。
public static int[] sort(int[] a){
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
int temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
return a;
}
插入排序
思路:第 i i i 趟,把第 i i i 个元素放到前 i − 1 i - 1 i−1 个有序的序列中 。
public static int[] InsertSort(int[] a){
for(int i=1;i<a.length;i++){
int temp = a[i];//处理第i个元素
int j = i-1;
for(;j>=0 && a[j]>temp;j--){
a[j+1] = a[j];//大的元素往后移
}
a[j+1] = temp;
}
return a;
}
选择排序
思路:第 i i i 趟把从 i i ~ i 结尾最小的元素找到,放到 i i i 位置。
public static int[] SelectedSort(int[] a){
for(int i=0;i<a.length;i++){
int min = i;//存放i+1到最后最小的元素所在的下标
for(int j=i+1;j<a.length;j++){
if(a[j]<a[min])
min = j;
}
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
return a;
}
希尔排序
思路:将排序的区间分成若干个有跨度的子区间,对每一个子区间,进行插入排序,跨度不断 / 2 / 2 /2 ,最终当跨度为 1 1 1 的时候,进行一个插入排序。
public static int[] shell(int[] a){
for(int gap = a.length/2;gap>0;gap/=2){
//对每一分组进行直接插入排序
for(int i=gap;i<a.length;i++){
int j = i;
while(j-gap>=0 && a[j-gap]>a[j]){//大的往后移动
int temp = a[j];
a[j] = a[j-gap];
a[j-gap] = temp;
j = j-gap;//下一次继续从分组的前一个位置开始
}
}
}
return a;
}
计数排序
思路:找出数组中的最大值和最小值,每个数都是在 m i n min min 和 m a x max max 之间,用一个长度为( m a x − m i n + 1 max - min + 1 max−min+1)的数组 c c c 来存储每一个数出现的次数,然后将数组 c c c 转换为前缀和数组,则 c [ i ] c[ i ] c[i],就表示不大于( i + m i n i+min i+min)的元素的个数,按照 c c c 数组还原排序结果。
public static void countSort(int[] a){
int[] b = new int[a.length];
int max = a[0];min = a[0];
for(int i=0;i<a.length;i++){
if(a[i]>max) max = a[i];
if(a[i]<min) min = a[i];
}
int dis = max - min + ;
int[] c = new int[dis];
for(int i=0;i<a.length;i++)
c[a[i]-min]++;
for(int i=1;i<c.length;i++)
c[i] = c[i] + c[i-1];
for(int i=a.length-1;i>=0;i--){
b[c[a[i]-min]-1] = a[i];
c[a[i]-min]--;
}
System.out.println(Arrays.toString(b));
}
归并排序
思路:先把数组从中间分成前后两部分,然后分别对前后两部分进行排序,再将排好序的两部分数据合并在一起
public static void mergeSort(int[] a,int left,int right){//待排序数组,要排序的范围[left,right]
int mid = (left+right)>>1;
if(left<right){
mergeSort(a,left,mid);
mergeSort(a,mid+1,right);
merge(a,left,mid,right);
}
}
public static void merge(int[] a,int left,int mid,int right){
int[] temp = new int[right-left+1];//临时数组,用来归并
int i=left,j=mid+1,k=0;//左半段用i指向,右半段用j指向,temp数组用k指向
while(i<=mid && j<=right){
if(a[i]<a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i<=mid) temp[k++] = a[i++];
while(j<=right) temp[k++] = a[j++];
for(int x=0;x<temp.length;x++){
a[left+x] = temp[x];
}
}
快速排序
思路:
1.首先设定一个分界值,通过该分界值将数组分成左右两部分。
2.将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。
3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
public static void quickSort(int[] a,int left,int right){
if(left>right) return;//区间擦肩而过,无效,不需要进行递归
int i=left,j=right,temp = a[left];//a[left]作为基准点
while(i!=j){
while(a[j]>=a[temp] && j>i)
j--;//只要a[j]大于基准点继续往前移动j
if(j>i)
a[i++] = a[j];
while(a[i]<=a[temp] && i<j)
i++;
if(i<j)
a[j--] = a[i];
}
a[i] = temp;//基准点元素放到最终位置
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}