From 5d6fecafb58beb797979acce31e44d713e482862 Mon Sep 17 00:00:00 2001 From: kratik1237 Date: Mon, 15 Jul 2024 20:42:57 +0530 Subject: [PATCH] Add counting sort in the list of sorting techniques --- counting.css | 476 ++++++++++++++++++++++++++++++++++++++++++++++++++ counting.html | 262 +++++++++++++++++++++++++++ counting.js | 216 +++++++++++++++++++++++ index.html | 4 +- 4 files changed, 957 insertions(+), 1 deletion(-) create mode 100644 counting.css create mode 100644 counting.html create mode 100644 counting.js diff --git a/counting.css b/counting.css new file mode 100644 index 0000000..eb04461 --- /dev/null +++ b/counting.css @@ -0,0 +1,476 @@ + +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #f0f0f0; +} + +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 20px; + background-color: white; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.navbar-logo { + display: flex; + align-items: center; +} + +.logo { + width: 30px; + height: 30px; + margin-right: 10px; +} + +.brand-name { + font-size: 1.5rem; + font-weight: bold; + color: #db7fdb; + text-decoration: none; +} + +.navbar-menu { + display: flex; + list-style-type: none; + margin: 0; + padding: 0; +} + +.navbar-menu li { + margin-left: 20px; +} + +.navbar-menu a { + text-decoration: none; + color: #333; + font-weight: 500; +} + +.dropdown { + position: relative; +} + +.dropdown-content { + display: none; + position: absolute; + background-color: #f9f9f9; + min-width: 160px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; +} + +.dropdown:hover .dropdown-content { + display: block; +} + +.login-btn { + background-color: #db7fdb; + color: white; + padding: 8px 15px; + border-radius: 20px; + text-decoration: none; +} + +main { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +h1, h2 { + color: #db7fdb; +} + +.content-wrapper { + display: flex; + gap: 20px; +} + +.text-content, .visualization-content { + flex: 1; +} + +.algorithm-box { + background-color: #f4f4f4; + padding: 15px; + border-radius: 5px; + margin-bottom: 20px; +} + +.visualization-box { + background-color: white; + border: 2px solid #db7fdb; + border-radius: 5px; + padding: 20px; + text-align: center; +} + +.array-visualization { + display: flex; + justify-content: center; + gap: 10px; +} + +.array-visualization span { + display: inline-block; + padding: 10px; + background-color: #e8f5e9; + border-radius: 5px; +} + +.complexity-table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; +} + +.complexity-table th, .complexity-table td { + border: 1px solid #ddd; + padding: 8px; + text-align: left; +} + +.complexity-table th { + background-color: #f2f2f2; +} + +#counting-sort-visualizer { + margin-top: 30px; +} + +#visualizer-container { + height: 300px; + background-color: #f9f9f9; + border: 1px solid #ddd; + margin-bottom: 20px; +} + +#array-container { + display: flex; + justify-content: center; + align-items: flex-end; + height: 100%; +} + +.array-bar { + width: 30px; + background-color: #db7fdb; + margin: 0 2px; + transition: height 0.3s ease; +} + +#input-controls { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +#input-controls input, #input-controls button { + padding: 8px; +} + +#input-controls input { + flex-grow: 1; +} + +#input-controls button { + background-color: #db7fdb; + color: white; + border: none; + cursor: pointer; +} + +#counting-sort-code { + background-color: #f4f4f4; + padding: 20px; + border-radius: 5px; +} + +.code-tabs { + display: flex; + gap: 10px; + margin-bottom: 10px; +} + +.tab-btn { + background-color: #ddd; + border: none; + padding: 8px 15px; + cursor: pointer; +} + +.tab-btn.active { + background-color: #db7fdb; + color: white; +} + +#code-display { + background-color: #333; + color: #fff; + padding: 15px; + border-radius: 5px; + overflow-x: auto; +} + +#practice-questions table { + width: 100%; + border-collapse: collapse; +} + +#practice-questions th, #practice-questions td { + border: 1px solid #ddd; + padding: 8px; + text-align: left; +} + +#practice-questions th { + background-color: #f2f2f2; +} + +/* New footer styles */ +footer.container { + background-color: #f8f9fa; + color: #6c757d; + padding: 4rem 1rem; + border-top: 1px solid #e9ecef; +} + +footer .row { + margin-bottom: 2rem; +} + +footer h5 { + font-size: 1.25rem; + margin-bottom: 1rem; +} + +footer ul { + list-style: none; + padding: 0; +} + +footer a { + color: #6c757d; + text-decoration: none; + transition: color 0.2s ease-in-out; +} + +footer a:hover { + color: #007bff; +} + +footer .nav-link { + padding: 0.2rem 0; +} + +/* Newsletter subscription form styles */ +footer form { + text-align: center; +} + +footer form h5 { + font-size: 1.5rem; + margin-bottom: 0.5rem; + color: #343a40; +} + +footer form p { + font-size: 1rem; + margin-bottom: 1rem; + color: #6c757d; +} + +footer form .form-control { + width: 60%; + margin-right: 0.5rem; +} + +footer form .btn-primary { + background-color: #007bff; + border: none; +} + +footer form .btn-primary:hover { + background-color: #0056b3; +} + +/* Social media icons */ +footer .icons { + display: flex; + justify-content: center; + gap: 1rem; + margin-top: 1rem; +} + +footer .icons a { + color: #6c757d; + font-size: 1.5rem; + transition: color 0.2s ease-in-out; +} + +footer .icons a:hover { + color: #007bff; +} + +/* Legal section styles */ +footer .foot { + text-align: center; + margin-top: 2rem; +} + +footer .foot .d-flex { + flex-direction: column; +} + +footer .foot p { + margin: 0; +} + +/* Back to top button */ +#topbtn { + position: fixed; + bottom: 2rem; + right: 2rem; + display: none; +} + +.gotopbtn { + background-color: #007bff; + color: #fff; + border: none; + padding: 0.5rem; + border-radius: 0.25rem; + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +.gotopbtn:hover { + background-color: #0056b3; +} + +/* Make back to top button visible */ +#topbtn.show { + display: block; +} + +/* Utility classes */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 15px; +} + +.row { + display: flex; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.col-md-6, .col-md-4, .col-6, .col-md-2 { + position: relative; + width: 100%; + padding-right: 15px; + padding-left: 15px; +} + +.mb-3 { + margin-bottom: 1rem; +} + +.mt-5 { + margin-top: 3rem; +} + +h5 { + font-size: 1.25rem; + margin-bottom: 0.5rem; + font-weight: 500; + color: #212529; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.footer-title { + font-size: 1 + +.5rem; + font-weight: bold; + color: #212529; + text-decoration: none; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; + text-decoration: none; + color: #6c757d; +} + +.text-body-secondary { + color: #6c757d; +} + +.border-top { + border-top: 1px solid #dee2e6; +} + +.py-4 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.my-4 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; +} +.footer-column { + width: 12.5%; /* Adjust the percentage as needed */ + flex: 0 0 12.5%; + max-width: 12.5%; +} + + +@media (min-width: 768px) { + .col-md-6 { + flex: 0 0 50%; + max-width: 50%; + } + + .col-md-4 { + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + + .col-md-2 { + flex: 0 0 16.666667%; + max-width: 16.666667%; + } +} \ No newline at end of file diff --git a/counting.html b/counting.html new file mode 100644 index 0000000..409ad9b --- /dev/null +++ b/counting.html @@ -0,0 +1,262 @@ + + + + + + Counting Sort Visualizer + + + + + + + +
+
+
+

