目录
1:冒泡排序
思想:对于n个元素的数组,第一趟需要比较的数列为n-1,第二趟为n-2……每一趟结束后,前序列有序,后序列无序,当总序列有序后,停止比较。是一种交换排序,需要用1个临时存储空间,因此空间复杂度为O(n)=1,时间复杂度为T(n)=n²。
比如当有6个元素时,需要排序5趟,第1趟比较5次,第2躺比较4次,第3躺比较3次……
比较的次数(j)和趟数(i)满足i+j=n,因此趟数(j)=n-i;
Java代码如下:
public class BubbleSort {
public static void main(String[] args) {
int[] nums = {7,4,3,2,6,8};
int temp = 0;
boolean flag = true
//比较n-1躺
for (int i = 0; i <= nums.length - 1&&flag; i++) {
flag = false;
//比较n-1-i次
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
temp = nums[j + 1];
nums[j + 1] = nums[j];
nums[j] = temp;
flag = true;
}
}
}
//测试
for (int k = 0; k < nums.length; k++) {
System.out.print(nums[k]);
}
}
}
Kotlin代码如下:
fun main() {
var arr = intArrayOf(1,5,8,2,4,3)
arr = bulletSort(arr)
for (i in arr) {
println(i)
}
}
//冒泡排序
fun bulletSort(arr:IntArray):IntArray{
//外层循环控制比较次数,内层循环控制交换次数,比如有6个数的数组,需要交换5次,
// 第1次,要比较5次,第2次,要比较4次,交换次数i和比较次数j满足i+j=n
var temp: Int
var flag = false
for (i in arr.indices) {
for(j in 0 until arr.size-i-1){
if(arr[j]>arr[j+1]){
temp = arr[j+1]
arr[j+1] = arr[j]
arr[j] = temp
flag = true
}
}
if(!flag) break
}
return arr
}
2:直接插入排序
思想:对于一个包含n个元素的数列,取其一作为哨兵,哨兵前的数列保持有序,哨兵后的序列依次后移,当哨兵后序列无移动时,结束比较。需要用到1个临时存储单元,因此空间复杂度O(n)=1,时间复杂度T(n)=n²。
除此还有折半插入:思想为:将直接插入排序的哨兵前序列,取中和哨兵比较,大的放到哨兵后,小的放到哨兵前,直接数列有序。
希尔排序:也是一种插入排序算法,思想为,将一个包含n个数的数列,按步频,划分为多个数列,比如直接插入和折半插入的步频都为1,而希尔排序的核心在于扩大步频,从而减少移动的次数,但如何找到最合适的步频,尚未解决。
Java代码如下:
public class InsertSort {
public static void main(String []args) {
int[] nums = {5,3,2,4,7,6};
//代插入的数,哨兵
int x = 0;
//待排序次数i
int i = 0;
//比较次数j
int j = 0;
//待排序的数字从第二个开始
for(i = 1;i<nums.length; i++){
//哨兵给第二个数
x = nums[i];
//如果代排序的数比有序数都小,有序数末尾需要后移
for(j = i-1;j>=0&&x<nums[j];j--){
nums[j+1] = nums[j];
}
//移动结束后,哨兵给j+1
nums[j+1] = x;
}
for(int k= 0 ;k<nums.length;k++){
System.out.print(nums[k]);
}
}
}
Kotlin代码如下:
fun main() {
var arr = intArrayOf(1,5,8,2,4,3)
arr = insertSort(arr)
for (i in arr) {
println(i)
}
}
//插入排序
fun insertSort(array: IntArray) :IntArray {
var x:Int
for(i in 1 until array.size){
//哨兵给第二个数
x = array[i]
//代排序的数列
for(j in i-1 downTo 0){
//整体后移
array[j+1] = array[j]
//每一个数都比x小,哨兵给j+1
if(array[j]<x){
array[j+1] = x
break
}
}
}
return array
}
3:快速排序
思想:也叫快排算法,是一种交换排序,核心思想在于,找到pivot,运用递归思想,进行分组比较,交换数列。时间复杂度T(n)=nlogn,因为涉及递归,栈存储,因此, 空间复杂度为O(n)=nlogn,是不稳定排序。当数列越乱时,排序效率越高,当数列有序后,退化为冒泡排序。
Java代码如下:
public class QuickSort {
public static void main(String[] args) {
int[] arr = {49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
quicksort(arr,0,arr.length-1);
for(int item:arr){
System.out.printf(item+",");
}
}
private static void quicksort(int[] a,int low,int high){
//先取一个基准数
//定义 两个指针high,low
//使用递归 持续 1过程和2过程
//1过程:从队尾开始,如果末尾值<base,把a[low] = a[high],如果末位置>=base,high--;
//2过程:从队头开始,如果队头值<=base,low++,如果队头值>base,把a[high] = a[low];
//当low>=high是,结束上述过程
if(low<high){
int base = getBaseNum(a,low,high);
quicksort(a,0,base-1);
quicksort(a,base+1,high);
}
}
private static int getBaseNum(int[] a,int low,int high){
int temp = a[low];
while(low<high){
while (low < high && a[high]>=temp)
high--;
a[low] = a[high];
while (low < high && a[low]<=temp)
low++;
a[high] = a[low];
}
//循环结束,low的值不等于temp;需要把temp给low
a[low] = temp;
return low;
}
Kotlin代码如下:
fun main() {
var arr = intArrayOf(1,5,8,2,4,3)
arr = quickSort(arr,0,arr.size-1)
for (i in arr) {
println(i)
}
}
//快速排序
fun quickSort(arr:IntArray,low:Int,high:Int):IntArray{
//快排的思想在于交换排序,递归,povit点的获取
if(low<high) {
val povit:Int = getBaseNum(arr, low, high)
quickSort(arr,0,povit-1)
quickSort(arr,povit+1,high)
}
return arr
}
fun getBaseNum(arr: IntArray, low: Int, high: Int): Int {
var l = low
var h = high
val temp = arr[l]
while (l<h){
while (l<h&&arr[h]>=temp)
h--
arr[l] = arr[h]
while (l<h&&temp>=arr[l])
l++
arr[h] = arr[l]
}
arr[l] = temp
return l
}