Merge pull request #360 from caitlingao/13_sorts

feat(geektime_algo): add 13 sorts
This commit is contained in:
wangzheng0822 2019-07-20 10:02:59 +08:00 committed by GitHub
commit 9056274f87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 207 additions and 0 deletions

View File

@ -0,0 +1,80 @@
/// 桶排序
/// 时间复杂度O(n), 稳定排序
// 桶排序
pub fn bucket_sort(mut nums: Vec<i32>, step: i32) -> Vec<i32> {
let (mut min, mut max) = (nums[0], nums[0]);
for i in 0..nums.len() {
if min > nums[i] { min = nums[i]; }
if max < nums[i] { max = nums[i]; }
}
// 设置需要的桶的数量
let bucket_num = (max - min) / step + 1;
let mut bucket_list: Vec<Vec<i32>> = vec![vec![]; bucket_num as usize];
// 将 nums 数组中元素分别装入桶中
for i in 0..nums.len() {
// 计算桶 index
let index = (nums[i] - min) / step;
bucket_list[index as usize].push(nums[i]);
}
let mut index = 0;
for i in 0..bucket_num {
let bucket = &bucket_list[i as usize];
// 对每个桶中元素使用快排进行排序
let new_bucket = quick_sort(bucket.to_vec());
// 将已经排序好的桶中元素拷贝到 nums 数组中
for num in new_bucket.into_iter() {
nums[index as usize] = num;
index += 1;
}
}
nums
}
pub fn quick_sort(mut nums: Vec<i32>) -> Vec<i32> {
if nums.is_empty() { return nums; }
let n = nums.len() - 1;
quick_sort_internally(&mut nums, 0, n);
nums
}
fn quick_sort_internally(nums: &mut Vec<i32>, start: usize, end: usize) {
if start >= end { return; }
// 分区点
let pivot = partition(nums, start, end);
if pivot != 0 {
quick_sort_internally(nums, start, pivot-1);
}
quick_sort_internally(nums, pivot+1, end);
}
fn partition(nums: &mut Vec<i32>, start: usize, end: usize) -> usize {
let pivot = nums[end];
let mut i = start;
for j in start..end {
if nums[j] < pivot {
swap(nums, i, j);
i += 1;
}
}
swap(nums, i, end);
i
}
fn swap(nums: &mut Vec<i32>, i: usize, j: usize) {
if i == j { return; }
let tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
fn main() {
let nums = vec![2, 5, 3, 0, 2, 3, 0, 3];
let m = bucket_sort(nums, 3);
println!("{:?}", m);
}

View File

@ -0,0 +1,51 @@
/// 计数排序
/// 时间复杂度O(n), 稳定排序
// 计数排序
pub fn counting_sort(mut nums: Vec<i32>) -> Vec<i32> {
if nums.len() <= 1 { return nums; }
let nums_len = nums.len();
// 获取最大数
let mut max = nums[0];
// 申请一个长度为 max + 1 的新数组
let mut bucket = vec![0; (max+1) as usize];
let mut tmp = vec![0; nums_len];
for i in 1..nums_len {
if max < nums[i] { max = nums[i]; }
}
for i in 0..nums_len {
bucket[nums[i] as usize] += 1;
}
// 对 bucket 中元素进行累加,针对 nums 数组中每个元素,小于等于这个元素的个数
// 如nums 数组中元素 3小于等于 3 的个数为 7 个
for i in 1..bucket.len() {
bucket[i] += bucket[i-1];
}
// 排序
// 1. 申请一个与 nums 等长的数组,用于存储排序后的内容;
// 2. 对数组 nums 从后向前迭代
// 1). 从 bucket 数组中取出下标为 nums 数组中当前元素的值,如 nums 中当前元素为3则从 bucket
// 中取出下标为 3 的元素(即:在 nums 数组中元素 3 的位置应该为 7index 为 6
// 2). 将元素 3 存入临时数组,此时元素 3 的个数变为 6 个
// 3). 依次类推,直到将所有元素存入临时数组 tmp 中,完成排序
for i in (0..nums_len).rev() {
let index = bucket[nums[i] as usize] - 1;
tmp[index] = nums[i];
bucket[nums[i] as usize] -= 1;
}
for i in 0..tmp.len() {
nums[i] = tmp[i];
}
nums
}
fn main() {
let nums = vec![2, 5, 3, 0, 2, 3, 0, 3];
let m = counting_sort(nums);
println!("{:?}", m);
}

View File

@ -0,0 +1,58 @@
/// 基数排序
/// 时间复杂度O(n), 稳定排序
// 基数排序
pub fn radix_sort(mut nums: Vec<i64>) -> Vec<i64> {
let max_bit = max_bit(&nums);
// 申请一个长度为 10 的桶
let mut bucket = vec![0; 10];
let mut tmp = vec![0; nums.len()];
let mut radix = 1;
let nums_len = nums.len();
// 迭代 max_bit 次
for _i in 0..max_bit {
// 每次比较前先将桶清空
for j in 0..bucket.len() { bucket[j] = 0; }
for j in 0..nums_len {
let index = ((nums[j] / radix) % 10) as usize;
bucket[index] += 1;
}
for j in 1..bucket.len() { bucket[j] += bucket[j-1]; }
// 对 nums 进行排序
for j in (0..nums_len).rev() {
let index = ((nums[j] / radix) % 10) as usize;
tmp[(bucket[index]-1) as usize] = nums[j];
bucket[index] -= 1;
}
for j in 0..nums_len {
nums[j] = tmp[j];
}
radix *= 10;
}
nums
}
fn max_bit(nums: &Vec<i64>) -> i32 {
let mut max = nums[0];
let mut bit = 1; // 预防数据库中元素全部是 0 的情况
for &num in nums.iter() {
if num > max { max = num; }
}
while max >= 10 {
max = max / 10;
bit += 1;
}
bit
}
fn main() {
// let nums = vec![1, 10, 100, 1000, 98, 67, 3, 28, 67, 888, 777];
let nums = vec![13111111111, 13299999999, 13311111111, 13133333333, 13922222222, 13722222222];
println!("{:?}", radix_sort(nums));
}

View File

@ -0,0 +1,18 @@
fn sort_string(s: String) -> Vec<Vec<char>> {
let mut bucket: Vec<Vec<char>> = vec![vec![]; 3];
for ch in s.as_bytes() {
if ch as u8 >= 48 && ch as u8 <= 57 {
bucket[0].push(ch);
} else if ch as u8 >= 65 && ch as u8 <= 90 {
bucket[1].push(ch);
} else {
bucket[2].push(ch);
}
}
bucket
}
fn main() {
let s = "DaFBCA789".to_string();
println!("{:?}", sort_string(s));
}