Push Swap is a sorting algorithm project implemented in C, designed to efficiently sort a stack of integers with a limited set of stack operations. It follows the Turk Algorithm for optimal sorting efficiency. The purpose of the project is to print the exact sequence of steps the algorithm executes to sort the numbers successfully.
The current algorithm has a time complexity of O(N²) in the worst case and a space complexity of O(N) due to stack storage. This implementation is optimized for small stacks of numbers, meeting and surpassing the benchmark criteria for the assignment.
The repository consists of multiple source files, each responsible for a different aspect of the program:
📁 Push_swap/
│── 📁 lib/
│ ├── 📁 libft/ # Custom libft library submodule
│
│── 📁 include/
│ ├── push_swap.h # Header file defining structures and function prototypes
│
│── 📁 src/
│ ├── 📁 algorithm/ # Sorting algorithm logic
│ │ ├── alg_sorting.c
│ │ ├── alg_targetA.c
│ │ ├── alg_targetB.c
│ │ ├── alg_tools.c
│ │ ├── alg_utils.c
│ │ ├── alg_rotations.c
│ │
│ ├── 📁 commands/ # Stack operations (push, swap, rotate, reverse rotate)
│ │ ├── cmd_push.c
│ │ ├── cmd_swap.c
│ │ ├── cmd_rotate.c
│ │ ├── cmd_revrotate.c
│ │
│ ├── 📁 parsing/ # Stack initialization and parsing
│ │ ├── parsing.c
│ │ ├── set_stack.c
│ │ ├── sort_init.c
│ │
│ ├── 📁 utils/ # Utility functions
│ │ ├── utils.c
│ │ ├── validity.c
│ │ ├── free.c
│ │
│ ├── main.c # Main entry point
To compile the program, ensure you have Makefile
make
Run the program with a sequence of integers:
./push_swap 4 67 3 87 23
If the input is valid, the program prints a sequence of operations to sort the numbers using the fewest moves.
Defines the core t_node
structure for doubly linked lists and function prototypes.
typedef struct s_node {
int nbr;
int index;
int push_cost;
bool above_median;
bool cheapest;
struct s_node *target_node;
struct s_node *next;
struct s_node *prev;
} t_node;
-
main.c
- Calls
parsing_arguments()
to process user input. - Initializes stack A using
init_stack_a()
. - If already sorted, it exits.
- Otherwise, sorting is initiated using
sort_fine_tuning()
.
- Calls
-
parsing.c
- Handles single/multiple argument parsing, but not both at the same time.
- Uses
ft_split()
for space-separated input. - Calls
is_valid_integer()
to validate input.
-
set_stack.c
- Converts string input into stack A.
- Calls
append_node()
and checks for duplicates.
Implemented in alg_sorting.c
, which uses Turk Algorithm:
void sort_turk(t_node **a, t_node **b, int size)
- Pushes elements from A to B until only three remain.
- Sorts the remaining three using
sort_three()
. - Pushes elements back to A in sorted order.
Each node is assigned a target position before being pushed.
-
alg_targetA.c
init_nodes_a()
determines target nodes for stack A.
-
alg_targetB.c
init_nodes_b()
determines target nodes for stack B.
These functions ensure the most efficient movements.
Push Swap operations follow a standard structure:
pa()
: Push top element of B to A.pb()
: Push top element of A to B.
void pb(t_node **b, t_node **a) {
push(a, b);
ft_printf("pb\n");
}
sa()
: Swap top two elements of A.
void sa(t_node **a) {
swap(a);
ft_printf("sa\n");
}
ra()
: Rotate A (move first element to the end).rb()
: Rotate B.rr()
: Rotate both.
rra()
: Reverse rotate A (move last element to the top).rrb()
: Reverse rotate B.rrr()
: Reverse rotate both.
utils.c
provides helper functions:
find_max()
,find_min()
stack_size()
find_last()
alg_tools.c
and alg_utils.c
include:
set_cheapest()
: Marks the node with the lowest push cost.rotate_to_top()
: Moves the best node to the top.
To prevent memory leaks, free.c
deallocates all used memory:
free_stack()
free_args()
free_av_arr()
If an error is detected (e.g., invalid input, duplicates, sorted list), the program:
- Prints
"Error"
to STDERR. - Frees allocated memory.
- Exits gracefully.
Example (from free.c
):
void error_indicator(t_node **a) {
write(STDERR_FILENO, "Error\n", 6);
free_stack(a);
}
This project efficiently sorts integers with minimal operations, following the Turk Algorithm. The modular design ensures clarity, while the memory-safe implementation prevents leaks.
✅ Passed 100%: This project successfully met all performance benchmarks!
- Sorting 100 numbers in less than 700 steps (average: 550 steps).
- Sorting 500 numbers in less than 5500 operations (achieved: ~5000 steps).
This ensures an optimized implementation with efficient sorting operations.
This section tracks active bugs and areas of improvement if any.
- [Segmentation Fault]
Description: There is an issue with the free logic even though always I follow a cetralized architecture for memory managment, in case of inputing a single space in quotes the program seems to crash and not properly handle this empty case.
Status: In progress / Under investigation.
Potential Fixes: The parsing part seems causing this issue.
- Improve error handling and input validation/ Handle mixed format input.
- Improve architecture by seperating the headerfiles.