- 資料結構與演算法
- DSA - 首頁
- DSA - 概述
- DSA - 環境設定
- DSA - 演算法基礎
- DSA - 漸近分析
- 資料結構
- DSA - 資料結構基礎
- DSA - 資料結構和型別
- DSA - 陣列資料結構
- 連結串列
- DSA - 連結串列資料結構
- DSA - 雙向連結串列資料結構
- DSA - 迴圈連結串列資料結構
- 棧與佇列
- DSA - 棧資料結構
- DSA - 表示式解析
- DSA - 佇列資料結構
- 搜尋演算法
- DSA - 搜尋演算法
- DSA - 線性搜尋演算法
- DSA - 二分搜尋演算法
- DSA - 插值搜尋
- DSA - 跳躍搜尋演算法
- DSA - 指數搜尋
- DSA - 斐波那契搜尋
- DSA - 子列表搜尋
- DSA - 雜湊表
- 排序演算法
- DSA - 排序演算法
- DSA - 氣泡排序演算法
- DSA - 插入排序演算法
- DSA - 選擇排序演算法
- DSA - 歸併排序演算法
- DSA - 希爾排序演算法
- DSA - 堆排序
- DSA - 桶排序演算法
- DSA - 計數排序演算法
- DSA - 基數排序演算法
- DSA - 快速排序演算法
- 圖資料結構
- DSA - 圖資料結構
- DSA - 深度優先遍歷
- DSA - 廣度優先遍歷
- DSA - 生成樹
- 樹資料結構
- DSA - 樹資料結構
- DSA - 樹的遍歷
- DSA - 二叉搜尋樹
- DSA - AVL樹
- DSA - 紅黑樹
- DSA - B樹
- DSA - B+樹
- DSA - 伸展樹
- DSA - 字典樹
- DSA - 堆資料結構
- 遞迴
- DSA - 遞迴演算法
- DSA - 使用遞迴的漢諾塔
- DSA - 使用遞迴的斐波那契數列
- 分治法
- DSA - 分治法
- DSA - 最大最小問題
- DSA - Strassen矩陣乘法
- DSA - Karatsuba演算法
- 貪心演算法
- DSA - 貪心演算法
- DSA - 旅行商問題(貪心演算法)
- DSA - Prim最小生成樹
- DSA - Kruskal最小生成樹
- DSA - Dijkstra最短路徑演算法
- DSA - 地圖著色演算法
- DSA - 分數揹包問題
- DSA - 帶截止日期的作業排序
- DSA - 最佳合併模式演算法
- 動態規劃
- DSA - 動態規劃
- DSA - 矩陣鏈乘法
- DSA - Floyd-Warshall演算法
- DSA - 0-1揹包問題
- DSA - 最長公共子序列演算法
- DSA - 旅行商問題(動態規劃)
- 近似演算法
- DSA - 近似演算法
- DSA - 頂點覆蓋演算法
- DSA - 集合覆蓋問題
- DSA - 旅行商問題(近似演算法)
- 隨機演算法
- DSA - 隨機演算法
- DSA - 隨機快速排序演算法
- DSA - Karger最小割演算法
- DSA - Fisher-Yates洗牌演算法
- DSA有用資源
- DSA - 問答
- DSA - 快速指南
- DSA - 有用資源
- DSA - 討論
基數排序演算法
基數排序是一種逐步排序演算法,它從輸入元素的最低有效位開始排序。與計數排序和桶排序一樣,基數排序也假設輸入元素有一些特性,即它們都是k位數。
排序從每個元素的最低有效位開始。這些最低有效位都被視為單個元素並首先排序;然後是次低有效位。這個過程持續進行,直到輸入元素的所有位都被排序。
注意 − 如果元素的位數不相等,則找到輸入元素中位數的最大值,並在位數較少的元素前面新增前導零。這不會改變元素的值,但仍然使它們成為k位數。
基數排序演算法
基數排序演算法在每個階段排序時都使用計數排序演算法。詳細步驟如下:
步驟1 − 檢查所有輸入元素的位數是否相同。如果不相同,檢查列表中位數最多的數字,並在位數較少的數字前面新增前導零。
步驟2 − 獲取每個元素的最低有效位。
步驟3 − 使用計數排序邏輯對這些位進行排序,並根據獲得的輸出更改元素的順序。例如,如果輸入元素是十進位制數,則每個位可以取的值為0-9,因此根據這些值對位進行索引。
步驟4 − 對下一個最低有效位重複步驟2,直到元素中的所有位都被排序。
步驟5 − 第k次迴圈後獲得的最終元素列表是排序後的輸出。
虛擬碼
Algorithm: RadixSort(a[], n):
// Find the maximum element of the list
max = a[0]
for (i=1 to n-1):
if (a[i]>max):
max=a[i]
// applying counting sort for each digit in each number of
//the input list
For (pos=1 to max/pos>0):
countSort(a, n, pos)
pos=pos*10
呼叫的countSort演算法為:
Algorithm: countSort(a, n, pos)
Initialize count[0…9] with zeroes
for i = 0 to n:
count[(a[i]/pos) % 10]++
for i = 1 to 10:
count[i] = count[i] + count[i-1]
for i = n-1 to 0:
output[count[(a[i]/pos) % 10]-1] = a[i]
i--
for i to n:
a[i] = output[i]
分析
假設輸入元素中有k位,則基數排序演算法的執行時間為Θ(k(n + b))。這裡,n是輸入列表中的元素個數,b是數字每一位可能取值的個數。
示例
對於給定的無序元素列表 236, 143, 26, 42, 1, 99, 765, 482, 3, 56,我們需要執行基數排序並獲得排序後的輸出列表:
步驟1
檢查位數最多的元素,為3位。因此,我們為位數少於3位的數字新增前導零。我們得到的列表為:
236, 143, 026, 042, 001, 099, 765, 482, 003, 056
步驟2
構建一個表來根據其索引儲存值。由於給定的輸入是十進位制數,因此基於這些數字的可能值(即0-9)進行索引。
步驟3
根據所有數字的最低有效位,將數字放在各自的索引上。
此步驟排序後的元素為 001, 042, 482, 143, 003, 765, 236, 026, 056, 099。
步驟4
此步驟的輸入順序為上一步輸出的順序。現在,我們使用次低有效位進行排序。
獲得的輸出順序為 001, 003, 026, 236, 042, 143, 056, 765, 482, 099。
步驟5
上一步後的輸入列表重新排列為:
001, 003, 026, 236, 042, 143, 056, 765, 482, 099
現在,我們需要對輸入元素的最後一位進行排序。
由於輸入元素中沒有其他位,因此此步驟中獲得的輸出被視為最終輸出。
最終排序後的輸出為:
1, 3, 26, 42, 56, 99, 143, 236, 482, 765
實現
計數排序演算法協助基數排序對多個d位數字進行迭代排序,迴圈次數為'd'。本教程中基數排序已使用四種程式語言實現:C、C++、Java、Python。
#include <stdio.h>
void countsort(int a[], int n, int pos){
int output[n + 1];
int max = (a[0] / pos) % 10;
for (int i = 1; i < n; i++) {
if (((a[i] / pos) % 10) > max)
max = a[i];
}
int count[max + 1];
for (int i = 0; i < max; ++i)
count[i] = 0;
for (int i = 0; i < n; i++)
count[(a[i] / pos) % 10]++;
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i--) {
output[count[(a[i] / pos) % 10] - 1] = a[i];
count[(a[i] / pos) % 10]--;
}
for (int i = 0; i < n; i++)
a[i] = output[i];
}
void radixsort(int a[], int n){
int max = a[0];
for (int i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
for (int pos = 1; max / pos > 0; pos *= 10)
countsort(a, n, pos);
}
int main(){
int a[] = {236, 15, 333, 27, 9, 108, 76, 498};
int n = sizeof(a) / sizeof(a[0]);
printf("Before sorting array elements are: ");
for (int i = 0; i <n; ++i) {
printf("%d ", a[i]);
}
radixsort(a, n);
printf("\nAfter sorting array elements are: ");
for (int i = 0; i < n; ++i) {
printf("%d ", a[i]);
}
printf("\n");
}
輸出
Before sorting array elements are: 236 15 333 27 9 108 76 498 After sorting array elements are: 9 15 27 76 108 236 333 498
#include <iostream>
using namespace std;
void countsort(int a[], int n, int pos){
int output[n + 1];
int max = (a[0] / pos) % 10;
for (int i = 1; i < n; i++) {
if (((a[i] / pos) % 10) > max)
max = a[i];
}
int count[max + 1];
for (int i = 0; i < max; ++i)
count[i] = 0;
for (int i = 0; i < n; i++)
count[(a[i] / pos) % 10]++;
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i--) {
output[count[(a[i] / pos) % 10] - 1] = a[i];
count[(a[i] / pos) % 10]--;
}
for (int i = 0; i < n; i++)
a[i] = output[i];
}
void radixsort(int a[], int n){
int max = a[0];
for (int i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
for (int pos = 1; max / pos > 0; pos *= 10)
countsort(a, n, pos);
}
int main(){
int a[] = {236, 15, 333, 27, 9, 108, 76, 498};
int n = sizeof(a) / sizeof(a[0]);
cout <<"Before sorting array elements are: ";
for (int i = 0; i < n; ++i) {
cout <<a[i] << " ";
}
radixsort(a, n);
cout <<"\nAfter sorting array elements are: ";
for (int i = 0; i < n; ++i) {
cout << a[i] << " ";
}
cout << "\n";
}
輸出
Before sorting array elements are: 236 15 333 27 9 108 76 498 After sorting array elements are: 9 15 27 76 108 236 333 498
import java.io.*;
public class Main {
static void countsort(int a[], int n, int pos) {
int output[] = new int[n + 1];
int max = (a[0] / pos) % 10;
for (int i = 1; i < n; i++) {
if (((a[i] / pos) % 10) > max)
max = a[i];
}
int count[] = new int[max + 1];
for (int i = 0; i < max; ++i)
count[i] = 0;
for (int i = 0; i < n; i++)
count[(a[i] / pos) % 10]++;
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i--) {
output[count[(a[i] / pos) % 10] - 1] = a[i];
count[(a[i] / pos) % 10]--;
}
for (int i = 0; i < n; i++)
a[i] = output[i];
}
static void radixsort(int a[], int n) {
int max = a[0];
for (int i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
for (int pos = 1; max / pos > 0; pos *= 10)
countsort(a, n, pos);
}
public static void main(String args[]) {
int a[] = {236, 15, 333, 27, 9, 108, 76, 498};
int n = a.length;
System.out.println("Before sorting array elements are: ");
for (int i = 0; i < n; ++i)
System.out.print(a[i] + " ");
radixsort(a, n);
System.out.println("\nAfter sorting array elements are: ");
for (int i = 0; i < n; ++i)
System.out.print(a[i] + " ");
}
}
輸出
Before sorting array elements are: 236 15 333 27 9 108 76 498 After sorting array elements are: 9 15 27 76 108 236 333 498
def countsort(a, pos):
n = len(a)
output = [0] * n
count = [0] * 10
for i in range(0, n):
idx = a[i] // pos
count[idx % 10] += 1
for i in range(1, 10):
count[i] += count[i - 1]
i = n - 1
while i >= 0:
idx = a[i] // pos
output[count[idx % 10] - 1] = a[i]
count[idx % 10] -= 1
i -= 1
for i in range(0, n):
a[i] = output[i]
def radixsort(a):
maximum = max(a)
pos = 1
while maximum // pos > 0:
countsort(a, pos)
pos *= 10
a = [236, 15, 333, 27, 9, 108, 76, 498]
print("Before sorting array elements are: ")
print (a)
radixsort(a)
print("After sorting array elements are: ")
print (a)
輸出
Before sorting array elements are: [236, 15, 333, 27, 9, 108, 76, 498] After sorting array elements are: [9, 15, 27, 76, 108, 236, 333, 498]