咋们今天来聊一聊比较常见的排序,选择,冒泡,计数,插入
选择排序
核心思想:当前元素和之后所有元素进行比较,如果当前大于后者,则进行交换
咋们来一个动图,就可以更加直观的了解了
算法步骤 :
1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3.重复第二步,直到所有元素均排序完毕。
代码演示:
class 排序{
public static void mian(String[] args){
int[] S=new int[10];
for(int i=0;i<S.length-1;i++){
for(int j=i+1;j<S.length;j++){
if(S[i]>S[j]){
int temp = S[i];
S[i]=S[j];
S[j]=temp;
}
}
}
show(S);
}
public static void show(int[] S){
String s="[";
for(int i=0;i<S.length;i++){
if(i==S.length-1){
s+=S[i]+"]";
}else{
s+=S[i]+",";
}
}
System.out.println(s);
}
}
冒泡排序
对于冒泡排序,我想大家想必不陌生,他是两两进行比较,大的一直往下沉(这里默认的情况是从小到大)
图解
算法 步骤:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码演示
class 冒泡{
public static void main(String[] args){
bubbleSort();
}
public static void bubbleSort(){
int[] arr={8,5,9,2,7,4,6,1,3};
for(int i=0;i<arr.length-1;i++){//-1是少一轮比较
for(int j=0;j<arr.length-1-i;j++){//-1避免重复比较和角标越界
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
show(arr);
}
public static void show(int[] arr){
//[1,2,3,4,5,6,7,8,9]
String s="[";
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
插入排序
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法步骤:
1.将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
2.从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
代码演示:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array={12,73,45,69,35};
int i,j,temp;
for(i=1;i<array.length;i++) {
/*
* 第一个for循环
* 把数组分成两部分,右边为未排序,左边为已排序
* 记录排序与未排序分割点temp(temp为下一个排序对象)
*/
temp=array[i];
for(j=i-1;j>=0;j--) {
/*
* 第二个for循环
* 将排序对象temp与已排序数组比较
* 当temp比最近左边的数大时(按从小到大循序排列时)
* 直接结束本次循环,进行下一个数排序
* 否则比左边这个数小时将这个数后移,腾出这个数的位置
*/
if (temp > array[j]) {
break;
}else{
array[j+1] = array[j];
}
}
array[j+1]=temp;
}
System.out.println(Arrays.toString(array));
}
}
计数排序
先找出最大值最小值,之后统计每个数出现的次数,根据次数从小到大往数组里添加。它适用于当前数组密集的情况。
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
算法步骤:
1.找出待排序的数组中最大和最小的元素;
2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
4.反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1.
代码演练
//计数排序
public static void CountSort(int *a, int size){
int max = a[0];
int min = a[0];
for (int i = 0; i < size; ++i)
{
if (a[i] > max)
max = a[i];
if (a[i] < min)
min = a[i];
}
int range = max - min + 1; //要开辟的数组范围
int *count = new int[range];
memset(count, 0, sizeof(int) * range); //初始化为0
//统计每个数出现的次数
for (int i = 0; i < size; ++i) //从原数组中取数,原数组个数为size
{
count[a[i] - min]++;
}
//写回到原数组
int index = 0;
for (int i = 0; i < range; ++i) //从开辟的数组中读取,开辟的数组大小为range
{
while (count[i]--)
{
a[index++] = i + min;
}
}
delete[] count;
}
排序还有好多,另外再见