常用排序方法
1.冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误
就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二
氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
冒泡排序算法的原理如下:
\1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
\2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的
数。
\3. 针对所有的元素重复以上的步骤,除了最后一个。
\4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public class BubbleSort {
public static void main(String[] args) {
int[] array={5,3,7,2,9,4};
int temp=0;
for (int i=0;i<array.length-1;i++){ //外层循环决定走几趟
int flag=0;
for (int j=0;j<array.length-1;j++){ //内层循环是具体的比较逻辑
if(array[j+1]>array[j]){
temp=array[j+1];
array[j+1]=array[j];
array[j]=temp;
flag=1;
}
}
if (flag==0){
break; //当所有数按顺序排列时,循环中断
}
}
for (int i : array) {
System.out.println(i);
}
}
}
2.选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小 (或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
public class SelectSort {
public static void main(String[] args) {
int[] array={5,3,7,2,9,4,76,45,64,102,41};
int temp=0;
for (int i=0;i<array.length-1;i++){
int minIndex=i;
for (int j=i+1;j<array.length;j++){
if (array[minIndex]>array[j]){
minIndex=j;
}
}
if (i!=minIndex){
temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
for (int i : array) {
System.out.println(i);
}
}
}
3.插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这
个时候就要用到一种新的排序方法——插入排序法,
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算
法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部
分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含
这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直
到全部插入完为止。
包括:直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。属于
稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置) 。
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: ⒈ 从第一个元素开始,该元素可以认为已
经被排序 ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描 ⒊ 如果该元素(已排序)大于新元素,将该元
素移到下一位置 ⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 ⒌ 将新元素插入到下一位置中 ⒍
重复步骤2~5
如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的
一个变种,称为二分查找排序。
public class InsertSort {
public static void main(String[] args) {
int[] array={5,3,7,2,9,4};
int temp=0;
for (int i=1;i<array.length;i++){
for (int j=i;j>0;j--){
if(array[j]<array[j-1]){
temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
}
else{
break;}
}
}
for (int i : array) {
System.out.println(i);
}
}
}
4.快速排序
在待排序的n个元素序列中,任意选取一个元素(通常选第一个)作为基准,然后从右边开始选取比较,直到选取的元素比基准元素小,并交换位置,然后从左边开始选取比较,直到选取的元素比基准元素大,并交换位置。完成一轮后,从基准划分为高低两部分序列,从低序列开始与第一轮一样,循环完成排序,再对高序列完成排序,从而确定序列顺序。
public class QuickSort1 {
public static void main(String[] args) {
int []arr= {3,6,2,8,6,35,77,21,1,89};
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr, int left, int right) {
//进行判断,如果左边索引比右边索引大,是不合法的,直接使用return结束这个方法
if(left>right)
{
return;
}
//定义变量保存基准数
int base=arr[left];
//定义变量i,指向最左边
int i=left;
//定义变量j,指向最右边
int j=right;
//当i和j不相遇的时候,在循环中进行检索
while(i!=j)
{
//向由j从右往左检索比基准数小的,如果检索到比基准数小的就停下
//如果检索到比基准数大的或者相等的,就继续检索
while(arr[j]>=base && i<j)
{
j--; //j从右边往左移动
}
while(arr[i]<=base&&i<j)
{
i++; //i从左往右移动
}
//代码走到这里,i停下了,j也停下了。然后交换i和j位置的元素
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//如果上面while循环的条件不成立,会跳出这个循环,往下执行
//如果这个条件不成立说明i和j相遇了
//如果i和J相遇了,就交换基准数这个元素和相遇位置的元素
//把相遇位置的元素赋值给基准数这个位置的元素
arr[left]=arr[i];
//把基准数赋值给相遇位置的元素
arr[i]=base;
//基准数在这里就归为了,左边的数字都比他小,右边的都比他大
//排基准数的左边
quickSort(arr, left, i-1);
//排右边
quickSort(arr, j+1, right);
}
}
把基准数赋值给相遇位置的元素
arr[i]=base;
//基准数在这里就归为了,左边的数字都比他小,右边的都比他大
//排基准数的左边
quickSort(arr, left, i-1);
//排右边
quickSort(arr, j+1, right);
}
}