Skip to content

Commit 674fc62

Browse files
authored
Add CPP version of bubble sort (#540)
1 parent 0dabe35 commit 674fc62

File tree

5 files changed

+81
-3
lines changed

5 files changed

+81
-3
lines changed

pydatastructs/linear_data_structures/_backend/cpp/algorithms/algorithms.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#include <Python.h>
22
#include "quick_sort.hpp"
3+
#include "bubble_sort.hpp"
34

45
static PyMethodDef algorithms_PyMethodDef[] = {
56
{"quick_sort", (PyCFunction) quick_sort,
67
METH_VARARGS | METH_KEYWORDS, ""},
8+
{"bubble_sort", (PyCFunction) bubble_sort,
9+
METH_VARARGS | METH_KEYWORDS, ""},
710
{NULL, NULL, 0, NULL} /* Sentinel */
811
};
912

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef LINEAR_DATA_STRUCTURES_ALGORITHMS_BUBBLE_SORT_HPP
2+
#define LINEAR_DATA_STRUCTURES_ALGORITHMS_BUBBLE_SORT_HPP
3+
4+
#define PY_SSIZE_T_CLEAN
5+
#include <Python.h>
6+
#include "../arrays/OneDimensionalArray.hpp"
7+
#include "../arrays/DynamicOneDimensionalArray.hpp"
8+
#include "../../../../utils/_backend/cpp/utils.hpp"
9+
10+
static PyObject* bubble_sort_impl(PyObject* array, size_t lower, size_t upper,
11+
PyObject* comp, size_t arr_length) {
12+
for (size_t i = 0; i < arr_length - 1; i++) {
13+
for (size_t j = lower; j < upper; j++) {
14+
PyObject* j_PyObject = PyLong_FromSize_t(j);
15+
PyObject* j1_PyObject = PyLong_FromSize_t(j+1);
16+
if( _comp(PyObject_GetItem(array, j_PyObject),
17+
PyObject_GetItem(array, j1_PyObject), comp) != 1 ) {
18+
PyObject* tmp = PyObject_GetItem(array, j1_PyObject);
19+
PyObject_SetItem(array, j1_PyObject,
20+
PyObject_GetItem(array, j_PyObject));
21+
PyObject_SetItem(array, j_PyObject, tmp);
22+
}
23+
}
24+
}
25+
return array;
26+
}
27+
28+
29+
static PyObject* bubble_sort(PyObject* self, PyObject* args, PyObject* kwds) {
30+
PyObject *args0 = NULL, *start = NULL, *end = NULL;
31+
PyObject *comp = NULL, *pick_pivot_element = NULL;
32+
size_t lower, upper, arr_length;
33+
args0 = PyObject_GetItem(args, PyZero);
34+
int is_DynamicOneDimensionalArray = _check_type(args0, &DynamicOneDimensionalArrayType);
35+
int is_OneDimensionalArray = _check_type(args0, &OneDimensionalArrayType);
36+
if( !is_DynamicOneDimensionalArray && !is_OneDimensionalArray ) {
37+
raise_exception_if_not_array(args0);
38+
return NULL;
39+
}
40+
comp = PyObject_GetItem(kwds, PyUnicode_FromString("comp"));
41+
if( comp == NULL ) {
42+
PyErr_Clear();
43+
}
44+
start = PyObject_GetItem(kwds, PyUnicode_FromString("start"));
45+
if( start == NULL ) {
46+
PyErr_Clear();
47+
lower = 0;
48+
} else {
49+
lower = PyLong_AsSize_t(start);
50+
}
51+
end = PyObject_GetItem(kwds, PyUnicode_FromString("end"));
52+
if( end == NULL ) {
53+
PyErr_Clear();
54+
upper = PyObject_Length(args0) - 1;
55+
} else {
56+
upper = PyLong_AsSize_t(end);
57+
}
58+
arr_length = PyObject_Length(args0);
59+
60+
args0 = bubble_sort_impl(args0, lower, upper, comp, arr_length);
61+
if( is_DynamicOneDimensionalArray ) {
62+
PyObject_CallMethod(args0, "_modify", "O", Py_True);
63+
}
64+
Py_INCREF(args0);
65+
return args0;
66+
}
67+
68+
#endif

pydatastructs/linear_data_structures/algorithms.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,8 +1361,9 @@ def bubble_sort(array, **kwargs):
13611361
13621362
.. [1] https://en.wikipedia.org/wiki/Bubble_sort
13631363
"""
1364-
raise_if_backend_is_not_python(
1365-
bubble_sort, kwargs.get('backend', Backend.PYTHON))
1364+
backend = kwargs.pop("backend", Backend.PYTHON)
1365+
if backend == Backend.CPP:
1366+
return _algorithms.bubble_sort(array, **kwargs)
13661367
start = kwargs.get('start', 0)
13671368
end = kwargs.get('end', len(array) - 1)
13681369
comp = kwargs.get("comp", lambda u, v: u <= v)

pydatastructs/linear_data_structures/tests/benchmarks/test_algorithms.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import random, timeit, functools, os, pytest
22
from pydatastructs import (OneDimensionalArray, Backend,
3-
DynamicOneDimensionalArray, quick_sort)
3+
DynamicOneDimensionalArray, quick_sort, bubble_sort)
44

55
def _test_common_sort(sort, **kwargs):
66
cpp = Backend.CPP
@@ -34,3 +34,8 @@ def _common(array_type, dtype, *args, **kwargs):
3434
@pytest.mark.xfail
3535
def test_quick_sort():
3636
_test_common_sort(quick_sort, size=4000)
37+
38+
39+
@pytest.mark.xfail
40+
def test_bubble_sort():
41+
_test_common_sort(bubble_sort, size=2000)

pydatastructs/linear_data_structures/tests/test_algorithms.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def test_quick_sort():
117117

118118
def test_bubble_sort():
119119
_test_common_sort(bubble_sort)
120+
_test_common_sort(bubble_sort, backend=Backend.CPP)
120121

121122
def test_selection_sort():
122123
_test_common_sort(selection_sort)

0 commit comments

Comments
 (0)