1. 程式人生 > >時間複雜度,插入排序,氣泡排序,選擇排序

時間複雜度,插入排序,氣泡排序,選擇排序

理解時間複雜度,插入排序,氣泡排序,選擇排序

什麼是時間複雜度

就是近似於約等於演算法總的執行的次數;
說白了時間複雜度就是近似約等於演算法中常數操作的次數;
時間複雜度使用O(n)(可以讀big O n)來表示
在一個演算法之中,演算法常數操作次數 * 每個數的常數操作的時間 = 演算法總執行的時間;

什麼是常數操作

一個樣本執行和數量沒有關係,每次都是固定時間完成,叫做常數操作。
比如兩個數加減乘除賦值的操作;比如
int i =好幾億;//固定時間完成
上面這樣說可能還是有點不清楚,通過一個例子詳細介紹一下;
比如我現在要列印一個連結串列上面的所有資料,假設連結串列的資料是下面這樣排列
(資料不是下面這樣有規律的排列,這裡只是為了看資料方便)

i 0 1 2 3 4 5
value -190 0 39 56 89 900

假設從連結串列中拿出一個數需要花t1秒,迭代一下需要花t2秒;那麼列印這個連結串列所有資料總共需要多長時間呢?
這個連結串列上面有N個數據,現在我們來總結一下,從N個數據中取一個數總共所需要的時間是多少?
i == 0,需要用時間 (t1+t2)* 1
i == 1,需要用時間 (t1+t2)* 2
i == 2,需要用時間 (t1+t2)* 3
i == 3,需要用時間 (t1+t2)* 4



i == N-1,需要用時間 (t1+t2)* N
所以,列印N個數的連結串列需要用總時間 : (N*(N+1)/2) * (t1+t2),其中 t1+t2 可以理解為操作一個數所用的平均時間(常數操作時間

),使用函式可以這樣表示f(n)=(n^2+n)/2* t‘;
f(n)可以表示演算法總的執行時間;
時間複雜度我們使用T(n)來表示;
這個時候就有 T(n) = O(f(n)),其中f(n)中我們只要高階項,不要低階項,不要高階項的係數,最後f(n) = n^2 ,
所以T(n) = O( n^2 ), 所以當n無窮大的時候,這個
n ^ 2 約等於(n^2+n)/2* t’,所以我們可以一般使用程式執行的常數時間次數來作為時間複雜度的指標;某種意義上來說,它也近似反映了程式的執行時間;
再來看看教科書裡面的定義;

若有某個輔助函式f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函式,記作T(n)=O(f(n)),它稱為演算法的漸進時間複雜度,簡稱時間複雜度。
以上就是我對時間複雜度的再次理解認識;

三種O(N^2)時間複雜度的排序演算法;

選擇排序

大體思想是這樣的:
從所有資料中選擇數值最大的數,記住下標,和第一個位置的資料進行交換,這樣第一個位置排好了順序;
然後在從剩下的資料中選擇數值最大的數,記住下標,和剩下的資料中的第一個位置交換,這樣剩下的資料中第一個位置也排好了順序…依次這樣迴圈執行到所有資料都排好了順序;
轉化成圖表示如下:
在這裡插入圖片描述
使用程式碼完成想選擇排序的過程:java實現

	//選擇排序的實現
	private static void selectSort(int[] arr) {

		for (int i = 0; i < arr.length; i++) {//從0 ~ arr.length-1中選擇出最大值的下標,和位置交換資料
			int index = i;//index用來記住最大值的下標,然後和i位置交換
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[index] < arr[j]) {
					index = j;
				}
			}
			//交換兩個位置資料的方法
			Utils.swap(arr, index, i);
		}

	}
氣泡排序

大體思想是這樣的:
從第一個位置數和下一個位置數進行兩兩比較,如果比下一個位置數大,就交換,否則就保持順序不變,
再比較後面的兩個資料,如果比下一個位置數大,就交換,否則就保持順序不變,

按照上面的規則一直往下去執行,直到所有的資料都排好位置;
這個過程就像氣泡一點一點往上浮起來一樣;
轉化成圖表示如下:
在這裡插入圖片描述
使用程式碼實現如下:java實現

	// 氣泡排序的實現
	public static void bubbleSort(int[] arr) {

		for (int i = arr.length - 1; i >= 0; i--) {

			for (int j = 0; j < i; j++) {// 冒泡 0 ~ i之間像氣泡一樣往上浮,排好了之後i會往下減
				// 前面的數大,就交換
				if (arr[j] > arr[j + 1]) {
					Utils.swap(arr, j, j + 1);
				}
			}
		}
	}

插入排序

大體思想
就是往已經排好序的資料中,插入一個數據,使得資料重新排列好.
使用圖形來表示:
在這裡插入圖片描述

使用程式碼來實現這個過程:java程式碼實現

	// 插入排序實現
	public static void insertSort(int[] arr) {

		for (int i = 0; i < arr.length; i++) {

			// 0~1 , 0~2 ,... , 0 ~ (arr.length-1)
			// 條件是j越界了嗎?&&這個數大於前一個數嗎
			for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {

				Utils.swap(arr, j, j + 1);

			}

		}

	}