前面有總結過各類常用的排序演算法,但是那些排序演算法平均的時間複雜度是o(nlogn),所以我要介紹三種時間複雜度為o(n)的線性時間複雜度的排序演算法。
計數排序利用了雜湊的性質,將乙個中間陣列來記錄數值對應的下標,最後查詢對應的下標進行放置;
步驟如下:
找出待排序的陣列中最小和最大值,計算最大和最小值之間的差值;
計算每個數值出現的次數,接著進行累加計算出數值的位置;
反向填充陣列,根據查詢下標找到位置後填充數值;
#include #include using namespace std;
vectorcounting_sort(vectornums)
if (min > nums[i])
}int k = max - min + 1;
vectortemp(k, 0);
// 第一步:計算每個數字出現的次數
for (size_t i = 0; i < len; i++)
// 第二步:累加
for (size_t i = 1; i < len; i++)
vectorresult(len, 0);
// 第三步:將數字放在相應的位置
for (size_t i = 0; i < len; i++)
return result;
}int main() );
for (auto re : res)
return 0;
}
利用了雜湊的原理,其時間複雜度為n,但是這是用空間複雜度來換的,即便上面有進行過優化,但是面對乙個較大值和較小值的陣列,其仍然會對空間造成很大的浪費。
將所有數值在每一位上面進行排序,排序方法利用計數排序的原理;
步驟:計算數值中最大值的位數,用作後面比較的次數;
計算所有數值在每一位上面的排序,參考計數排序;
void redis_sort(vector& nums)
// 第二步:累加計算下標
for (int j = 1; j < 10; j++)
// 第三步:根據bit的下標找到位置來填充
for (int j = len-1; j >= 0; j--)
// 第四部:排好序的陣列賦值
for (int j = 0; j < len; j++) }}
因為其下標在0-10之間,所以有效的控制了空間複雜度,但是其複雜度較計數排序增加了,明顯其時間複雜度為o(k * n),k代表數字位數,這取決於數字位的選擇,比如位元位數,其決定了要進行多少輪的處理;雖然增加了時間複雜度,但依舊比那些需要進行比較的排序演算法較快一些。
桶排序的原理在於將陣列分配到一定數量的桶中,每個桶在個別排序,最後合併排序。
const int bucket_num = 10;
// 鍊錶的插入排序
linknode* insert(linknode* head, int val)
node->_next = temp->_next;
temp->_next = node;
return newhead->_next;
}// 兩個排序鍊錶的合併
linknode* merge(linknode* head, linknode* bucket_node)
else
temp = temp->_next;
}if (head != null)
else if (bucket_node != null)
return newhead->_next;
}vectorbucketsort(vectornums)
// 第二步:將桶中的值進行合併
linknode *head = null;
for (int i = 0; i < bucket_num; i++)
// 第三步:將排序好的鍊錶賦值
vectorresult(len, 0);
for (int i = 0; i < len, head != null; i++, head = head->_next)
return result;
}
如果陣列中的每個數值都會均勻的落入每個桶中,則其最優的時間複雜度在n,但是如果數值都集中的加入到固定的幾個桶中,甚至是都落入乙個桶中,那麼這樣在對數值進行插入排序的時候就變成了雙層迴圈,則其最差時間複雜度為n^2。 線性排序演算法
插入,快速,合併,堆排序等基於比較的排序演算法的最壞情況下界為 nlogn 最壞情況下都要進行 nlogn 次比較。假設有一n個元素組成的陣列 假設每個元素都不相等 那麼一共有n 排列組合,而且這n 排列組合結果都應該在決策樹的葉子節點上 如圖1 在圖1中n 3,所以有3 6種組合全都在決策樹的葉子...
線性時間排序演算法
基於比較的演算法的時間下限為nlogn,而計數排序 桶排序和基數排序這幾種非比較演算法卻可以突破這個下限,僅管它們對輸入都有一定限制條件,即輸入資料必須在某個範圍內。但是,這些演算法還是非常實用的。閒著沒事,寫了一下 詳細見 演算法導論 define no cmp sort ifdef no cmp...
線性時間排序演算法
基於比較的演算法的時間下限為nlogn,而計數排序 桶排序和基數排序這幾種非比較演算法卻可以突破這個下限,僅管它們對輸入都有一定限制條件,即輸入資料必須在某個範圍內。但是,這些演算法還是非常實用的。閒著沒事,寫了一下 詳細見 演算法導論 define no cmp sort ifdef no cmp...