Counting Sort

+
+
+

Counting Sort is a non-comparison-based sorting algorithm that works well when there is a limited range of input values. It is particularly efficient when the range of input values is small compared to the number of elements to be sorted. The basic idea behind Counting Sort is to count the frequency of each distinct element in the input array and use that information to place the elements in their correct sorted positions.

+ +
+

Algorithm:

+
    +
  1. Find the range of the input array (minimum and maximum elements).
  2. +
  3. Create a count array to store the count of each unique object.
  4. +
  5. Store the count of each unique object in the count array.
  6. +
  7. Modify the count array by storing the actual position of each object in the output array.
  8. +
  9. Build the output array using the modified count array and the original input array.
  10. +
  11. Copy the sorted elements into the original array.
  12. +
+
+
+
+
+
+ 2 + 5 + 4 + 6 + 1 + 3 +
+
+ + + + + + + + + + + + + +
Complexity
Time Complexity (Best, Average, Worst)O(n + k)
Space ComplexityO(k)
+

Where n is the number of elements in the input array and k is the range of input.

+
+
+
+ + +
+
+

Counting Sort Visualizer

+
+
+
+
+ + + + + + + +
+
+
+

Counting Sort Code

+
+ + + + +
+

+        
+ +
+

Practice Questions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Question NumberQuestion TitleLevelLink
1Sort an ArrayEasyLink
2Sort Characters By FrequencyMediumLink
3Largest NumberHardLink
+
+
+ + + + + + + + \ No newline at end of file diff --git a/counting.js b/counting.js new file mode 100644 index 0000000..a88f374 --- /dev/null +++ b/counting.js @@ -0,0 +1,216 @@ +// DOM elements +const arrayContainer = document.getElementById('array-container'); +const arrayInput = document.getElementById('input-numbers'); +const submitBtn = document.getElementById('submit'); +const startBtn = document.getElementById('start-sort'); +const stopBtn = document.getElementById('stop'); +const resumeBtn = document.getElementById('resume'); +const resetBtn = document.getElementById('reset'); +const clearBtn = document.getElementById('clear'); +const codeDisplay = document.getElementById('code-display'); + +// Variables +let array = []; +let sorting = false; +let paused = false; + +// Event listeners +submitBtn.addEventListener('click', submitArray); +startBtn.addEventListener('click', startSort); +stopBtn.addEventListener('click', stopSort); +resumeBtn.addEventListener('click', resumeSort); +resetBtn.addEventListener('click', resetArray); +clearBtn.addEventListener('click', clearArray); + +// Tab buttons event listeners +document.querySelectorAll('.tab-btn').forEach(button => { + button.addEventListener('click', () => { + document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); + button.classList.add('active'); + displayCode(button.getAttribute('data-lang')); + }); +}); + +function submitArray() { + const input = arrayInput.value.trim().split(/\s+/).map(Number); + if (input.some(isNaN)) { + alert('Please enter valid numbers'); + return; + } + array = input; + displayArray(); +} + +function displayArray() { + arrayContainer.innerHTML = ''; + const max = Math.max(...array); + array.forEach(num => { + const bar = document.createElement('div'); + bar.className = 'array-bar'; + bar.style.height = `${(num / max) * 100}%`; + bar.style.width = `${100 / array.length}%`; + arrayContainer.appendChild(bar); + }); +} + +async function countingSort() { + const max = Math.max(...array); + const count = new Array(max + 1).fill(0); + const output = new Array(array.length); + + for (let i = 0; i < array.length; i++) { + if (paused) await new Promise(resolve => resumeBtn.onclick = () => { paused = false; resolve(); }); + count[array[i]]++; + updateBar(i, 'red'); + await sleep(100); + } + + for (let i = 1; i <= max; i++) { + if (paused) await new Promise(resolve => resumeBtn.onclick = () => { paused = false; resolve(); }); + count[i] += count[i - 1]; + await sleep(50); + } + + for (let i = array.length - 1; i >= 0; i--) { + if (paused) await new Promise(resolve => resumeBtn.onclick = () => { paused = false; resolve(); }); + output[count[array[i]] - 1] = array[i]; + count[array[i]]--; + updateBar(i, 'green'); + await sleep(100); + } + + for (let i = 0; i < array.length; i++) { + if (paused) await new Promise(resolve => resumeBtn.onclick = () => { paused = false; resolve(); }); + array[i] = output[i]; + updateBar(i, 'blue'); + await sleep(100); + } + + sorting = false; +} + +function updateBar(index, color) { + arrayContainer.children[index].style.backgroundColor = color; +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +function startSort() { + if (!sorting) { + sorting = true; + paused = false; + countingSort(); + } +} + +function stopSort() { + paused = true; +} + +function resumeSort() { + paused = false; +} + +function resetArray() { + sorting = false; + paused = false; + displayArray(); +} + +function clearArray() { + array = []; + arrayContainer.innerHTML = ''; + arrayInput.value = ''; +} + +function displayCode(lang) { + const codes = { + java: `public void countingSort(int[] arr) { + int max = Arrays.stream(arr).max().getAsInt(); + int min = Arrays.stream(arr).min().getAsInt(); + int range = max - min + 1; + int count[] = new int[range]; + int output[] = new int[arr.length]; + for (int i = 0; i < arr.length; i++) { + count[arr[i] - min]++; + } + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + for (int i = arr.length - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + for (int i = 0; i < arr.length; i++) { + arr[i] = output[i]; + } +}`, + c: `void countingSort(int arr[], int n) { + int max = arr[0]; + for (int i = 1; i < n; i++) { + if (arr[i] > max) + max = arr[i]; + } + int count[max + 1]; + int output[n]; + memset(count, 0, sizeof(count)); + for (int i = 0; i < n; i++) + count[arr[i]]++; + for (int i = 1; i <= max; i++) + count[i] += count[i - 1]; + for (int i = n - 1; i >= 0; i--) { + output[count[arr[i]] - 1] = arr[i]; + count[arr[i]]--; + } + for (int i = 0; i < n; i++) + arr[i] = output[i]; +}`, + cpp: `void countingSort(vector& arr) { + int max = *max_element(arr.begin(), arr.end()); + int min = *min_element(arr.begin(), arr.end()); + int range = max - min + 1; + vector count(range), output(arr.size()); + for (int i = 0; i < arr.size(); i++) + count[arr[i] - min]++; + for (int i = 1; i < count.size(); i++) + count[i] += count[i - 1]; + for (int i = arr.size() - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + for (int i = 0; i < arr.size(); i++) + arr[i] = output[i]; +}`, + python: `def counting_sort(arr): + max_element = max(arr) + min_element = min(arr) + range_of_elements = max_element - min_element + 1 + count_arr = [0 for _ in range(range_of_elements)] + output_arr = [0 for _ in range(len(arr))] + + for i in range(0, len(arr)): + count_arr[arr[i]-min_element] += 1 + + for i in range(1, len(count_arr)): + count_arr[i] += count_arr[i-1] + + i = len(arr)-1 + while i >= 0: + output_arr[count_arr[arr[i] - min_element] - 1] = arr[i] + count_arr[arr[i] - min_element] -= 1 + i -= 1 + + for i in range(0, len(arr)): + arr[i] = output_arr[i] + + return arr` + }; + + codeDisplay.textContent = codes[lang] || 'Code not available for this language'; +} + +// Initial display +displayArray(); +displayCode('java'); \ No newline at end of file diff --git a/index.html b/index.html index 2e313b2..8e9a76f 100644 --- a/index.html +++ b/index.html @@ -111,6 +111,7 @@
  • Merge Sort
  • Heap Sort
  • Quick Sort
  • +
  • Counting Sort
  • @@ -134,7 +135,8 @@
  • Merge Sort
  • Heap Sort
  • Quick Sort
  • - +
  • Counting Sort
  • +