前面介紹的幾種排序方式都是比較式的排序,今天,我們來介紹兩種非比較排序。計數排序和基數排序。
1.基本思想:
遍歷待排陣列,找到陣列中最大的元素,然後開闢乙個比這個最大元素大1的新陣列,以新陣列的下標表示待排元素,統計原陣列中所有元素出現的個數放在新陣列相應的位置,然後把新陣列中除過0次出現的其餘元素,按順序拷貝回原陣列即可。
2.思想流圖 :
3.**實現:
void countsort(int *array, int size)//計數排序
int *tmp = new int[max + 1];
memset(tmp, 0, sizeof(int)*(max + 1));
for (size_t j = 0; j < size; ++j)
int index = 0;
for (size_t k = 0; k < size; ++k) }
delete tmp;
}
4.演算法效能:
時間複雜度:它的時間複雜度是o(n+k),其中k主要是取決於排序陣列的範圍。
空間複雜度:它的空間複雜度是o(n),實際上,計數排序是一種以空間換時間的做法。
穩定性:不穩定。
適用場景:元素排列比較集中的情況。
5.優化:
當元素比較集中的時候,我們再開闢比最大元素大1的陣列的時候就比較浪費空間,因此我們找到陣列中元素的最大最小值,開闢乙個最大值減去最小值再加一的陣列大小,就比較節省空間。
void countsort1(int* a,size_t n)
if (min > a[i+1])
} //開闢適當空間的陣列
int range = max - min + 1;
int* tmp = new int[range];
memset(tmp,0,sizeof(int)*(range));
for (size_t i = 0; i < n; ++i)
//將資料考回原陣列
int index = 0;
for (int i = 0; i < range; ++i)
} delete tmp;
}
1.基本思想:基數排序又成為「桶子法「,是根據元素各個位先進行排序,比如先根據個位進行排序,再根據十位排,一直排到最大元素的最高位截至。
2.思想流圖:
3.**實現:
int getmaxdigit(int*array, int size)
int count = 0;
while (max)
return count;
}void lsdsort(int *array, int size)//基數排序
; for (size_t i = 0; i < size; ++i)
int start[10] = ;
//統計個位相同的數在陣列中出現的位置
for (size_t j = 1; j < size; ++j)
memset(tmp, 0, sizeof(int)*size);
for (int k = 0; k < size; ++k)
memcpy(array, tmp, sizeof(int)*size);
base *= 10;
} delete tmp;
}
4.演算法效能:
時間複雜度:0(n*digit)主要取決於最大元素的位數digit。
空間複雜度:o(n)
穩定性:穩定。
計數排序和基數排序
計數排序和基數排序是屬於線性級時間複雜度的排序方式,雖然沒有冒泡,選擇,快排演算法那些讓人廣為所知,但是這兩種排序方式在某些場合非常適用。計數排序是基數排序的基礎,最為關鍵的是 基數排序演算法是字尾陣列的關鍵 當然字尾陣列也可以用快排 字尾陣列是用於處理字串的一種非常優秀的資料結構,可以高效的處理很...
計數排序 基數排序
一.計數排序 counting sort 基本思想 對每乙個輸入元素x,確定出小於x的元素個數。適用範圍 適用於輸入是由小範圍的整數構成的序列。穩定性 演算法是穩定的。具體實現 include using namespace std arr 初始輸入陣列,res 存放排序結果的陣列,hash臨時儲存...
桶排序 基數排序 計數基數排序 Java
前面已經講述了很多排序演算法,但是他們的排序演算法都是基於兩個值之間的比較,通過決策樹的方法可以證明深度為d的二叉樹則最多有 一些好的排序演算法是可以達到時間複雜度是線性的,桶排序就是其中一種。比如有n個數,但是這些數的最大數不超過m。這個時候就可以定義乙個含有m個元素的陣列 初始值為0 然後遍歷n...