Java学习笔记 - 排序
选择排序
选择排序(Selection sort)是一种简单直观的排序算法,它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的元素,将它与序列的第一个元素交换,然后再从剩余的未排序元素中寻找到最小(大)元素,然后与为排序的数列中的第一个元素进行交换。以此类推,直到全部待排序的数据元素的个数为零。
选择排序是不稳定的排序方法。
选择排序的稳定性即,假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
步骤(降序):
1.先找到第一大(小)的值,与数列第一个元素交换。
2.在未排序的数列中继续找最大值,与未排序数列的第一个元素交换。
3.重复上述步骤,最后所有元素排序完成。
class Test01{
public static void main(String[] args){
int[] a = {7, 3, 2, 5, 1, 4, 6, 8};//无序数组
int max = 0;//标记,,每次查找到的最大值的下标
for(int i = 0; i < a.length - 1; i++){
max = i;//默认最大值为未排序数列的第一个元素,然后开始查找
for(int j = i + 1; j < a.length; j++){
if(a[max] < a[j]) max = j;//标记真正的最大值的数组的下标
}
if(max != i){//判断未排序数列的第一个是否是最大值,是则不必交换数值
a[max] += a[i];
a[i] = a[max] - a[i];
a[max] = a[max] - a[i];
}
System.out.print(a[i] + " ");//打印排好序的数列的前7个元素
}
System.out.print(a[7]);//打印排好序的数列的最后1个元素
}
}
冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的比较简单排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
冒泡排序是稳定的排序算法。
步骤(降序):
1.比较无序数列的第一个元素和第二个元素,如果第一个元素小于第二个元素,那么交换这两个元素的值;如果第一个元素大于第二个元素,则不交换。
2.一直比较,直到最小的值被交换到数列的末尾。然后一个数据排好,对剩下的数据排序。
3.重复上述步骤,直到所有元素有序。
代码:
class Test02{
public static void main(String[] args){
int[] a = {7, 3, 2, 5, 1, 4, 6, 8};//无序数列
for(int i = 0; i < a.length - 1; i++){
for(int j = 1; j < a.length - i; j++){
if(a[j-1] < a[j]){//比较相邻的两个元素,小的放在后面,大的放在前面
a[j - 1] += a[j];
a[j] = a[j - 1] - a[j];
a[j - 1] = a[j - 1] - a[j];
}
}
}
}
}
计数排序
计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如归并排序,堆排序)
步骤:
1.对一定范围的数据,建立一个长度合适的数组。数组的默认值为0。
2.遍历无序数列,将无数数列中元素对应的数组的值置为1。例如:遍历到2时,就将数组中的[2]号元素置为1 。
3.当遍历完无序数列,根据数组的值来输出排好序的数列,即数组中值为一时,输出该元素的下标。
代码:
class Test03{
public static void main(String[] args){
int[] a = {11,2,6,5,8,7,4,1,3,6}, b = new int[12];//无序数列和空数组
for(int i = 0; i < a.length; i++){
b[a[i]] = 1;//对应的数组元素的值置为1
}
for(int i = 0; i < a.length; i++){
if(b[i] == 1) System.out.print(i + " ");//输出排序后的数组
}
}
}
插入排序
插入排序(Insertion sort)是一种简单直观且稳定的排序算法。如果有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法。算法适用于少量数据的排序,时间复杂度O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
步骤:
1.从第二个元素开始查找,判断该元素的而左边是否有数字,有则比较大小,根据结果判断是否需要将前面的数值后移,直到左边无数据,或者左边的数值小于它,那么将另外存储的数值存入数列空出的位置中。
2.然后从第三个元素查找
3.重复以上步骤,直到数列全部有序。
代码:
class Test03{
public static void main(String[] args){
int[] arr={8,5,9,2,7,4,6,1,3};
int e;
int j;
for(int i=1;i<arr.length;i++){
e=arr[i];//存储被占位的元素的数值
for(j=i;j>0&&arr[j-1]>e;j--){//比较当前元素及左边的元素,当查找到小于储存的数据时,结束
arr[j]=arr[j-1];
}
arr[j]=e;//将存储的数据存入空出来的数列位置中
}
}
}