Skip to content

Commit

Permalink
Add CPP version of bubble sort (#540)
Browse files Browse the repository at this point in the history
  • Loading branch information
sak-codes committed Jul 11, 2023
1 parent 0dabe35 commit 674fc62
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include <Python.h>
#include "quick_sort.hpp"
#include "bubble_sort.hpp"

static PyMethodDef algorithms_PyMethodDef[] = {
{"quick_sort", (PyCFunction) quick_sort,
METH_VARARGS | METH_KEYWORDS, ""},
{"bubble_sort", (PyCFunction) bubble_sort,
METH_VARARGS | METH_KEYWORDS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#ifndef LINEAR_DATA_STRUCTURES_ALGORITHMS_BUBBLE_SORT_HPP
#define LINEAR_DATA_STRUCTURES_ALGORITHMS_BUBBLE_SORT_HPP

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "../arrays/OneDimensionalArray.hpp"
#include "../arrays/DynamicOneDimensionalArray.hpp"
#include "../../../../utils/_backend/cpp/utils.hpp"

static PyObject* bubble_sort_impl(PyObject* array, size_t lower, size_t upper,
PyObject* comp, size_t arr_length) {
for (size_t i = 0; i < arr_length - 1; i++) {
for (size_t j = lower; j < upper; j++) {
PyObject* j_PyObject = PyLong_FromSize_t(j);
PyObject* j1_PyObject = PyLong_FromSize_t(j+1);
if( _comp(PyObject_GetItem(array, j_PyObject),
PyObject_GetItem(array, j1_PyObject), comp) != 1 ) {
PyObject* tmp = PyObject_GetItem(array, j1_PyObject);
PyObject_SetItem(array, j1_PyObject,
PyObject_GetItem(array, j_PyObject));
PyObject_SetItem(array, j_PyObject, tmp);
}
}
}
return array;
}


static PyObject* bubble_sort(PyObject* self, PyObject* args, PyObject* kwds) {
PyObject *args0 = NULL, *start = NULL, *end = NULL;
PyObject *comp = NULL, *pick_pivot_element = NULL;
size_t lower, upper, arr_length;
args0 = PyObject_GetItem(args, PyZero);
int is_DynamicOneDimensionalArray = _check_type(args0, &DynamicOneDimensionalArrayType);
int is_OneDimensionalArray = _check_type(args0, &OneDimensionalArrayType);
if( !is_DynamicOneDimensionalArray && !is_OneDimensionalArray ) {
raise_exception_if_not_array(args0);
return NULL;
}
comp = PyObject_GetItem(kwds, PyUnicode_FromString("comp"));
if( comp == NULL ) {
PyErr_Clear();
}
start = PyObject_GetItem(kwds, PyUnicode_FromString("start"));
if( start == NULL ) {
PyErr_Clear();
lower = 0;
} else {
lower = PyLong_AsSize_t(start);
}
end = PyObject_GetItem(kwds, PyUnicode_FromString("end"));
if( end == NULL ) {
PyErr_Clear();
upper = PyObject_Length(args0) - 1;
} else {
upper = PyLong_AsSize_t(end);
}
arr_length = PyObject_Length(args0);

args0 = bubble_sort_impl(args0, lower, upper, comp, arr_length);
if( is_DynamicOneDimensionalArray ) {
PyObject_CallMethod(args0, "_modify", "O", Py_True);
}
Py_INCREF(args0);
return args0;
}

#endif
5 changes: 3 additions & 2 deletions pydatastructs/linear_data_structures/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1361,8 +1361,9 @@ def bubble_sort(array, **kwargs):
.. [1] https://en.wikipedia.org/wiki/Bubble_sort
"""
raise_if_backend_is_not_python(
bubble_sort, kwargs.get('backend', Backend.PYTHON))
backend = kwargs.pop("backend", Backend.PYTHON)
if backend == Backend.CPP:
return _algorithms.bubble_sort(array, **kwargs)
start = kwargs.get('start', 0)
end = kwargs.get('end', len(array) - 1)
comp = kwargs.get("comp", lambda u, v: u <= v)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import random, timeit, functools, os, pytest
from pydatastructs import (OneDimensionalArray, Backend,
DynamicOneDimensionalArray, quick_sort)
DynamicOneDimensionalArray, quick_sort, bubble_sort)

def _test_common_sort(sort, **kwargs):
cpp = Backend.CPP
Expand Down Expand Up @@ -34,3 +34,8 @@ def _common(array_type, dtype, *args, **kwargs):
@pytest.mark.xfail
def test_quick_sort():
_test_common_sort(quick_sort, size=4000)


@pytest.mark.xfail
def test_bubble_sort():
_test_common_sort(bubble_sort, size=2000)
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def test_quick_sort():

def test_bubble_sort():
_test_common_sort(bubble_sort)
_test_common_sort(bubble_sort, backend=Backend.CPP)

def test_selection_sort():
_test_common_sort(selection_sort)
Expand Down

0 comments on commit 674fc62

Please sign in to comment.