Welcome back to my journey through the CS50 Introduction to Computer Science course! Week 3 has been a fascinating exploration into the world of algorithms and sorting techniques. Let's delve into the key highlights and concepts that I've encountered.

Understanding Algorithms: The Building Blocks of Problem Solving
Algorithms serve as the backbone of problem-solving in computer science. They are systematic step-by-step procedures designed to tackle various computational tasks. During this week's lectures, I gained a deeper understanding of how algorithms can be expressed both in pseudocode and implemented in code.
Unveiling Linear Search: A Fundamental Search Algorithm
Linear search emerged as a fundamental search algorithm, characterized by its simplicity. It sequentially traverses each item in a list until finding the target item. This method, though straightforward, laid the groundwork for comprehending more complex search algorithms.
Discovering the Efficiency of Binary Search
One of the highlights of this week was exploring binary search, a more efficient alternative for searching sorted lists. By systematically dividing the search space in half at each step, binary search significantly reduces the number of comparisons required to find the target element.

Decoding Running Time and Big O Notation
In understanding the efficiency of algorithms, we delved into the realm of running time analysis and Big O notation. This mathematical notation provides insights into an algorithm's time complexity, offering a measure of its scalability as input size grows. Concepts like O(n) and O(log n) became integral in evaluating algorithmic performance.
Implementation with Search.c: Putting Theory into Practice
Putting theory into practice, we implemented linear search in the C programming language through the 'search.c' example. This hands-on experience solidified my understanding of searching algorithms, demonstrating their application in real-world scenarios.

Embracing Data Structures: Introducing Structs in C
The introduction of structs in C provided a gateway to creating custom data types, offering a structured approach to organizing and manipulating data. Building upon this foundation, we explored the concept of data structures and their significance in algorithm design.
Unveiling Sorting Algorithms: From Selection Sort to Merge Sort
Sorting algorithms emerged as a pivotal topic, essential for organizing unsorted data efficiently. While we explored simple sorting methods like Selection Sort and Bubble Sort, the spotlight shone brightly on Merge Sort. This recursive sorting algorithm showcased the elegance and efficiency of divide-and-conquer techniques.

Embracing Recursion: A Powerful Programming Technique
Recursion captivated my interest as a powerful programming technique employed in various algorithms. We jumped into recursion not only through theoretical explanations but also through hands-on exercises. One such exercise involved writing a recursive function called "collatz," where we explored the Collatz conjecture. This exercise provided firsthand experience in applying recursion to solve real-world problems. From crafting recursive solutions to traversing data structures, recursion showcased its elegance and simplicity, enriching my understanding of algorithmic design and problem-solving strategies.
Here is my take on this exercise:
#include <stdio.h>
#include <cs50.h>
// Recursion Excersise, follow these steps:
//// If 'n' is 1, stop.
//// otherwise, if 'n' is even, repeat this process on n/2.
//// otherwise, if 'n' is odd, repeat this process on 3n + 1.
//
//// Write a recursive function collatz(n) that calculates
//// how many steps it takes to get to 1 if you start from n.
// Recursive function to calculate Collatz conjecture steps
int collatz(int n);
////////////////////////////////
int main(void)
{
// Get a positive integer from the user
int n;
do
{
n = get_int("Please choose a whole, positive number: ");
}
// Check for negative numbers
while (n < 1);
// Call the collatz function to calculate steps
int steps = collatz(n);
// Print the result
printf("Following the rules, it took %i steps to return to 1 from %i\n", steps, n);
return 0;
}
// Recursive function to calculate Collatz conjecture steps
int collatz(int n)
{
// Base case: if n is 1, return 0 steps
if (n == 1)
{
return 0;
}
// If n is even, divide it by 2 and recursively call collatz
else if (n % 2 == 0)
{
return 1 + collatz(n / 2);
}
// If n is odd, multiply it by 3 and add 1, then recursively call collatz
else
{
return 1 + collatz(3 * n + 1);
}
}
Summing Up: Recapitulating Key Concepts
As we draw this week's exploration to a close, it's imperative to recapitulate the key concepts covered. From algorithms and Big O notation to search and sorting techniques, recursion, and data structures, Week 3 has equipped me with a solid foundation in fundamental computer science principles.
In conclusion, Week 3 of the CS50 course has been an enriching journey through the intricacies of algorithms and sorting. With a newfound appreciation for the efficiency and elegance of algorithms, I eagerly anticipate the challenges and discoveries that lie ahead in my CS50 adventure. Until next time!