【資料結構】非比較排序--計數排序和基數排序
阿新 • • 發佈:2019-02-16
非比較排序
- 1、思想
不需要進行元素之間的比較,交換,線上性的時間內完成排序。 - 2、分類
1)計數排序
2)基數排序 - 3、優缺點
要求的空間比較多,是典型的以空間換時間的一種做法
計數排序
- 1、原理
- 2、程式碼實現
#include<iostream>
using namespace std;
void CountSort(int* a,int n)
{
//1、首先確定要開一個多大的用於統計的陣列
int size = 0;
int min = a[0];
int max = a[0];
for(int i = 0; i<n; i++)
{
if (a[i] < min)
min = a[i];
if(a[i] > max)
max = a[i];
}
size = max-min+1;
//2、開始進行統計原陣列中對應下標出現的數
int* count = new int[size];
memset(count,0,sizeof(int)*size);
for(int i = 0; i<n; i++)
{
count[a[i]-min]++;
}
//3、遍歷雜湊表,將count陣列中大於0的數對應出原陣列的值,
//寫入原陣列中
int j = 0;
for(int i = 0; i<size; i++)
{
while(count[i]--)
{
a[j++] = i+min;
}
}
delete[] count;
}
//測試函式
void TestCountSort()
{
int a[10] = {2,5,3,8,3,7,10,9,4,0};
int sz = sizeof(a)/sizeof(a[0]);
CountSort(a,sz);
for(int i = 0; i<sz; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
4、時間複雜度和空間複雜度
時間複雜度:O(N)
空間複雜度:O(k)(其中K為要排序的陣列的範圍)5、優缺點
1)缺點:由於計數排序的計數陣列的大小是取決於資料的範圍,那麼當要進行排序的資料範圍很大時,就需要大量的時間和記憶體。
2)優點:
A:無需進行比較,所以時間上快於任何的比較排序。
B:適用於資料比較集中的資料排序
基數排序
- 1、原理
- 2、分類:
LSD–從低位向高位排
MSD–從高位向低位排 - 3、程式碼實現
#include<iostream>
using namespace std;
//給一個數,求這個數有多少位
int GetDigit(int* a,size_t n)
{
int base = 10;
int digit = 1;
int num = 0;
for(int i = 0; i<n; i++)
{
while(a[i] >= base)
{
digit++;
base *= 10;
}
}
return digit;
}
void LSDdigit(int* a,int n)
{
int digit = GetDigit(a,n); //得到位數
int count[10] = {0};
int start[10] = {0};
int base = 1;
//開闢一個新的陣列,用於存放一次排序後的數
int*temp = new int[n];
while(digit--)
{
//首先按各位進行統計個位上的數出現的次數
for(int i = 0; i<n; i++)
{
int num = (a[i]/base)%10;
count[num]++;
}
start[0] = 0;
for(int i = 1; i<10; i++)
{
start[i] = start[i-1]+count[i-1];
}
for(int i = 0; i<10; i++)
{
int num = (a[i]/base)%10;
temp[start[num]++] = a[i];
count[num]--;
}
for(int i = 0; i<10; i++)
{
a[i] = temp[i];
}
base *= 10;
}
delete[] temp;
}
//測試函式
void TestLSDdigit()
{
int a[10] = {73,22,93,43,55,14,28,65,39,81};
int sz = sizeof(a)/sizeof(a[0]);
LSDdigit(a,sz);
for(int i = 0; i<sz; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
- 4、時間複雜度和空間複雜度
時間複雜度:O(N*digit)
空間複雜度:O(N) 5、適用性
- 基數排序更適合用於對時間、字串等這些整體權值未知的資料進行排序。
- 注意:基數排序如果從高位向低位排的話會很麻煩
6、缺點
由於是空間換取時間,按位進行排序,那麼每一位的數的位置可能會發生巨大的變化,目前硬體的快取不是很佔優勢,並且當記憶體比較寶貴的時候,就不要採取這種方式進行排序了。