排序算法(1)——冒泡、插入、选择

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012292754/article/details/83758439

1 概念性介绍

  • 原地排序(Sorted in place),就是特指空间复杂度是 O(1) 的排序算法。
  • 排序算法的稳定性:待排序的序列中存在值相等的元素,经过排序后,相等元素之间的原有先后顺序不变;
排序算法 时间复杂度 是否基于比较
冒泡、插入、选择 O(n^2)
快排、归并 O(nlogn)
桶、计数、基数 O(n)

2 冒泡排序

冒泡排序的优势是可以检测输入序列是否已经是有序的。

// 复杂度 O(n^2)

void BubbleSort(int A[],int n){ // n 表示数据大小
	for(int pass = n-1; pass >= 0; pass--) {
		for(int i=0; i < pass; i++) {
			if(A[i] > A[i+1]) {
				int temp = A[i];
				A[i] = A[j];
				A[i+1] = temp;
			}
		}
	}
}

2.1 改进冒泡排序

排序中没有交换意味着排序完成

 public static void BubbleSortImproved(int A[], int n) {
        int pass, i, temp;
        boolean swapped = true;
        for (pass = n - 1; pass >= 0 && swapped; pass--) {
            swapped = false;
            for (i = 0; i < pass; i++) {
                if (A[i] > A[i + 1]) {
                    temp = A[i];
                    A[i] = A[i+1];
                    A[i+1] = temp;
                    swapped = true;
                }
            }
        }
    }
public static void BubbleSortImproved(int A[], int n) {
        boolean flag = false;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n - 1 - i; j++) {
                if (A[j] > A[j + 1]) {
                    int temp = A[j];
                    A[j] = A[j + 1];
                    A[j + 1] = temp;
                    flag = true;
                }
            }

            if (!flag) break;

        }
    }

3 插入排序

将数组中的数据分为两个区间,已排序区间和未排序区间。初始的已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序的区间中的元素,在已经排序的区间中找到合适的位置插入,保证已排序的序列一直有序。重复这个过程,直到这个未排序的区间中的元素为空。

 public static void insertSort(int a[], int n) {
        if (n <= 1) return;
        for (int i = 1; i < n; i++) {
            int value = a[i];
            int j = i - 1;
            //查找插入的位置
            for (; j >= 0; j--) {
                if (a[j] > value) {
                    a[j + 1] = a[j]; //数据移动
                } else {
                    break;
                }
            }

            a[j + 1] = value; //插入数据
        }
    }
public static void insertSort(int a[], int n) {
        int i, j, v;
        for (i = 1; i < n; i++) {
            v = a[i];
            j = i - 1;
            while (j >= 0) {
                if( a[j] > v){
                    a[j+1] = a[j];
                    --j;
                }
                else break;
            }
            a[j+1] = v;
        }
    }

3.1 冒泡排序和插入排序的比较

冒泡和插入的时间复杂度都是 O(n^2), 为何插入比冒泡更受欢迎呢?
冒泡排序不管怎么优化,元素的交换次数是一个固定值,是原始数据的逆序度;同样插入排序也是原始数据的逆序度。但是从代码上看,冒泡的数据交换比插入的数据移动复杂,冒泡需要3个赋值操作,插入只需要一个。

3.2 希尔排序(插入排序的优化)

4 选择排序

选择排序和插入排序有些类似,也分为已排序区间和未排序区间。但是选择排序每次会从未排序的区间中找到最小元素,将其放到已排序区间的末尾。

public static void Selection(int A[], int n) {
        int i, j, min, temp;
        for (i = 0; i < n - 1; i++) {
            min = i;
            for (j = i+1; j < n; j++) {
                if (A[j] < A[min]){
                    min = j;
                }
            }

            temp = A[min];
            A[min] = A[i];
            A[i] = temp;

        }
    }

5 总结

是否原地排序 是否稳定 最好 最坏 平均
冒泡 O(n) O(n^2) O(n^2)
插入 O(n) O(n^2) O(n^2)
选择 O(n^2) O(n^2) O(n^2)

猜你喜欢

转载自blog.csdn.net/u012292754/article/details/83758439