第8章 线性时间排序
一、概念
任何比較排序在最壞情況下都要用O(lgn)次比較不進行排序
計算排序、基數排序、桶排序都是穩定排序
?
二、代碼
#include <iostream> #include <cmath> using namespace std; int length_A, digit; void Print(int *A, int start, int end) { int i; for(i = start; i <= end; i++) { if(i == start)cout<<'{'; else cout<<' '; cout<<A[i]; } cout<<'}'<<endl; } //計數排序 void Counting_Sort(int *A, int *B, int k) { int i, j; //將C數組初始化為0,用于計數 int *C = new int[k+1]; for(i = 0; i <= k; i++) C[i] = 0; //C[j]表示數字j在數組A中出現的次數 for(j = 1; j <= length_A; j++) C[A[j]]++; //C[i]表示所以<=i的數字出現過的次數 for(i = 1; i <= k; i++) C[i] = C[i] + C[i-1]; //初始化B為0,B用于輸出排序結果 for(i = 1; i <= length_A; i++) B[i] = 0; for(j = length_A; j >= 1; j--) { //如果<=A[j]的數字的個數是x,那么排序后A[j]應該出現在第x個位置,即B[x]=A[j] B[C[A[j]]] = A[j]; C[A[j]]--; } delete C; } //基數排序調用的穩定排序 void Stable_Sort(int *A, int *B, int k, int d) { int i, j; //將C數組初始化為0,用于計數 int *C = new int[k+1]; for(i = 0; i <= k; i++) C[i] = 0; int *D = new int[length_A+1]; for(j = 1; j <= length_A; j++) { //D[j]表示第[j]個元素的第i位數字 D[j] = A[j] % (int)pow(10.0, d) / (int)pow(10.0, d-1); //C[j]表示數字D[j]在數組A中出現的次數 C[D[j]]++; } //C[i]表示所以<=i的數字出現過的次數 for(i = 1; i <= k; i++) C[i] = C[i] + C[i-1]; //初始化B為0,B用于輸出排序結果 for(i = 1; i <= length_A; i++) B[i] = 0; for(j = length_A; j >= 1; j--) { //如果<=D[j]的數字的個數是x,那么排序后A[j]應該出現在第x個位置,即B[x]=A[j] B[C[D[j]]] = A[j]; C[D[j]]--; } delete []C; delete []D; } //基數排序 void Radix_Sort(int *A, int *B) { int i, j; //依次對每一位進行排序,從低位到高位 for(i = 1; i <= digit; i++) { Stable_Sort(A, B, 9, i); //輸入的是A,輸出的是B,再次排序時要把輸出數據放入輸出數據中 for(j = 1; j <= length_A; j++) A[j] = B[j]; } } int main() { cin>>length_A>>digit; int *A = new int[length_A+1]; int *B = new int[length_A+1]; int i; //隨機產生length_A個digit位的數據 for(i = 1; i <= length_A; i++) { A[i] = 0; while(A[i] < (int)pow(10.0, digit-1)) A[i] = rand() % (int)pow(10.0, digit); } Print(A, 1, length_A); // Counting_Sort(A, B, 9); Radix_Sort(A, B); Print(A, 1, length_A); delete []A; delete []B; return 0; }
?
?
三、練習
?
8.1-1 決策樹是一棵二叉樹,每個節點表示元素之間一組可能的排序,它與已進行的比較相一致,比較的結果是樹的邊。 令T是深度為d的二叉樹,則T最多有2^T片葉子。具有L片葉子的二叉樹深度至少是lgL。 n個元素排序會有n!個不同的大小關系,其決策樹必然有n!片樹葉,因此決策樹的深度至少是lg(n!)?
?
8.2-1因為假設待排序數據的范圍中[0,k],所以B被初始化為-1
?
A = {6 0 2 0 1 3 4 6 1 3 2} ==> C = {2 2 2 2 1 0 2} ==> C = {2 4 6 8 9 9 11} ==> B = {-1 -1 -1 -1 -1 2 -1 -1 -1 -1 -1} C = {2 4 5 8 9 9 11} ==> B = {-1 -1 -1 -1 -1 2 -1 3 -1 0 -1 -1} C = {2 4 5 7 9 9 11} ==> B = {-1 -1 -1 1 -1 2 -1 3 -1 -1 -1} C = {2 3 5 7 9 9 11} ==> B = {-1 -1 -1 1 -1 2 -1 3 -1 -1 6} C = {2 3 5 7 9 9 10} ==> B = {-1 -1 -1 1 -1 2 -1 3 4 -1 6} C = {2 3 5 7 8 9 10} ==> B = {-1 -1 -1 1 -1 2 3 3 4 -1 6} C = {2 3 5 6 8 9 10} ==> B = {-1 -1 1 1 -1 2 3 3 4 -1 6} C = {2 2 5 6 8 9 10} ==> B = {-1 0 1 1 -1 2 3 3 4 -1 6} C = {1 2 5 6 8 9 10} ==> B = {-1 0 1 1 2 2 3 3 4 -1 6} C = {1 2 4 6 8 9 10} ==> B = {0 0 1 1 2 2 3 3 4 -1 6} C = {0 2 4 6 8 9 10} ==> B = {0 0 1 1 2 2 3 3 4 6 6} C = {0 2 4 6 8 9 9}
?
8.2-3 不穩定?
?
8.2-4 COUNTING-SORT(A, B, k)中步驟L1-L4求出C,ans = C[b] - C[a-1],?C[-1]=08.3-1 A = {COW, DOG, SEA, RUG, ROW, MOB, BOX, TAB, BAR, EAR, TAR, DIG, BIG, TEA, NOW, FOX} ==> A = {SEA, TEA, MOB, TAB, DOG, RUG, DIG, BIG, BAR, EAR, TAR, COW, ROW, NOW, BOX, FOX} ==> A = {TAB, BAR, EAR, TAR, SEA, TEA, DIG, BIG, MOB, DOG, COW, ROW, NOW, BOX, FOX, RUB} ==> A = {BAR, BIG, BOX, COW, DIG, DOG, EAR, FOX, MOB, NOW, ROW, TAB, TAR, TEA, SEA, RUB}8.3-2
穩定排序有:插入排序,合并排序 方法:為每一個元素加入一個最初位置的屬性,但兩個元素的value一樣大時,比較position,這樣不會有相同的兩個元素 額外空間:O(4n) 8.3-3 把整數轉換為n進制再排序,見算法導論8.3-4 8.3-4 最壞情況下需要d遍
8.4-1 A = {0.79, 0.13, 0.16, 0.64, 0.39, 0.20, 0.89, 0.53, 0.71, 0.42} ==> A = {0.13, 0.16, 0.20, 0.39, 0.42, 0.53, 0.64, 0.79, 0.71, 0.89} ==> A = {0.13, 0.16, 0.20, 0.39, 0.42, 0.53, 0.64, 0.71, 0.79, 0.89} 8.4-2 最壞情況是O(n^2) 修改:使用最壞情況下時間為O(nlgn)的算法來處理桶的插入操作 8.4-3 E(X^2)=3/2 E^2(X)=1/2不知道怎么算 8.4-4 假設分為n個桶 BUCKET-SORT(A) 1 ? ?n <- length[A] 2 ? ?for i <- 1 to n 3 ? ?do insert A[i] to list B[n*(A[i].x^2 + A[i].y^2)] 4 ? ?for i <- 0 to n-1 5 ? ? ? ?do sort list B[i] with insertion sort 6????concatenate the lists B[0], B[1], ……,B[n-1] together in order 8.4-5
8-2 計數排序:時間O(k+n),穩定,空間O(k+n) 基數排序:時間O(d*(k+n)),穩定,無額外空間 桶排序:時間O(n),穩定,空間O(n) a)計數排序、基數排序、桶排序 b)基數排序 c)基數排序 d)基數排序 e)不穩定 COUNTING-SORT(A, k) 1 for i <- 0 to k 2 do C[i] <- 0 3 for j <-1 to length[A] 4 C[A[j]] <- C[A[j]] + 1 5 cnt <- 1 6 for i <- 1 to k 7 while C[i] > 0 8 A[cnt] <- i 9 C[i] <- C[j] - 1 10 cnt <- cnt + 1
8-3 a)先用桶排序(答案里面是計數排序)方法按數字位數排序O(n),再用基數排序的方法分別對每個桶中的元素排序O(n) b)遞歸使用計數排序,先依據第一個字母進行排序,首字相同的放在同一組(我覺得更像是桶排序),再對每一組分別使用計數排序的方法比較第二個字母 見到有人用字典樹,也是可以的 代碼見算法導論-8-3-排序不同長度的數據項
8-4 a)最原始的比較方法,所有的紅水壺與所有的藍水壺依次比較 c)算法類似于快排,由于不是同種顏色的水壺之間比較,所以采用交叉比較 step1:從紅色水壺中隨機選擇一個 step2:以紅色水壺為主元對藍色水壺進行劃分 step3:劃分的結果是兩個數組,并得到與紅色水壺相同大小的藍色水壺 step4:以這個藍色水壺為主元,對紅色水壺進行劃分 step5:用step1到step4的過程不斷迭代 8-5 a)1排序是完全排序 b)1,3,2,4,5,7,6,8,9,10 d) step1:分別把1, 1+k, 1+2k, 1+3k,……;2, 2+k, 2+2k, 2+3k,……;……當作是單獨的集合 step2:對每個集合進行排序時間為O(nlg(n/k))
e) step1:同d)step1 step2:用堆排序進行k路合并,見算法導論6.5-8堆排序-K路合并
轉載于:https://www.cnblogs.com/windmissing/archive/2012/06/20/2559798.html
總結
以上是生活随笔為你收集整理的第8章 线性时间排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 对象名无效 问题
- 下一篇: 在ios开发中使用 try 和 catc