冒泡排序:属于稳定排序。
基本思想:(从后往前排:先确定最后一个记录,在依次往前确定记录)
比较相邻两个记录,如第一个比第二个大,就交换两个记录,在依次比较第二个和第三个,对每一对记录做同样的操作,从第一对到最后一对。第一次遍历数组就将最大的记录放在最后,在依次重复执行上面的操作,除了最后一个记录,每次操作都比上一次少一个记录。
public class BubbleSort{
public static void main(String[] args){
int[] arr = {9,12,36,5,42,90};
for(int i = 0; i < arr.length - 1; i++){
for(int j = 0;j <arr.length -i-1;j++){
if(arr[j] > arr[j + 1]){
int k=arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = k;
}
}
}
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
时间复杂度: 若文件是初始状态是正序的,一次扫描就可以完成排序,比较次数和移动次数最小。比较次数为C =n-1,记录移动的次数M =0。所以冒泡排序最好的时间复杂度为:O(n)。若文件的初始状态是反序的,需要进行n-1次排序,每次需要进行n-i此比较(1<= i <=n-1),每次比较需要移动三次来达到交换位置,所以比较次数和移动次数最大。比较次数为C =n(n-1)/2,记录移动次数M =3n(n-1)/2。所以冒泡排序最坏的时间复杂度为:O(n^2)。
冒泡排序的平均时间复杂度为:O(n^2)。 空间复杂度为:O(1)。
插入排序:属于稳定排序。(直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序))
直接插入排序:
基本思想:对于给定的一组记录,把第一个记录看做有序序列,其余的看做无序序列,从第二个记录开始,按照记录大小依次将其插入到之前的有序序列中。
public class InsertionSort{
public static void main(String[] args){
int[] arr = {9,12,36,5,42,90};
for(int i = 0; i < arr.length ; i++){
for(int j = i;j > 0 ;j--){
if(arr[j] < arr[j - 1]){
int m=arr[j];
arr[j] = arr[j-1];
arr[j-1] = m;
}else{
break;
}
}
}
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
时间复杂度:若文件的初始状态是正序,所需的比较次数和移动次数最小,比较次数为C =n-1,记录移动次数M =0。所以
插入排序最好的时间复杂度为:O(n)。若文件的初始状态是反序,所需的比较次数和移动次数最大,比较的次数为C =(n+2)(n+1)/2,
记录移动次数M =(n+4)(n-1)/2。所以插入排序最坏的时间复杂度为:O(n^2)。
插入排序的平均时间复杂度为:O(n^2)。空间复杂度为:O(1)。
选择排序:属于不稳地排序 (简单选择排序,树形选择排序,堆排序)
简单选择排序:
基本思想:第一次,在待排序记录a[0]~a[n]中选择出最小的记录,将其和a[0]交换;第二次,在待排序记录a[1]~a[n]中选择出最小的记录,将其和a[1]交换;以此类推,重复上面操作。
public class SelectionSort{
public static void main(String[] args){
int[] arr = {9,12,36,5,42,90};
for(int i = 0; i < arr.length - 1; i++){
int min = i;
for(int j = i + 1;j <arr.length ;j++){
if(arr[j] < arr[min]){
min = j;
}
}
if(min != i){
int m=arr[i];
arr[i] = arr[min];
arr[min] = m;
}
}
}
时间复杂度:若文件的初始状态是正序,所需比较次数为C =n(n-1)/2,记录移动次数为:M =0,简单选择排序最好的时间复杂度为:O(n^2)。若文件的初始状态是反序,所需的比较次数为:C =n(n-1)/2,记录移动次数为:M =3(n-1),简单选择排序最坏的时间复杂度为:O(n^2)。
简单选择排序的平均时间复杂度为:O(n^2)。空间复杂度为:O(1)。
快速排序:属于不稳定排序 (冒泡排序的一种改进)
基本思想:首先选取一个记录(通常选数组第一个记录),通过一次排序将待排记录分为两部分,将比它小的记录放在它前面,将比它大的记录放在它后面。在分别对两部分记录进行上面方法的排序,直到整个序列有序。
public class QuickSort{
public static void main(String[] args){
int[] arr = {7,6,1,9,5,3,8,11,23,12,0,4,2,10};
quicksort(arr,0,arr.length - 1);
printarr(arr);
}
public static void quicksort(int[] arr,int left, int right){
int dp;
if(left < right){
dp = partition(arr,left,right);
quicksort(arr,left,dp - 1);
quicksort(arr,dp + 1,right);
}
}
public static int partition(int[] arr,int left, int right){
int pivot = arr[left];
while(left < right){
while(left < right && arr[right] >= pivot){
right--;
}
if(left < right){
arr[left] = arr[right];
left++;
}
while(left < right && arr[left] <= pivot){
left++;
}
if(left < right){
arr[right] = arr[left];
right--;
}
}
arr[left] = pivot;
return left;
}
public static void printarr(int[] arr){
for(int i = 0;i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
时间复杂度:快速排序涉及递归调用,所以该算法的时间复杂度还和递归调用的时间复杂度有关,快速排序最好的时间复杂度为:O(nlogn)。快速排序最坏的时间复杂度为:O(n^2)。
快速排序的平均时间复杂度为:O(nlogn)。空间复杂度为:O(nlogn)。