Skip to content

Commit

Permalink
Merge pull request #10 from donjuanplatinum/patch-2
Browse files Browse the repository at this point in the history
feat(algorithms,doc): 1. insertionsort 2. heap 3. doc
  • Loading branch information
donjuanplatinum authored Jun 6, 2024
2 parents 077bc46 + e1fc3de commit 45ba00c
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "algori"
version = "0.11.10"
edition = "2021"
authors = ["Donjuan Platinum <[email protected]>"]
license = "GPL-2.0-only"
description = "Rust Algorithms"
repository = "https://github.com/donjuanplatinum/Algori"
readme = "README.md"
documentation = "https://docs.rs/algori"
keywords = ["matrix","math","algorithm","sort","search"]
categories = ["algorithms"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div align="center">

[![](https://img.shields.io/crates/d/algori.svg)](https://crates.io/crates/algori)
[![](https://img.shields.io/github/forks/barrensea/algori.svg)](https://github.com/BarrenSea/algori/fork)
[![](https://img.shields.io/github/repo-size/barrensea/algori.svg)](https://github.com/BarrenSea/algori)
[![](https://img.shields.io/github/stars/barrensea/algori.svg)](https://github.com/BarrenSea/algori)
[![](https://img.shields.io/github/commit-activity/t/barrensea/algori.svg)](https://github.com/BarrenSea/algori)

</div>

<p align="center">
<a href="https://github.com/barrensea/algori" rel="noopener">
<img width=200px height=200px src="./imgs/algori.png"></a>

<h3 align="center"><a href="https://join-lemmy.org">Algori</a></h3>
<p align="center">
Rust Algorithms
<br />
<br />
<a href="https://docs.rs/algori">Docs</a>
·
<a href="https://matrix.to/#/#algori:mozilla.org">Matrix</a>
</p>
</p>

## Algorithms
### Sorting 排序
- [Insertionsort 插入排序](./doc/sorting/README.md)
### Structures 数据结构
- [Heap 堆排序](./doc/structure/README.md)
10 changes: 10 additions & 0 deletions doc/sorting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Sorting 排序

+ 插入排序

## 插入排序
[![Insertion_sort](./insertion_sort.svg)](./insertion_sort.svg)

### 复杂度
最优时间复杂度: O(n)
最坏时间复杂度: O(n ^ 2)
1 change: 1 addition & 0 deletions doc/sorting/insertion_sort.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions doc/structure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Structure 数据结构

+ Heap/Priority Queue 堆/优先队列

## Heap/Priority Queue 堆/优先队列
[![Heap](./binary_heap_insert.svg)](./binary_heap_insert.svg)

1 change: 1 addition & 0 deletions doc/structure/binary_heap_insert.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/algori.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2024 Barrensea. Licensed under GPL-2

//! Algori - Rust Algorithms
//!
/// Sortion Algorithms
pub mod sorting;

/// Structures
pub mod structure;



62 changes: 62 additions & 0 deletions src/sorting/insertion_sort.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/// # Insertion_Sort
pub fn insertion_sort<T>(array: &mut[T]) -> ()
where T: PartialOrd,
{
for point in 1..array.len() {
let mut current_point: usize = point;
while current_point > 0 && array[current_point] < array[current_point - 1] {
array.swap(current_point,current_point - 1);
current_point -= 1;
}
}
}

/// # Reverse Insertion_Sort
pub fn reverse_insertion_sort<T>(array: &mut[T]) -> ()
where T: PartialOrd,
{
for point in 1..array.len() {
let mut current_point: usize = point;
while current_point > 0 && array[current_point] > array[current_point - 1] {
array.swap(current_point,current_point - 1);
current_point -= 1;
}
}
}

#[cfg(test)]
mod insertion_sort_tests {
use super::{insertion_sort,reverse_insertion_sort};
use super::super::is_sorted;
#[test]
fn empty() -> ()
{
let mut a: [i32;0] = [];
insertion_sort(&mut a);

assert_eq!(is_sorted(&mut a,|a,b| a <= b),true);
}

#[test]
fn one_element() -> ()
{
let mut a: [i32;1] = [1];
insertion_sort(&mut a);
assert_eq!(is_sorted(&mut a ,|a,b| a <= b),true);
}
#[test]
fn positive() -> ()
{
let mut a = [1,123,123,12,4234,42,1123,123,15112,312];
insertion_sort(&mut a);
assert_eq!(is_sorted(&mut a,|a,b| a <= b),true);
}
#[test]
fn reverse() -> ()
{
let mut a = [1,123,123,12,4234,42,1123,123,15112,312];
reverse_insertion_sort(&mut a);
assert_eq!(is_sorted(&mut a,|a,b| a >= b),true);
}
}

5 changes: 5 additions & 0 deletions src/sorting/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod utils;
mod insertion_sort;

pub use self::utils::*;
pub use self::insertion_sort::* ;
52 changes: 52 additions & 0 deletions src/sorting/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/// # Determine a slice if it is ordered
/// *Feature* : Use a Function to check if a slice is sorted or not
///
/// *Return* : if is sorted or not sorted, return true , if the element cant compare, return false
///
/// # Use
/// ```
/// use algori::sorting::{is_sorted,insertion_sort};
/// let mut a = [1,3,2,0,123,1,1,4634,341,2312452,351];
/// assert_eq!(is_sorted(&mut a, |a,b|a <=b),false);
///
/// insertion_sort(&mut a);
/// assert_eq!(is_sorted(&mut a,|a,b|a<=b),true);
/// ```
pub fn is_sorted<'a, T>(array: &'a [T],compare: fn(&T,&T)->bool) -> bool
where T: PartialOrd + 'a,
{
if array.len() == 0 {return true;}
for i in 0..array.len() - 1 {
match compare(&array[i],&array[i+1]) {
true => {continue;},
false => {return false;},
}
}
return true;
}


#[cfg(test)]
mod issorted_test {
use super::is_sorted;
#[test]
fn sorted() ->() {
let a = [1,2,3,4,5,6,111,321312321,623123124];
assert_eq!(is_sorted(& a, |a,b| a<=b),true);
}
#[test]
fn unsorted() -> () {
let a = [2,0,3,0,4,9,323,1,4,7,1,233,6,7];
assert_eq!(is_sorted(&a, |a,b| a <= b),false);
}
#[test]
fn char_compare() ->() {
let a: &[char] = &['a','b','c','d','e','f','g','h'];
assert_eq!(is_sorted(&a ,|a,b| a <= b),true);
}
#[test]
fn reverse() -> () {
let a = [7,6,5,4,3,2,1,0];
assert_eq!(is_sorted(&a,|a,b| a >= b),true);
}
}
189 changes: 189 additions & 0 deletions src/structure/heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
macro_rules! left_child {
($parent:ident) => {
($parent <<1) + 1 as usize
};
}


macro_rules! right_child {
($parent:ident) => {
($parent <<1) + 2 as usize
};
}


macro_rules! parent {
($child:ident) => {
($child - 1) >> 1
};
}




/// # Heap(Priority Queue)
/// Heap is a completely binary tree , Its parent node always maintains a relationship(define in comparator) with its child nodes
/// # Example
/// ```
/// use algori::structure::Heap;
/// //Create a Max Priority(Max Heap)
/// let mut a: Heap<i32> = Heap::new(|a,b| a >= b);
/// a.push(1); a.push(100); a.push(40); a.push(0);
/// assert_eq!(a.pop().unwrap(),100); assert_eq!(a.pop().unwrap(),40);
/// ```
#[derive(Debug,Clone)]
pub struct Heap<T> {
items: Vec<T>,
comparator: fn(&T,&T) -> bool,
}

use core::ops::Index;
impl<T> Index<usize> for Heap<T>
{
type Output = T;
fn index(&self,index: usize) -> &Self::Output {
return &self.items[index];
}
}

#[allow(dead_code)]
impl<T: PartialOrd> Heap<T> {
/// Create A Heap With A Comparator
/// ```
/// use algori::structure::Heap;
/// let a: Heap<i32> = Heap::new(|a,b| a >= b);
/// ```
pub fn new(comparator: fn(&T,&T) -> bool) -> Self {
return Self {
items: vec!(),
comparator,
};
}
/// Return The Length Of Heap
pub fn len(&self) -> usize {
return self.items.len();
}
pub fn is_empty(&self) -> bool {
return self.items.is_empty();
}
/// heapify_down use the comparator
fn heapify_down(&mut self,start: usize,end:usize) {
let mut better_element_index: usize = start;
if right_child!(start) < end && (self.comparator)(&self.items[right_child!(start)],&self.items[better_element_index]) {
better_element_index = right_child!(start);
}
if left_child!(start) < end && (self.comparator)(&self.items[left_child!(start)],&self.items[better_element_index]) {
better_element_index = left_child!(start);
}
if better_element_index != start {
self.items.swap(start,better_element_index);
self.heapify_down(better_element_index,end);
}
}
/// Push A New Element and heapify
pub fn push(&mut self,value: T) ->()
{
self.items.push(value);
let mut point: usize = self.len() - 1;
while point > 0 && (self.comparator)(&self.items[point],&self.items[parent!(point)]) {
self.items.swap(point,parent!(point));
point = parent!(point);
}
}
/// Pop the Top Element
pub fn pop(&mut self) -> Result<T,&str> {
if self.is_empty() {return Err("Heap Is Empty!");}
if self.len() == 1 {return Ok(self.items.pop().unwrap());}
// pop the top element
let pop_element:T = self.items.swap_remove(0);
self.heapify_down(0,self.len());
Ok(pop_element)
}
/// heap_sort use the comparator
pub fn sort(&mut self) -> () {
let len = self.len();
// heap_sort
for i in (1..len).rev() {
self.items.swap(0, i);
self.heapify_down(0, i);
}
}

/// clear all the elements
pub fn clear(&mut self) ->() {
self.items.clear();
}
}

#[allow(unused_parens)]
#[allow(dead_code)]
impl<T> Heap<T> {
pub fn comparator(&self) -> (fn(&T,&T) -> bool)
{
return self.comparator;
}
}




#[cfg(test)]
mod heap_tests {
use super::Heap;
#[test]
fn comparator_test() ->() {
let a: Heap<i32> = Heap::new(|a,b| a > b);
let c = (a.comparator())(&6,&7);
assert_eq!(c,false)
}
#[test]
fn macro_test() ->() {
let mut a = 0;
let l = left_child!(a);
let r = right_child!(a);
assert_eq!(l,1);
assert_eq!(r,2);
a = 20;
let p = parent!(a);
assert_eq!(9,p);
}
#[test]
fn max_heap_operation() -> () {
let mut a: Heap<i32> = Heap::new(|a,b| a >= b);
a.push(60);
a.push(2);
a.push(30);
a.push(100);
let mut vec: Vec<i32> = vec!();
vec.push(100);
vec.push(60);
vec.push(30);
vec.push(2);
assert_eq!(a.items,vec);
}
#[test]
fn min_heap_operation() -> (){
let mut a: Heap<i32> = Heap::new(|a,b| a <= b);
a.push(60);
a.push(2);
a.push(30);
a.push(100);
a.push(1);
a.push(40);
let mut vec: Vec<i32> = vec!();
vec.push(1);
vec.push(2);
vec.push(30);
vec.push(100);
vec.push(60);
vec.push(40);
assert_eq!(a.items,vec);
}
#[test]
fn sort() -> () {
let mut a: Heap<i32> = Heap::new(|a,b| a>=b);
a.push(199); a.push(0); a.push(20); a.push(40);
a.sort();
assert_eq!(a.items,[0,20,40,199]);
}
}
5 changes: 5 additions & 0 deletions src/structure/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

mod heap;


pub use self::heap::*;

0 comments on commit 45ba00c

Please sign in to comment.