Merge remote-tracking branch 'upstream/master' into gnome_sort

This commit is contained in:
Krishna Vedala
2020-07-17 19:59:04 -04:00
333 changed files with 52811 additions and 10006 deletions

6
.clang-tidy Normal file
View File

@@ -0,0 +1,6 @@
---
Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*'
WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*,-cppcoreguidelines-owning-memory,-clang-analyzer-cplusplus.Move'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }'

View File

@@ -3,19 +3,19 @@
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/TheAlgorithms/C-Plus-Plus/CONTRIBUTION.md
Contributors guide: https://github.com/TheAlgorithms/C-Plus-Plus/CONTRIBUTING.md
-->
#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
- [ ] Added description of change
- [ ] Added file name matches [File name guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTION.md#New-File-Name-guidelines)
- [ ] Added file name matches [File name guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#New-File-Name-guidelines)
- [ ] Added tests and example, test must pass
- [ ] Added documentation so that the program is self-explanatory and educational - [Doxygen guidelines](https://www.doxygen.nl/manual/docblocks.html)
- [ ] Relevant documentation/comments is changed or added
- [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTION.md#Commit-Guidelines)
- [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#Commit-Guidelines)
- [ ] Search previous suggestions before making a new one, as yours may be a duplicate.
- [ ] Sort by alphabetical order
- [ ] I acknowledge that all my contributions will be made under the project's license.
Notes: <!-- Please add a one-line description for developers or pull request viewers -->

173
.github/workflows/awesome_workflow.yml vendored Normal file
View File

@@ -0,0 +1,173 @@
name: Awesome CI Workflow
on: [push, pull_request]
# push:
# branches: [ master ]
# pull_request:
# branches: [ master ]
jobs:
MainSequence:
name: Code Formatter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1 # v2 is broken for git diff
- uses: actions/setup-python@v2
- name: requirements
run: |
sudo apt -qq -y update
sudo apt -qq install clang-tidy-10
# checks are passing with less errors when used with this version.
# The default installs v6.0 which did not work out well in my tests
- name: Setup Git Specs
run: |
git config --global user.name github-actions
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
- name: Filename Formatter
run: |
IFS=$'\n'
for fname in `find . -type f -name '*.cpp' -o -name '*.cc' -o -name '*.h'`
do
echo "${fname}"
new_fname=`echo ${fname} | tr ' ' '_'`
echo " ${new_fname}"
new_fname=`echo ${new_fname} | tr 'A-Z' 'a-z'`
echo " ${new_fname}"
new_fname=`echo ${new_fname} | tr '-' '_'`
echo " ${new_fname}"
new_fname=${new_fname/.cc/.cpp}
echo " ${new_fname}"
if [ ${fname} != ${new_fname} ]
then
echo " ${fname} --> ${new_fname}"
git "mv" "${fname}" ${new_fname}
fi
done
git commit -am "formatting filenames $GITHUB_SHA" || true
- name: Update DIRECTORY.md
shell: python
run: |
import os
from typing import Iterator
URL_BASE = "https://github.com/TheAlgorithms/C-Plus-Plus/blob/master"
g_output = []
def good_filepaths(top_dir: str = ".") -> Iterator[str]:
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
for dirpath, dirnames, filenames in os.walk(top_dir):
dirnames[:] = [d for d in dirnames if d[0] not in "._"]
for filename in filenames:
if os.path.splitext(filename)[1].lower() in cpp_exts:
yield os.path.join(dirpath, filename).lstrip("./")
def md_prefix(i):
return f"{i * ' '}*" if i else "\n##"
def print_path(old_path: str, new_path: str) -> str:
global g_output
old_parts = old_path.split(os.sep)
for i, new_part in enumerate(new_path.split(os.sep)):
if i + 1 > len(old_parts) or old_parts[i] != new_part:
if new_part:
g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}")
return new_path
def build_directory_md(top_dir: str = ".") -> str:
global g_output
old_path = ""
for filepath in sorted(good_filepaths(), key=str.lower):
filepath, filename = os.path.split(filepath)
if filepath != old_path:
old_path = print_path(old_path, filepath)
indent = (filepath.count(os.sep) + 1) if filepath else 0
url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20")
filename = os.path.splitext(filename.replace("_", " ").title())[0]
g_output.append(f"{md_prefix(indent)} [{filename}]({url})")
return "# List of all files\n" + "\n".join(g_output)
with open("DIRECTORY.md", "w") as out_file:
out_file.write(build_directory_md(".") + "\n")
- name: Commit DIRECTORY.md
run: git commit -m "updating DIRECTORY.md" DIRECTORY.md || true
- name: Get file changes
run: |
git remote -v
git branch
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git diff --diff-filter=dr --name-only origin/master > git_diff.txt
echo "Files changed-- `cat git_diff.txt`"
- name: Configure for static lint checks
# compiling first gives clang-tidy access to all the header files and settings used to compile the programs.
# This will check for macros, if any, on linux and not for Windows. But the use of portability checks should
# be able to catch any errors for other platforms.
run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Lint modified files
shell: python
run: |
import os
import subprocess
import sys
print("Python {}.{}.{}".format(*sys.version_info)) # Python 3.8
with open("git_diff.txt") as in_file:
modified_files = sorted(in_file.read().splitlines())
print("{} files were modified.".format(len(modified_files)))
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
cpp_files = [file for file in modified_files if file.lower().endswith(cpp_exts)]
print(f"{len(cpp_files)} C++ files were modified.")
if not cpp_files:
sys.exit(0)
subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-arg=-std=c++11", *cpp_files, "--"],
check=True, text=True, stderr=subprocess.STDOUT)
# for cpp_file in cpp_files:
# subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"],
# check=True, text=True, stderr=subprocess.STDOUT)
# print("g++:")
# compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split())
# compile_files = [file for file in cpp_files if file.lower().endswith(compile_exts)]
# for cpp_file in cpp_files:
# subprocess.run(["g++", cpp_file], check=True, text=True)
upper_files = [file for file in cpp_files if file != file.lower()]
if upper_files:
print(f"{len(upper_files)} files contain uppercase characters:")
print("\n".join(upper_files) + "\n")
space_files = [file for file in cpp_files if " " in file or "-" in file]
if space_files:
print(f"{len(space_files)} files contain space or dash characters:")
print("\n".join(space_files) + "\n")
nodir_files = [file for file in cpp_files if file.count(os.sep) != 1]
if nodir_files:
print(f"{len(nodir_files)} files are not in one and only one directory:")
print("\n".join(nodir_files) + "\n")
bad_files = len(upper_files + space_files + nodir_files)
if bad_files:
sys.exit(bad_files)
- name: Commit and push changes
run: |
git diff DIRECTORY.md
git commit -am "clang-tidy fixes for $GITHUB_SHA" || true
git push --force origin HEAD:$GITHUB_REF || true
build:
name: Compile checks
runs-on: ${{ matrix.os }}
needs: [MainSequence]
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@master
with:
submodules: true
- run: cmake -B ./build -S .
- run: cmake --build build

View File

@@ -1,13 +0,0 @@
name: cpplint
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
- run: pip install cpplint
# - run: cpplint --filter= # print out all cpplint rules
- run: cpplint --recursive . || true # all issues to be fixed
# TODO: Remove each filter one at a time and fix those failures
- run: cpplint --filter=-build,-legal,-readability,-runtime,-whitespace --recursive .

View File

@@ -1,64 +0,0 @@
# GitHub Action that enables a repo to achieve gradual compliance with cpplint by
# linting only those files that have been added or modified (vs. origin/master).
# 1. runs cpplint only on those files that have been modified vs. origin/master.
# 2. compiles with g++ only those files that have been modified vs. origin/master.
# 3. other optional filepath verifications may be commented out at the end of this file.
# From: https://github.com/cpplint/GitHub-Action-for-cpplint
name: cpplint_modified_files
on: [push, pull_request]
jobs:
cpplint_modified_files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1 # v2 is broken for git diff
- uses: actions/setup-python@v1
- run: python -m pip install cpplint
- run: git remote -v
- run: git branch
- run: git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
- run: git diff --diff-filter=dr --name-only origin/master > git_diff.txt
- name: cpplint_modified_files
shell: python
run: |
import os
import subprocess
import sys
print("Python {}.{}.{}".format(*sys.version_info)) # Python 3.8
with open("git_diff.txt") as in_file:
modified_files = sorted(in_file.read().splitlines())
print("{} files were modified.".format(len(modified_files)))
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
cpp_files = [file for file in modified_files if file.lower().endswith(cpp_exts)]
print(f"{len(cpp_files)} C++ files were modified.")
if not cpp_files:
sys.exit(0)
print("cpplint:")
subprocess.run(["cpplint", "--filter=-legal/copyright"] + cpp_files, check=True, text=True)
print("g++:")
# compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split())
# compile_files = [file for file in cpp_files if file.lower().endswith(compile_exts)]
subprocess.run(["g++"] + cpp_files, check=True, text=True)
upper_files = [file for file in cpp_files if file != file.lower()]
if upper_files:
print(f"{len(upper_files)} files contain uppercase characters:")
print("\n".join(upper_files) + "\n")
space_files = [file for file in cpp_files if " " in file or "-" in file]
if space_files:
print(f"{len(space_files)} files contain space or dash characters:")
print("\n".join(space_files) + "\n")
nodir_files = [file for file in cpp_files if file.count(os.sep) != 1]
if nodir_files:
print(f"{len(nodir_files)} files are not in one and only one directory:")
print("\n".join(nodir_files) + "\n")
bad_files = len(upper_files + space_files + nodir_files)
if bad_files:
sys.exit(bad_files)

36
.github/workflows/gh-pages.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: Doxygen CI
on:
push:
branches: [master]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@master
with:
submodules: true
- name: Install requirements
run: |
brew install graphviz ninja doxygen
- name: configure
run: cmake -G Ninja -B ./build -S .
- name: build
run: cmake --build build -t doc
- name: gh-pages
uses: actions/checkout@master
with:
ref: "gh-pages"
clean: false
- name: Move & Commit files
run: |
git config --global user.name github-actions
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
rm -rf d* && rm *.html && rm *.svg && rm *.map && rm *.md5 && rm *.png && rm *.js && rm *.css
git add .
cp -rp ./build/html/* . && rm -rf ./build && ls -lah
git add .
git commit -m "Documentation for $GITHUB_SHA" || true
git push --force || true

View File

@@ -1,24 +0,0 @@
name: sorting_non_recursive_merge_sort
on:
pull_request:
push:
# branches: [master]
jobs:
sorting_non_recursive_merge_sort:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: mattnotmitt/doxygen-action@master
with:
working-directory: 'sorting/'
doxyfile-path: 'doxy.txt'
#- uses: peaceiris/actions-gh-pages@v3
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: ./sorting
# external_repository: TheAlgorithms/C-Plus-Plus
# publish_branch: master
# enable_jekyll: true
- run: |
cd sorting
make test

View File

@@ -1,68 +0,0 @@
# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push
name: update_directory_md
on: [push]
jobs:
update_directory_md:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- name: update_directory_md
shell: python
run: |
import os
from typing import Iterator
URL_BASE = "https://github.com/TheAlgorithms/C-Plus-Plus/blob/master"
g_output = []
def good_filepaths(top_dir: str = ".") -> Iterator[str]:
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
for dirpath, dirnames, filenames in os.walk(top_dir):
dirnames[:] = [d for d in dirnames if d[0] not in "._"]
for filename in filenames:
if os.path.splitext(filename)[1].lower() in cpp_exts:
yield os.path.join(dirpath, filename).lstrip("./")
def md_prefix(i):
return f"{i * ' '}*" if i else "\n##"
def print_path(old_path: str, new_path: str) -> str:
global g_output
old_parts = old_path.split(os.sep)
for i, new_part in enumerate(new_path.split(os.sep)):
if i + 1 > len(old_parts) or old_parts[i] != new_part:
if new_part:
g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}")
return new_path
def build_directory_md(top_dir: str = ".") -> str:
global g_output
old_path = ""
for filepath in sorted(good_filepaths(), key=str.lower):
filepath, filename = os.path.split(filepath)
if filepath != old_path:
old_path = print_path(old_path, filepath)
indent = (filepath.count(os.sep) + 1) if filepath else 0
url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20")
filename = os.path.splitext(filename.replace("_", " ").title())[0]
g_output.append(f"{md_prefix(indent)} [{filename}]({url})")
return "\n".join(g_output)
with open("DIRECTORY.md", "w") as out_file:
out_file.write(build_directory_md(".") + "\n")
- name: Update DIRECTORY.md
run: |
cat DIRECTORY.md
git config --global user.name github-actions
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git add DIRECTORY.md
git commit -am "updating DIRECTORY.md" || true
git push --force origin HEAD:$GITHUB_REF || true

2
.gitignore vendored
View File

@@ -33,3 +33,5 @@
a.out
*.out
*.app
build/

9
.gitpod.dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM gitpod/workspace-full-vnc
RUN sudo apt-get update \
&& sudo apt-get install -y \
doxygen \
graphviz \
ninja-build \
&& pip install cpplint \
&& sudo rm -rf /var/lib/apt/lists/*

18
.gitpod.yml Normal file
View File

@@ -0,0 +1,18 @@
image:
file: .gitpod.dockerfile
github:
prebuilds:
addBadge: true
addComment: false
addCheck: false
master: true
branches: true
pullRequestsFromForks: true
vscode:
extensions:
- ms-vscode.cpptools@0.28.3:mjRj37VUK0nY2ZeDXzxOJA==
- twxs.cmake@0.0.17:9s7m9CWOr6i6NZ7CNNF4kw==
- ms-vscode.cmake-tools@1.4.0:eP3hU/MFme+CcSL21Klk1w==
- mhutchie.git-graph@1.23.0:TM9ShNmBn94aUJMJusCJlg==

69
.vscode/settings.json vendored
View File

@@ -1,71 +1,6 @@
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"cfenv": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"csetjmp": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cuchar": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"memory": "cpp",
"mutex": "cpp",
"new": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"scoped_allocator": "cpp",
"shared_mutex": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"thread": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"valarray": "cpp",
"algorithm": "cpp"
},
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 80, UseTab: Never}",
"C_Cpp.clang_format_style": "{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }",
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.formatOnPaste": true
}
}

89
CMakeLists.txt Normal file
View File

@@ -0,0 +1,89 @@
cmake_minimum_required(VERSION 3.9)
project(Algorithms_in_C++
LANGUAGES CXX
VERSION 1.0.0
DESCRIPTION "Set of algorithms implemented in C++."
)
# set(CMAKE_CXX_CPPLINT "~/anaconda3/bin/cpplint --filter=-legal/copyright --std=c++11")
# find_program(CLANG_FORMAT "clang-format")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(MSVC)
# set(CMAKE_CXX_STANDARD 14)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
option(USE_OPENMP "flag to use OpenMP for multithreading" ON)
if(USE_OPENMP)
find_package(OpenMP)
if (OpenMP_CXX_FOUND)
message(STATUS "Building with OpenMP Multithreading.")
else()
message(STATUS "No OpenMP found, no multithreading.")
endif()
endif()
add_subdirectory(math)
add_subdirectory(others)
add_subdirectory(search)
add_subdirectory(ciphers)
add_subdirectory(strings)
add_subdirectory(sorting)
add_subdirectory(geometry)
add_subdirectory(graphics)
add_subdirectory(probability)
add_subdirectory(data_structures)
add_subdirectory(machine_learning)
add_subdirectory(numerical_methods)
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0057 NEW)
find_package(Doxygen OPTIONAL_COMPONENTS dot dia)
if(DOXYGEN_FOUND)
set(DOXYGEN_GENERATE_MAN NO)
set(DOXYGEN_USE_MATHJAX YES)
set(DOXYGEN_GENERATE_HTML YES)
# set(DOXYGEN_HTML_TIMESTAMP YES)
set(DOXYGEN_EXTRACT_STATIC YES)
set(DOXYGEN_INLINE_SOURCES YES)
set(DOXYGEN_CREATE_SUBDIRS YES)
set(DOXYGEN_EXTRACT_PRIVATE YES)
set(DOXYGEN_GENERATE_TREEVIEW YES)
set(DOXYGEN_STRIP_CODE_COMMENTS NO)
set(DOXYGEN_EXT_LINKS_IN_WINDOW YES)
set(DOXYGEN_BUILTIN_STL_SUPPORT YES)
set(DOXYGEN_ENABLE_PREPROCESSING YES)
set(DOXYGEN_CLANG_ASSISTED_PARSING YES)
set(DOXYGEN_FILE_PATTERNS *.cpp *.h *.hpp *.md)
set(DOXYGEN_MATHJAX_EXTENSIONS TeX/AMSmath TeX/AMSsymbols)
set(DOXYGEN_TAGFILES "doc/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/")
if(MSVC)
set(DOXYGEN_CPP_CLI_SUPPORT YES)
endif()
set(DOXYGEN_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML")
if(Doxygen_dot_FOUND)
set(DOXYGEN_HAVE_DOT YES)
set(DOXYGEN_CALL_GRAPH YES)
set(DOXYGEN_INTERACTIVE_SVG YES)
set(DOXYGEN_DOT_IMAGE_FORMAT "svg")
endif()
if(OPENMP_FOUND)
set(DOXYGEN_PREDEFINED "_OPENMP=1")
endif()
if(GLUT_FOUND)
set(DOXYGEN_PREDEFINED ${DOXYGEN_PREDEFINED} "GLUT_FOUND=1")
endif()
doxygen_add_docs(
doc
${PROJECT_SOURCE_DIR}
COMMENT "Generate documentation"
)
endif()
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

View File

@@ -28,8 +28,85 @@ We are very happy that you consider implementing algorithms and data structures
- Strictly use snake_case (underscore_separated) in filenames.
- If you have added or modified code, please make sure the code compiles before submitting.
- Our automated testing runs [__cpplint__](https://github.com/cpplint/cpplint) on all pull requests so please be sure that your code passes before submitting.
- Please conform to [doxygen](https://www.doxygen.nl/manual/docblocks.html) standard and document the code as much as possible. This not only facilitates the readers but also generates the correct info on website.
- **Be consistent in use of these guidelines.**
#### Documentation
- Make sure you put useful comments in your code. Do not comment things that are obvious.
- Please avoid creating new directories if at all possible. Try to fit your work into the existing directory structure. If you want to create a new directory, then please check if a similar category has been recently suggested or created by other pull requests.
- If you have modified/added documentation, please ensure that your language is concise and contains no grammar errors.
- Do not update README.md along with other changes, first create an issue and then link to that issue in your pull request to suggest specific changes required to README.md
- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repo website](https://thealgorithms.github.io/C-Plus-Plus). Please ensure the code is documented in this structure. Sample implementation is given below.
#### Test
- Make sure to add examples and test cases in your main() function.
- If you find any algorithm or document without tests, please feel free to create a pull request or issue describing suggested changes.
- Please try to add one or more `test()` functions that will invoke the algorithm implementation on random test data with expected output. Use `assert()` function to confirm that the tests will pass.
#### Typical structure of a program:
```cpp
/**
* @file
* @brief Add one line description here
* @details
* This is a multi line
* description containing links, references,
* math equations, etc
* @author [Name](https://github.com/handle)
* @see related_file.cpp, another_file.cpp
*/
#include
/**
* @namespace <check from other files in this repo>
*/
namespace name {
/**
* Class documentation
*/
class cls_name{
private:
int var1; ///< short info of this variable
char *msg; ///< short info
public:
// other members also documented as below
}
/**
* Function documentation
* @tparam T this is a one-line info about T
* @param param1 on-line info about param1
* @param param2 on-line info about param2
* @returns `true` if ...
* @returns `false` if ...
*/
template<class T>
bool func(int param1, T param2) {
// function statements here
if(/*something bad*/)
return false;
return true;
}
/** Test function */
void test() {
/* some statements */
assert(func(...) == ...); // this ensures that the algorithm works as expected
// can have multiple checks
}
/** Main function */
int main(int argc, char *argv[]) {
// code here
return 0;
}
```
#### New File Name guidelines
- Use lowercase words with ``"_"`` as separator
- For instance
@@ -70,16 +147,6 @@ Common prefixes:
- docs: Documentation changes
- test: Correct existing tests or add new ones
#### Documentation
- Make sure you put useful comments in your code. Do not comment things that are obvious.
- Please avoid creating new directories if at all possible. Try to fit your work into the existing directory structure. If you want to create a new directory, then please check if a similar category has been recently suggested or created by other pull requests.
- If you have modified/added documentation, please ensure that your language is concise and contains no grammar errors.
- Do not update README.md along with other changes, first create an issue and then link to that issue in your pull request to suggest specific changes required to README.md
#### Test
- Make sure to add examples and test cases in your main() function.
- If you find any algorithm or document without tests, please feel free to create a pull request or issue describing suggested changes.
### Pull Requests
- Checkout our [pull request template](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/.github/pull_request_template.md)

View File

@@ -1,3 +1,4 @@
# List of all files
## Backtracking
* [Graph Coloring](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/graph_coloring.cpp)
@@ -9,67 +10,58 @@
* [Rat Maze](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/rat_maze.cpp)
* [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp)
## Computer Oriented Statistical Methods
* [Bisection Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Bisection_method.CPP)
* [False-Position](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/false-position.cpp)
* [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Gaussian_elimination.cpp)
* [Newton Raphson](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Newton_Raphson.CPP)
* [Ordinary Least Squares Regressor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/ordinary_least_squares_regressor.cpp)
* [Secant Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Secant_method.CPP)
* [Successive Approximation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/successive_approximation.CPP)
## Ciphers
* [Hill Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/hill_cipher.cpp)
## Data Structure
* [Avltree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/AVLtree.cpp)
* [Binary Search Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Binary%20Search%20Tree.cpp)
* [Binaryheap](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Binaryheap.cpp)
* [Circular Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/circular_Queue_using_Linked_List.cpp)
## Data Structures
* [Avltree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/avltree.cpp)
* [Binary Search Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/binary_search_tree.cpp)
* [Binaryheap](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/binaryheap.cpp)
* [Circular Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/circular_queue_using_linked_list.cpp)
* Cll
* [Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/cll/cll.cpp)
* [Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/cll/cll.h)
* [Main Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/cll/main_cll.cpp)
* [Disjoint Set](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/disjoint_set.cpp)
* [Doubly Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/doubly_linked_list.cpp)
* [Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/linked_list.cpp)
* [Linkedlist Implentation Usingarray](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/linkedList_implentation_usingArray.cpp)
* [List Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/List%20Array.cpp)
* [Morrisinorder](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/MorrisInorder.cpp)
* [Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Queue%20Using%20Array.cpp)
* [Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Queue%20Using%20Linked%20List.cpp)
* Queue
* [Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/queue/queue.cpp)
* [Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/queue/queue.h)
* [Test Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/queue/test_queue.cpp)
* [Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/queue_using_array.cpp)
* [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/queue_using_linkedlist.cpp)
* [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Stack%20Using%20Array.cpp)
* [Stack Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Stack%20Using%20Linked%20List.cpp)
* Stk
* [Main](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/main.cpp)
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/stack.cpp)
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/stack.h)
* [Test Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/test_stack.cpp)
* [Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Tree.cpp)
* [Trie Modern](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/trie_modern.cpp)
* [Trie Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/trie_tree.cpp)
* [Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/cll/cll.cpp)
* [Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/cll/cll.h)
* [Main Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/cll/main_cll.cpp)
* [Disjoint Set](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/disjoint_set.cpp)
* [Doubly Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/doubly_linked_list.cpp)
* [Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/linked_list.cpp)
* [Linkedlist Implentation Usingarray](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/linkedlist_implentation_usingarray.cpp)
* [List Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/list_array.cpp)
* [Morrisinorder](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/morrisinorder.cpp)
* [Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue.h)
* [Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_array.cpp)
* [Queue Using Array2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_array2.cpp)
* [Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linked_list.cpp)
* [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linkedlist.cpp)
* [Skip List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/skip_list.cpp)
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h)
* [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_array.cpp)
* [Stack Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_linked_list.cpp)
* [Test Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_queue.cpp)
* [Test Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack.cpp)
* [Test Stack Students](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack_students.cpp)
* [Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/tree.cpp)
* [Trie Modern](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/trie_modern.cpp)
* [Trie Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/trie_tree.cpp)
## Dynamic Programming
* [0-1 Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/0-1%20Knapsack.cpp)
* [0 1 Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/0_1_knapsack.cpp)
* [Armstrong Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/armstrong_number.cpp)
* [Bellman-Ford](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Bellman-Ford.cpp)
* [Catalan-Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Catalan-Numbers.cpp)
* [Coin-Change](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Coin-Change.cpp)
* [Cut Rod](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Cut%20Rod.cpp)
* [Edit Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Edit%20Distance.cpp)
* [Egg-Dropping-Puzzle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Egg-Dropping-Puzzle.cpp)
* [Fibonacci Bottom Up](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Fibonacci_Bottom_Up.cpp)
* [Fibonacci Top Down](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Fibonacci_Top_Down.cpp)
* [Floyd-Warshall](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Floyd-Warshall.cpp)
* [Bellman Ford](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/bellman_ford.cpp)
* [Catalan Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/catalan_numbers.cpp)
* [Coin Change](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/coin_change.cpp)
* [Cut Rod](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/cut_rod.cpp)
* [Edit Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/edit_distance.cpp)
* [Egg Dropping Puzzle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/egg_dropping_puzzle.cpp)
* [Fibonacci Bottom Up](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/fibonacci_bottom_up.cpp)
* [Fibonacci Top Down](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/fibonacci_top_down.cpp)
* [Floyd Warshall](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/floyd_warshall.cpp)
* [Kadane](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/kadane.cpp)
* [Longest Common Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Longest%20Common%20Subsequence.cpp)
* [Longest Increasing Subsequence (Nlogn)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Longest%20Increasing%20Subsequence%20(nlogn).cpp)
* [Longest Increasing Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Longest%20Increasing%20Subsequence.cpp)
* [Longest Common String](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_common_string.cpp)
* [Matrix-Chain-Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/Matrix-Chain-Multiplication.cpp)
* [Longest Common Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_common_subsequence.cpp)
* [Longest Increasing Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_increasing_subsequence.cpp)
* [Longest Increasing Subsequence (Nlogn)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_increasing_subsequence_(nlogn).cpp)
* [Matrix Chain Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/matrix_chain_multiplication.cpp)
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/tree_height.cpp)
@@ -77,87 +69,123 @@
* [Line Segment Intersection](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/line_segment_intersection.cpp)
## Graph
* [Bfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/BFS.cpp)
* [Bfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bfs.cpp)
* [Bridge Finding With Tarjan Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bridge_finding_with_tarjan_algorithm.cpp)
* [Connected Components](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components.cpp)
* [Connected Components With Dsu](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components_with_dsu.cpp)
* [Dfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/DFS.cpp)
* [Dfs With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/DFS_with_stack.cc)
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Dijkstra.cpp)
* [Cycle Check Directed Graph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/cycle_check_directed_graph.cpp)
* [Dfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dfs.cpp)
* [Dfs With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dfs_with_stack.cpp)
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dijkstra.cpp)
* [Kosaraju](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kosaraju.cpp)
* [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Kruskal.cpp)
* [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kruskal.cpp)
* [Lca](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/lca.cpp)
* [Max Flow With Ford Fulkerson And Edmond Karp Algo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp)
* [Prim](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/prim.cpp)
* [Topological-Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Topological-Sort.cpp)
* [Topological Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/topological_sort.cpp)
* [Topological Sort By Kahns Algo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/topological_sort_by_kahns_algo.cpp)
## Graphics
* [Spirograph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graphics/spirograph.cpp)
## Greedy Algorithms
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/Dijkstra.cpp)
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/dijkstra.cpp)
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/huffman.cpp)
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/Knapsack.cpp)
* [Kruskals Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/Kruskals%20Minimum%20Spanning%20Tree.cpp)
* [Prims Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/Prims%20Minimum%20Spanning%20Tree.cpp)
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/knapsack.cpp)
* [Kruskals Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/kruskals_minimum_spanning_tree.cpp)
* [Prims Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/prims_minimum_spanning_tree.cpp)
## Hashing
* [Chaining](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/Chaining.cpp)
* [Chaining](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/chaining.cpp)
* [Double Hash Hash Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/double_hash_hash_table.cpp)
* [Linear Probing Hash Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/linear_probing_hash_table.cpp)
* [Quadratic Probing Hash Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/quadratic_probing_hash_table.cpp)
## Machine Learning
* [Adaline Learning](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/adaline_learning.cpp)
* [Kohonen Som Topology](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/kohonen_som_topology.cpp)
* [Kohonen Som Trace](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/kohonen_som_trace.cpp)
* [Ordinary Least Squares Regressor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/ordinary_least_squares_regressor.cpp)
## Math
* [Armstrong Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/armstrong_number.cpp)
* [Binary Exponent](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/binary_exponent.cpp)
* [Check Amicable Pair](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_amicable_pair.cpp)
* [Check Prime](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_prime.cpp)
* [Complex Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/complex_numbers.cpp)
* [Double Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/double_factorial.cpp)
* [Eulers Totient Function](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/eulers_totient_function.cpp)
* [Extended Euclid Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/extended_euclid_algorithm.cpp)
* [Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/factorial.cpp)
* [Fast Power](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fast_power.cpp)
* [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp)
* [Greatest Common Divisor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor.cpp)
* [Greatest Common Divisor Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor_euclidean.cpp)
* [Fibonacci Fast](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci_fast.cpp)
* [Fibonacci Large](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci_large.cpp)
* [Gcd Iterative Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_iterative_euclidean.cpp)
* [Gcd Of N Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_of_n_numbers.cpp)
* [Gcd Recursive Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_recursive_euclidean.cpp)
* [Large Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_factorial.cpp)
* [Large Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_number.h)
* [Least Common Multiple](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/least_common_multiple.cpp)
* [Miller Rabin](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/miller_rabin.cpp)
* [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp)
* [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp)
* [Power For Huge Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/power_for_huge_numbers.cpp)
* [Prime Factorization](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/prime_factorization.cpp)
* [Prime Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/prime_numbers.cpp)
* [Primes Up To 10^8](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/primes_up_to_10^8.cpp)
* [Primes Up To Billion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/primes_up_to_billion.cpp)
* [Realtime Stats](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/realtime_stats.cpp)
* [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sieve_of_eratosthenes.cpp)
* [Sqrt Double](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sqrt_double.cpp)
* [String Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/string_fibonacci.cpp)
* [Sum Of Digits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sum_of_digits.cpp)
## Numerical Methods
* [Bisection Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/bisection_method.cpp)
* [Brent Method Extrema](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/brent_method_extrema.cpp)
* [Durand Kerner Roots](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/durand_kerner_roots.cpp)
* [False Position](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/false_position.cpp)
* [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/gaussian_elimination.cpp)
* [Golden Search Extrema](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/golden_search_extrema.cpp)
* [Lu Decompose](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/lu_decompose.cpp)
* [Lu Decomposition](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/lu_decomposition.h)
* [Newton Raphson Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/newton_raphson_method.cpp)
* [Ode Forward Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_forward_euler.cpp)
* [Ode Midpoint Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_midpoint_euler.cpp)
* [Ode Semi Implicit Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_semi_implicit_euler.cpp)
* [Qr Decompose](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_decompose.h)
* [Qr Decomposition](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_decomposition.cpp)
* [Qr Eigen Values](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_eigen_values.cpp)
* [Successive Approximation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/successive_approximation.cpp)
## Operations On Datastructures
* [Array Left Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Array%20Left%20Rotation.cpp)
* [Array Right Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Array%20Right%20Rotation.cpp)
* [Circular Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Circular%20Linked%20List.cpp)
* [Circular Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Circular%20Queue%20Using%20Array.cpp)
* [Array Left Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/array_left_rotation.cpp)
* [Array Right Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/array_right_rotation.cpp)
* [Circular Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/circular_linked_list.cpp)
* [Circular Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/circular_queue_using_array.cpp)
* [Get Size Of Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/get_size_of_linked_list.cpp)
* [Intersection Of 2 Arrays](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Intersection_of_2_arrays.cpp)
* [Reverse A Linked List Using Recusion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Reverse%20a%20Linked%20List%20using%20Recusion.cpp)
* [Selectionsortlinkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/selectionSortLinkedList.cpp)
* [Union Of 2 Arrays](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Union_of_2_arrays.cpp)
* [Intersection Of 2 Arrays](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/intersection_of_2_arrays.cpp)
* [Reverse A Linked List Using Recusion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/reverse_a_linked_list_using_recusion.cpp)
* [Selectionsortlinkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/selectionsortlinkedlist.cpp)
* [Union Of 2 Arrays](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/union_of_2_arrays.cpp)
## Others
* [Buzz Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Buzz_number.cpp)
* [Decimal To Binary](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Decimal%20To%20Binary.cpp)
* [Decimal To Hexadecimal ](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Decimal%20To%20Hexadecimal%20.cpp)
* [Decimal To Roman Numeral](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Decimal%20to%20Roman%20Numeral.cpp)
* [Buzz Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/buzz_number.cpp)
* [Decimal To Binary](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/decimal_to_binary.cpp)
* [Decimal To Hexadecimal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/decimal_to_hexadecimal.cpp)
* [Decimal To Roman Numeral](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/decimal_to_roman_numeral.cpp)
* [Fast Interger Input](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fast_interger_input.cpp)
* [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fibonacci.cpp)
* [Gcd Of N Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/GCD_of_n_numbers.cpp)
* [Happy Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/happy_number.cpp)
* [Matrix Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/matrix_exponentiation.cpp)
* [Measure Time Elapsed](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/measure_time_elapsed.cpp)
* [Palindromeofnumber](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Palindromeofnumber.cpp)
* [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Paranthesis%20Matching.cpp)
* [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/palindrome_of_number.cpp)
* [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/paranthesis_matching.cpp)
* [Pascal Triangle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/pascal_triangle.cpp)
* [Primality Test](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Primality%20Test.cpp)
* [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sieve_of_Eratosthenes.cpp)
* [Smallest-Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest-circle.cpp)
* [Sparse Matrix](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Sparse%20matrix.cpp)
* [Primality Test](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/primality_test.cpp)
* [Smallest Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest_circle.cpp)
* [Sparse Matrix](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sparse_matrix.cpp)
* [Spiral Print](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/spiral_print.cpp)
* [Stairs Pattern](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/stairs_pattern.cpp)
* [Strassen Matrix Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Strassen%20Matrix%20Multiplication.cpp)
* [String Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/String%20Fibonacci.cpp)
* [Tower Of Hanoi](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/Tower%20of%20Hanoi.cpp)
* [Tower Of Hanoi](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/tower_of_hanoi.cpp)
* [Vector Important Functions](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/vector_important_functions.cpp)
## Probability
@@ -167,46 +195,48 @@
* [Poisson Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/poisson_dist.cpp)
## Range Queries
* [Bit](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/bit.cpp)
* [Fenwicktree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/FenwickTree.cpp)
* [Mo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/MO.cpp)
* [Segtree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/segTree.cpp)
* [Fenwick Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/fenwick_tree.cpp)
* [Mo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/mo.cpp)
* [Segtree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/segtree.cpp)
## Search
* [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/binary_search.cpp)
* [Exponential Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/exponential_search.cpp)
* [Fibonacci Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/fibonacci_search.cpp)
* [Hash Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/hash_search.cpp)
* [Interpolation Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/Interpolation%20Search.cpp)
* [Interpolation Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/interpolation_search.cpp)
* [Interpolation Search2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/interpolation_search2.cpp)
* [Jump Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/jump_search.cpp)
* [Linear Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/Linear%20Search.cpp)
* [Linear Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/linear_search.cpp)
* [Median Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/median_search.cpp)
* [Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/searching.cpp)
* [Ternary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/ternary_search.cpp)
* [Text Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/text_search.cpp)
## Sorting
* [Beadsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/BeadSort.cpp)
* [Bitonicsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/BitonicSort.cpp)
* [Bubble Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Bubble%20Sort.cpp)
* [Bucketsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bucketSort.cpp)
* [Cocktailselectionsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/CocktailSelectionSort.cpp)
* [Combsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/combsort.cpp)
* [Counting Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Counting_Sort.cpp)
* [Countingsortstring](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/CountingSortString.cpp)
* [Bead Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bead_sort.cpp)
* [Bitonic Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bitonic_sort.cpp)
* [Bogo Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bogo_sort.cpp)
* [Bubble Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bubble_sort.cpp)
* [Bucket Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bucket_sort.cpp)
* [Cocktail Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/cocktail_selection_sort.cpp)
* [Comb Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/comb_sort.cpp)
* [Counting Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort.cpp)
* [Counting Sort String](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort_string.cpp)
* [Heap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/heap_sort.cpp)
* [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Insertion%20Sort.cpp)
* [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/insertion_sort.cpp)
* [Library Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/library_sort.cpp)
* [Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Merge%20Sort.cpp)
* [Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/merge_sort.cpp)
* [Non Recursive Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/non_recursive_merge_sort.cpp)
* [Numericstringsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/NumericStringSort.cpp)
* [Oddeven Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/OddEven%20Sort.cpp)
* [Numeric String Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/numeric_string_sort.cpp)
* [Odd Even Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/odd_even_sort.cpp)
* [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/quick_sort.cpp)
* [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Radix%20Sort.cpp)
* [Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Selection%20Sort.cpp)
* [Shell Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Shell%20Sort.cpp)
* [Slow Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Slow%20Sort.cpp)
* [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/radix_sort.cpp)
* [Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/selection_sort.cpp)
* [Shell Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/shell_sort.cpp)
* [Shell Sort2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/shell_sort2.cpp)
* [Slow Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/slow_sort.cpp)
* [Swap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/swap_sort.cpp)
* [Tim Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Tim%20Sort.cpp)
* [Tim Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/tim_sort.cpp)
## Strings
* [Brute Force String Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/brute_force_string_searching.cpp)

View File

@@ -1,10 +1,36 @@
# The Algorithms - C++
[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTION.md)&nbsp;
# The Algorithms - C++ # {#mainpage}
<!-- the suffix in the above line is required for doxygen to consider this as the index page of the generated documentation site -->
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp)
[![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms)
[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md)
![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C-Plus-Plus?color=red&style=flat-square)
![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/TheAlgorithms/C-Plus-Plus?color=green&style=flat-square)
[![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)](https://TheAlgorithms.github.io/C-Plus-Plus)
[![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22)
### All algorithms implemented in C++ (for education)
The implementations are for learning purpose. They may be less efficient than the implementation in the standard library.
## Overview
### Contribute Guidelines
Read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTION.md) before you contribute.
The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). The algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations.
## Features
* The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B).
* Well documented source code with detailed explanations provide a valuable resource for educators and students alike.
* Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth.
* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively.
* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc. with little to no changes.
* Self-checks within programs ensure correct implementations with confidence.
* Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications.
## Documentation
[Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus) is generated from the repository source codes directly. The documentation contains all resources including source code snippets, details on execution of the programs, diagrammatic representation of program flow, and links to external resources where necessary. The documentation also introduces interactive source code with links to documentation for C++ STL library functions used.
Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to see the list of all the files documented with the code.
[Documentation of Algorithms in C++](https://thealgorithms.github.io/C-Plus-Plus) by [The Algorithms Contributors](https://github.com/TheAlgorithms/C-Plus-Plus/graphs/contributors) is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1)<br/>
<a href="https://creativecommons.org/licenses/by-sa/4.0"><img alt="Creative Commons License" style="height:22px!important;margin-left: 3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" /><img alt="Credit must be given to the creator" style="height:22px!important;margin-left: 3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" /><img alt="Adaptations must be shared under the same terms" style="height:22px!important;margin-left: 3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" /></a>
## Contributions
As a community developed and maintained repository, we welcome new un-plagiarized quality contributions. Please read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md).

View File

@@ -7,8 +7,7 @@ void printSolution(int color[]);
/* A utility function to check if the current color assignment
is safe for vertex v */
bool isSafe(int v, bool graph[V][V], int color[], int c)
{
bool isSafe(int v, bool graph[V][V], int color[], int c) {
for (int i = 0; i < V; i++)
if (graph[v][i] && c == color[i])
return false;
@@ -16,22 +15,18 @@ bool isSafe(int v, bool graph[V][V], int color[], int c)
}
/* A recursive utility function to solve m coloring problem */
void graphColoring(bool graph[V][V], int m, int color[], int v)
{
void graphColoring(bool graph[V][V], int m, int color[], int v) {
/* base case: If all vertices are assigned a color then
return true */
if (v == V)
{
if (v == V) {
printSolution(color);
return;
}
/* Consider this vertex v and try different colors */
for (int c = 1; c <= m; c++)
{
for (int c = 1; c <= m; c++) {
/* Check if assignment of color c to v is fine*/
if (isSafe(v, graph, color, c))
{
if (isSafe(v, graph, color, c)) {
color[v] = c;
/* recur to assign colors to rest of the vertices */
@@ -45,17 +40,14 @@ void graphColoring(bool graph[V][V], int m, int color[], int v)
}
/* A utility function to print solution */
void printSolution(int color[])
{
void printSolution(int color[]) {
printf(" Following are the assigned colors \n");
for (int i = 0; i < V; i++)
printf(" %d ", color[i]);
for (int i = 0; i < V; i++) printf(" %d ", color[i]);
printf("\n");
}
// driver program to test above function
int main()
{
int main() {
/* Create following graph and test whether it is 3 colorable
(3)---(2)
| / |
@@ -69,12 +61,11 @@ int main()
{1, 1, 0, 1},
{1, 0, 1, 0},
};
int m = 3; // Number of colors
int m = 3; // Number of colors
int color[V];
for (int i = 0; i < V; i++)
color[i] = 0;
for (int i = 0; i < V; i++) color[i] = 0;
graphColoring(graph, m, color, 0);
return 0;

View File

@@ -1,68 +1,60 @@
#include <iostream>
# define n 8
#define n 8
/**
A knight's tour is a sequence of moves of a knight on a chessboard
such that the knight visits every square only once. If the knight
ends on a square that is one knight's move from the beginning
square (so that it could tour the board again immediately, following
such that the knight visits every square only once. If the knight
ends on a square that is one knight's move from the beginning
square (so that it could tour the board again immediately, following
the same path), the tour is closed; otherwise, it is open.
**/
using namespace std;
bool issafe(int x,int y,int sol[n][n])
{
return (x<n && x>=0 && y<n && y>=0 && sol[x][y]==-1);
using std::cin;
using std::cout;
bool issafe(int x, int y, int sol[n][n]) {
return (x < n && x >= 0 && y < n && y >= 0 && sol[x][y] == -1);
}
bool solve(int x,int y, int mov, int sol[n][n], int xmov[n], int ymov[n])
{
int k,xnext,ynext;
bool solve(int x, int y, int mov, int sol[n][n], int xmov[n], int ymov[n]) {
int k, xnext, ynext;
if(mov == n*n)
if (mov == n * n)
return true;
for(k=0;k<8;k++)
{
xnext=x+xmov[k];
ynext=y+ymov[k];
for (k = 0; k < 8; k++) {
xnext = x + xmov[k];
ynext = y + ymov[k];
if(issafe(xnext,ynext,sol))
{
sol[xnext][ynext]=mov;
if (issafe(xnext, ynext, sol)) {
sol[xnext][ynext] = mov;
if(solve(xnext,ynext,mov+1,sol,xmov,ymov)==true)
return true;
else
sol[xnext][ynext]=-1;
}
if (solve(xnext, ynext, mov + 1, sol, xmov, ymov) == true)
return true;
else
sol[xnext][ynext] = -1;
}
}
return false;
}
int main()
{
//initialize();
int main() {
// initialize();
int sol[n][n];
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
sol[i][j]=-1;
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) sol[i][j] = -1;
int xmov[8] = { 2, 1, -1, -2, -2, -1, 1, 2 };
int ymov[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
sol[0][0]=0;
int xmov[8] = {2, 1, -1, -2, -2, -1, 1, 2};
int ymov[8] = {1, 2, 2, 1, -1, -2, -2, -1};
sol[0][0] = 0;
bool flag=solve(0,0,1,sol,xmov,ymov);
if(flag==false)
cout<<"solution doesnot exist \n";
else
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<sol[i][j]<<" ";
cout<<"\n";
bool flag = solve(0, 0, 1, sol, xmov, ymov);
if (flag == false)
cout << "solution doesnot exist \n";
else {
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) cout << sol[i][j] << " ";
cout << "\n";
}
}
}

View File

@@ -20,7 +20,7 @@ int minimax(int depth, int node_index, bool is_max, vector<int> scores,
}
int main() {
vector<int> scores = { 90, 23, 6, 33, 21, 65, 123, 34423 };
vector<int> scores = {90, 23, 6, 33, 21, 65, 123, 34423};
int height = log2(scores.size());
cout << "Optimal value: " << minimax(0, 0, true, scores, height) << endl;

View File

@@ -2,19 +2,15 @@
#define N 4
using namespace std;
void printSolution(int board[N][N])
{
void printSolution(int board[N][N]) {
cout << "\n";
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << "" << board[i][j];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) cout << "" << board[i][j];
cout << "\n";
}
}
bool isSafe(int board[N][N], int row, int col)
{
bool isSafe(int board[N][N], int row, int col) {
int i, j;
/* Check this row on left side */
@@ -35,23 +31,18 @@ bool isSafe(int board[N][N], int row, int col)
return true;
}
void solveNQ(int board[N][N], int col)
{
if (col >= N)
{
void solveNQ(int board[N][N], int col) {
if (col >= N) {
printSolution(board);
return;
}
/* Consider this column and try placing
this queen in all rows one by one */
for (int i = 0; i < N; i++)
{
for (int i = 0; i < N; i++) {
/* Check if queen can be placed on
board[i][col] */
if (isSafe(board, i, col))
{
if (isSafe(board, i, col)) {
/* Place this queen in board[i][col] */
// cout<<"\n"<<col<<"can place"<<i;
board[i][col] = 1;
@@ -59,18 +50,13 @@ void solveNQ(int board[N][N], int col)
/* recur to place rest of the queens */
solveNQ(board, col + 1);
board[i][col] = 0; // BACKTRACK
board[i][col] = 0; // BACKTRACK
}
}
}
int main()
{
int board[N][N] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};
int main() {
int board[N][N] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
solveNQ(board, 0);
return 0;

View File

@@ -1,18 +1,16 @@
#include <iostream>
#define n 4
#define inc_loop(var, start, stop) for (int var=start; var <= stop; var++)
#define dec_loop(var, start, stop) for (int var=start; var >= stop; var--)
#define inc_loop(var, start, stop) for (int var = start; var <= stop; var++)
#define dec_loop(var, start, stop) for (int var = start; var >= stop; var--)
void PrintSol(int Board[n][n]) {
inc_loop(i, 0, n-1) {
inc_loop(j, 0, n-1)
std::cout << Board[i][j] << " ";
inc_loop(i, 0, n - 1) {
inc_loop(j, 0, n - 1) std::cout << Board[i][j] << " ";
std::cout << std::endl;
}
std::cout << std::endl;
if (n%2 == 0 || (n%2 == 1 && Board[n/2+1][0] != 1)) {
inc_loop(i, 0, n-1) {
dec_loop(j, n-1, 0)
std::cout << Board[i][j] << " ";
if (n % 2 == 0 || (n % 2 == 1 && Board[n / 2 + 1][0] != 1)) {
inc_loop(i, 0, n - 1) {
dec_loop(j, n - 1, 0) std::cout << Board[i][j] << " ";
std::cout << std::endl;
}
std::cout << std::endl;
@@ -21,7 +19,7 @@ void PrintSol(int Board[n][n]) {
bool CanIMove(int Board[n][n], int row, int col) {
/// check in the row
inc_loop(i, 0, col-1) {
inc_loop(i, 0, col - 1) {
if (Board[row][i] == 1)
return false;
}
@@ -43,7 +41,7 @@ void NQueenSol(int Board[n][n], int col) {
PrintSol(Board);
return;
}
inc_loop(i, 0, n-1) {
inc_loop(i, 0, n - 1) {
if (CanIMove(Board, i, col)) {
Board[i][col] = 1;
NQueenSol(Board, col + 1);
@@ -54,8 +52,8 @@ void NQueenSol(int Board[n][n], int col) {
int main() {
int Board[n][n] = {0};
if (n%2 == 0) {
inc_loop(i, 0, n/2-1) {
if (n % 2 == 0) {
inc_loop(i, 0, n / 2 - 1) {
if (CanIMove(Board, i, 0)) {
Board[i][0] = 1;
NQueenSol(Board, 1);
@@ -63,7 +61,7 @@ int main() {
}
}
} else {
inc_loop(i, 0, n/2) {
inc_loop(i, 0, n / 2) {
if (CanIMove(Board, i, 0)) {
Board[i][0] = 1;
NQueenSol(Board, 1);

View File

@@ -1,73 +1,62 @@
/*
A Maze is given as N*N binary matrix of blocks where source block is the upper
left most block i.e., maze[0][0] and destination block is lower rightmost
block i.e., maze[N-1][N-1]. A rat starts from source and has to reach destination.
The rat can move only in two directions: forward and down. In the maze matrix,
0 means the block is dead end and 1 means the block can be used in the path
from source to destination.
A Maze is given as N*N binary matrix of blocks where source block is the
upper left most block i.e., maze[0][0] and destination block is lower
rightmost block i.e., maze[N-1][N-1]. A rat starts from source and has to
reach destination. The rat can move only in two directions: forward and down.
In the maze matrix, 0 means the block is dead end and 1 means the block can
be used in the path from source to destination.
*/
#include <iostream>
#define size 4
using namespace std;
int solveMaze(int currposrow, int currposcol, int maze[size][size], int soln[size][size])
{
if ((currposrow == size - 1) && (currposcol == size - 1))
{
soln[currposrow][currposcol] = 1;
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
cout << soln[i][j];
}
cout << endl;
}
return 1;
}
else
{
soln[currposrow][currposcol] = 1;
int solveMaze(int currposrow, int currposcol, int maze[size][size],
int soln[size][size]) {
if ((currposrow == size - 1) && (currposcol == size - 1)) {
soln[currposrow][currposcol] = 1;
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
cout << soln[i][j];
}
cout << endl;
}
return 1;
} else {
soln[currposrow][currposcol] = 1;
// if there exist a solution by moving one step ahead in a collumn
if ((currposcol < size - 1) && maze[currposrow][currposcol + 1] == 1 && solveMaze(currposrow, currposcol + 1, maze, soln))
{
return 1;
}
// if there exist a solution by moving one step ahead in a collumn
if ((currposcol < size - 1) && maze[currposrow][currposcol + 1] == 1 &&
solveMaze(currposrow, currposcol + 1, maze, soln)) {
return 1;
}
// if there exists a solution by moving one step ahead in a row
if ((currposrow < size - 1) && maze[currposrow + 1][currposcol] == 1 && solveMaze(currposrow + 1, currposcol, maze, soln))
{
return 1;
}
// if there exists a solution by moving one step ahead in a row
if ((currposrow < size - 1) && maze[currposrow + 1][currposcol] == 1 &&
solveMaze(currposrow + 1, currposcol, maze, soln)) {
return 1;
}
// the backtracking part
soln[currposrow][currposcol] = 0;
return 0;
}
// the backtracking part
soln[currposrow][currposcol] = 0;
return 0;
}
}
int main(int argc, char const *argv[])
{
int maze[size][size] = {
{1, 0, 1, 0},
{1, 0, 1, 1},
{1, 0, 0, 1},
{1, 1, 1, 1}};
int main(int argc, char const *argv[]) {
int maze[size][size] = {
{1, 0, 1, 0}, {1, 0, 1, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}};
int soln[size][size];
int soln[size][size];
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
soln[i][j] = 0;
}
}
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
soln[i][j] = 0;
}
}
int currposrow = 0;
int currposcol = 0;
solveMaze(currposrow, currposcol, maze, soln);
return 0;
int currposrow = 0;
int currposcol = 0;
solveMaze(currposrow, currposcol, maze, soln);
return 0;
}

View File

@@ -1,15 +1,12 @@
#include <iostream>
using namespace std;
///N=9;
/// N=9;
int n = 9;
bool isPossible(int mat[][9], int i, int j, int no)
{
///Row or col nahin hona chahiye
for (int x = 0; x < n; x++)
{
if (mat[x][j] == no || mat[i][x] == no)
{
bool isPossible(int mat[][9], int i, int j, int no) {
/// Row or col nahin hona chahiye
for (int x = 0; x < n; x++) {
if (mat[x][j] == no || mat[i][x] == no) {
return false;
}
}
@@ -18,12 +15,9 @@ bool isPossible(int mat[][9], int i, int j, int no)
int sx = (i / 3) * 3;
int sy = (j / 3) * 3;
for (int x = sx; x < sx + 3; x++)
{
for (int y = sy; y < sy + 3; y++)
{
if (mat[x][y] == no)
{
for (int x = sx; x < sx + 3; x++) {
for (int y = sy; y < sy + 3; y++) {
if (mat[x][y] == no) {
return false;
}
}
@@ -31,83 +25,63 @@ bool isPossible(int mat[][9], int i, int j, int no)
return true;
}
void printMat(int mat[][9])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
void printMat(int mat[][9]) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << mat[i][j] << " ";
if ((j + 1) % 3 == 0)
{
if ((j + 1) % 3 == 0) {
cout << '\t';
}
}
if ((i + 1) % 3 == 0)
{
if ((i + 1) % 3 == 0) {
cout << endl;
}
cout << endl;
}
}
bool solveSudoku(int mat[][9], int i, int j)
{
///Base Case
if (i == 9)
{
///Solve kr chuke hain for 9 rows already
bool solveSudoku(int mat[][9], int i, int j) {
/// Base Case
if (i == 9) {
/// Solve kr chuke hain for 9 rows already
printMat(mat);
return true;
}
///Crossed the last Cell in the row
if (j == 9)
{
/// Crossed the last Cell in the row
if (j == 9) {
return solveSudoku(mat, i + 1, 0);
}
///Blue Cell - Skip
if (mat[i][j] != 0)
{
/// Blue Cell - Skip
if (mat[i][j] != 0) {
return solveSudoku(mat, i, j + 1);
}
///White Cell
///Try to place every possible no
for (int no = 1; no <= 9; no++)
{
if (isPossible(mat, i, j, no))
{
///Place the no - assuming solution aa jayega
/// White Cell
/// Try to place every possible no
for (int no = 1; no <= 9; no++) {
if (isPossible(mat, i, j, no)) {
/// Place the no - assuming solution aa jayega
mat[i][j] = no;
bool aageKiSolveHui = solveSudoku(mat, i, j + 1);
if (aageKiSolveHui)
{
if (aageKiSolveHui) {
return true;
}
///Nahin solve hui
///loop will place the next no.
/// Nahin solve hui
/// loop will place the next no.
}
}
///Sare no try kr liey, kisi se bhi solve nahi hui
/// Sare no try kr liey, kisi se bhi solve nahi hui
mat[i][j] = 0;
return false;
}
int main()
{
int mat[9][9] =
{{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
int main() {
int mat[9][9] = {{5, 3, 0, 0, 7, 0, 0, 0, 0}, {6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0}, {8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1}, {7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
printMat(mat);
cout << "Solution " << endl;

18
ciphers/CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".cpp" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
if(OpenMP_CXX_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
endif()
install(TARGETS ${testname} DESTINATION "bin/ciphers")
endforeach( testsourcefile ${APP_SOURCES} )

543
ciphers/hill_cipher.cpp Normal file
View File

@@ -0,0 +1,543 @@
/**
* @file hill_cipher.cpp
* @brief Implementation of [Hill
* cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm.
*
* Program to generate the encryption-decryption key and perform encryption and
* decryption of ASCII text using the famous block cipher algorithm. This is a
* powerful encryption algorithm that is relatively easy to implement with a
* given key. The strength of the algorithm depends on the size of the block
* encryption matrix key; the bigger the matrix, the stronger the encryption and
* more difficult to break it. However, the important requirement for the matrix
* is that:
* 1. matrix should be invertible - all inversion conditions should be satisfied
* and
* 2. its determinant must not have any common factors with the length of
* character set
* Due to this restriction, most implementations only implement with small 3x3
* encryption keys and a small subset of ASCII alphabets.
*
* In the current implementation, I present to you an implementation for
* generating larger encryption keys (I have attempted upto 10x10) and an ASCII
* character set of 97 printable characters. Hence, a typical ASCII text file
* could be easily encrypted with the module. The larger character set increases
* the modulo of cipher and hence the matrix determinants can get very large
* very quickly rendering them ill-defined.
*
* \note This program uses determinant computation using LU decomposition from
* the file lu_decomposition.h
* \note The matrix generation algorithm is very rudimentary and does not
* guarantee an invertible modulus matrix. \todo Better matrix generation
* algorithm.
*
* @author [Krishna Vedala](https://github.com/kvedala)
*/
#include <cassert>
#include <cmath>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#ifdef _OPENMP
#include <omp.h>
#endif
#include "../numerical_methods/lu_decomposition.h"
/**
* operator to print a matrix
*/
template <typename T>
static std::ostream &operator<<(std::ostream &out, matrix<T> const &v) {
const int width = 15;
const char separator = ' ';
for (size_t row = 0; row < v.size(); row++) {
for (size_t col = 0; col < v[row].size(); col++)
out << std::left << std::setw(width) << std::setfill(separator)
<< v[row][col];
out << std::endl;
}
return out;
}
/** \namespace ciphers
* \brief Algorithms for encryption and decryption
*/
namespace ciphers {
/** dictionary of characters that can be encrypted and decrypted */
static const char *STRKEY =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&"
"*()_+`-=[]{}|;':\",./<>?\\\r\n \0";
/**
* @brief Implementation of [Hill
* Cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm
*/
class HillCipher {
private:
/**
* @brief Function to generate a random integer in a given interval
*
* @param a lower limit of interval
* @param b upper limit of interval
* @tparam T type of output
* @return random integer in the interval \f$[a,b)\f$
*/
template <typename T1, typename T2>
static const T2 rand_range(T1 a, T1 b) {
// generate random number between 0 and 1
long double r = static_cast<long double>(std::rand()) / RAND_MAX;
// scale and return random number as integer
return static_cast<T2>(r * (b - a) + a);
}
/**
* @brief Function overload to fill a matrix with random integers in a given
* interval
*
* @param M pointer to matrix to be filled with random numbers
* @param a lower limit of interval
* @param b upper limit of interval
* @tparam T1 type of input range
* @tparam T2 type of matrix
* @return determinant of generated random matrix
*
* @warning There will need to be a balance between the matrix size and the
* range of random numbers. If the matrix is large, the range of random
* numbers must be small to have a well defined keys. Or if the matrix is
* smaller, the random numbers range can be larger. For an 8x8 matrix, range
* should be no more than \f$[0,10]\f$
*/
template <typename T1, typename T2>
static double rand_range(matrix<T2> *M, T1 a, T1 b) {
for (size_t i = 0; i < M->size(); i++) {
for (size_t j = 0; j < M[0][0].size(); j++) {
M[0][i][j] = rand_range<T1, T2>(a, b);
}
}
return determinant_lu(*M);
}
/**
* @brief Compute
* [GCD](https://en.wikipedia.org/wiki/Greatest_common_divisor) of two
* integers using Euler's algorithm
*
* @param a first number
* @param b second number
* @return GCD of \f$a\f$ and \f$b\f$
*/
template <typename T>
static const T gcd(T a, T b) {
if (b > a) // ensure always a < b
std::swap(a, b);
while (b != 0) {
T tmp = b;
b = a % b;
a = tmp;
}
return a;
}
/**
* @brief helper function to perform vector multiplication with encryption
* or decryption matrix
*
* @param vector vector to multiply
* @param key encryption or decryption key matrix
* @return corresponding encrypted or decrypted text
*/
static const std::valarray<uint8_t> mat_mul(
const std::valarray<uint8_t> &vector, const matrix<int> &key) {
std::valarray<uint8_t> out(vector); // make a copy
size_t L = std::strlen(STRKEY);
for (size_t i = 0; i < key.size(); i++) {
int tmp = 0;
for (size_t j = 0; j < vector.size(); j++) {
tmp += key[i][j] * vector[j];
}
out[i] = static_cast<uint8_t>(tmp % L);
}
return out;
}
/**
* @brief Get the character at a given index in the ::STRKEY
*
* @param idx index value
* @return character at the index
*/
static inline char get_idx_char(const uint8_t idx) { return STRKEY[idx]; }
/**
* @brief Get the index of a character in the ::STRKEY
*
* @param ch character to search
* @return index of character
*/
static inline uint8_t get_char_idx(const char ch) {
size_t L = std::strlen(STRKEY);
for (size_t idx = 0; idx <= L; idx++)
if (STRKEY[idx] == ch)
return idx;
std::cerr << __func__ << ":" << __LINE__ << ": (" << ch
<< ") Should not reach here!\n";
return 0;
}
/**
* @brief Convenience function to perform block cipher operations. The
* operations are identical for both encryption and decryption.
*
* @param text input text to encrypt or decrypt
* @param key key for encryption or decryption
* @return encrypted/decrypted output
*/
static const std::string codec(const std::string &text,
const matrix<int> &key) {
size_t text_len = text.length();
size_t key_len = key.size();
// length of output string must be a multiple of key_len
// create output string and initialize with '\0' character
size_t L2 = text_len % key_len == 0
? text_len
: text_len + key_len - (text_len % key_len);
std::string coded_text(L2, '\0');
// temporary array for batch processing
int i;
#ifdef _OPENMP
#pragma parallel omp for private(i)
#endif
for (i = 0; i < L2 - key_len + 1; i += key_len) {
std::valarray<uint8_t> batch_int(key_len);
for (size_t j = 0; j < key_len; j++) {
batch_int[j] = get_char_idx(text[i + j]);
}
batch_int = mat_mul(batch_int, key);
for (size_t j = 0; j < key_len; j++) {
coded_text[i + j] =
STRKEY[batch_int[j]]; // get character at key
}
}
return coded_text;
}
/**
* Get matrix inverse using Row-transformations. Given matrix must
* be a square and non-singular.
* \returns inverse matrix
**/
template <typename T>
static matrix<double> get_inverse(matrix<T> const &A) {
// Assuming A is square matrix
size_t N = A.size();
matrix<double> inverse(N, std::valarray<double>(N));
for (size_t row = 0; row < N; row++) {
for (size_t col = 0; col < N; col++) {
// create identity matrix
inverse[row][col] = (row == col) ? 1.f : 0.f;
}
}
if (A.size() != A[0].size()) {
std::cerr << "A must be a square matrix!" << std::endl;
return inverse;
}
// preallocate a temporary matrix identical to A
matrix<double> temp(N, std::valarray<double>(N));
for (size_t row = 0; row < N; row++) {
for (size_t col = 0; col < N; col++)
temp[row][col] = static_cast<double>(A[row][col]);
}
// start transformations
for (size_t row = 0; row < N; row++) {
for (size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) {
// this to ensure diagonal elements are not 0
temp[row] = temp[row] + temp[row2];
inverse[row] = inverse[row] + inverse[row2];
}
for (size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) {
// this to further ensure diagonal elements are not 0
for (size_t row2 = 0; row2 < N; row2++) {
temp[row2][row] = temp[row2][row] + temp[row2][col2];
inverse[row2][row] =
inverse[row2][row] + inverse[row2][col2];
}
}
if (temp[row][row] == 0) {
// Probably a low-rank matrix and hence singular
std::cerr << "Low-rank matrix, no inverse!" << std::endl;
return inverse;
}
// set diagonal to 1
double divisor = temp[row][row];
temp[row] = temp[row] / divisor;
inverse[row] = inverse[row] / divisor;
// Row transformations
for (size_t row2 = 0; row2 < N; row2++) {
if (row2 == row)
continue;
double factor = temp[row2][row];
temp[row2] = temp[row2] - factor * temp[row];
inverse[row2] = inverse[row2] - factor * inverse[row];
}
}
return inverse;
}
static int modulo(int a, int b) {
int ret = a % b;
if (ret < 0)
ret += b;
return ret;
}
public:
/**
* @brief Generate encryption matrix of a given size. Larger size matrices
* are difficult to generate but provide more security. Important conditions
* are:
* 1. matrix should be invertible
* 2. determinant must not have any common factors with the length of
* character key
* There is no head-fast way to generate hte matrix under the given
* numerical restrictions of the machine but the conditions added achieve
* the goals. Bigger the matrix, greater is the probability of the matrix
* being ill-defined.
*
* @param size size of matrix (typically \f$\text{size}\le10\f$)
* @param limit1 lower limit of range of random elements (default=0)
* @param limit2 upper limit of range of random elements (default=10)
* @return Encryption martix
*/
static matrix<int> generate_encryption_key(size_t size, int limit1 = 0,
int limit2 = 10) {
matrix<int> encrypt_key(size, std::valarray<int>(size));
matrix<int> min_mat = encrypt_key;
int mat_determinant = -1; // because matrix has only ints, the
// determinant will also be an int
int L = std::strlen(STRKEY);
double dd;
do {
// keeping the random number range smaller generates better
// defined matrices with more ease of cracking
dd = rand_range(&encrypt_key, limit1, limit2);
mat_determinant = static_cast<int>(dd);
if (mat_determinant < 0)
mat_determinant = (mat_determinant % L);
} while (std::abs(dd) > 1e3 || // while ill-defined
dd < 0.1 || // while singular or negative determinant
!std::isfinite(dd) || // while determinant is not finite
gcd(mat_determinant, L) != 1); // while no common factors
// std::cout <<
return encrypt_key;
}
/**
* @brief Generate decryption matrix from an encryption matrix key.
*
* @param encrypt_key encryption key for which to create a decrypt key
* @return Decryption martix
*/
static matrix<int> generate_decryption_key(matrix<int> const &encrypt_key) {
size_t size = encrypt_key.size();
int L = std::strlen(STRKEY);
matrix<int> decrypt_key(size, std::valarray<int>(size));
int det_encrypt = static_cast<int>(determinant_lu(encrypt_key));
int mat_determinant = det_encrypt < 0 ? det_encrypt % L : det_encrypt;
matrix<double> tmp_inverse = get_inverse(encrypt_key);
double d2 = determinant_lu(decrypt_key);
// find co-prime factor for inversion
int det_inv = -1;
for (int i = 0; i < L; i++) {
if (modulo(mat_determinant * i, L) == 1) {
det_inv = i;
break;
}
}
if (det_inv == -1) {
std::cerr << "Could not find a co-prime for inversion\n";
std::exit(EXIT_FAILURE);
}
mat_determinant = det_inv * det_encrypt;
// perform modular inverse of encryption matrix
int i;
#ifdef _OPENMP
#pragma parallel omp for private(i)
#endif
for (i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
int temp = std::round(tmp_inverse[i][j] * mat_determinant);
decrypt_key[i][j] = modulo(temp, L);
}
}
return decrypt_key;
}
/**
* @brief Generate encryption and decryption key pair
*
* @param size size of matrix key (typically \f$\text{size}\le10\f$)
* @param limit1 lower limit of range of random elements (default=0)
* @param limit2 upper limit of range of random elements (default=10)
* @return std::pair<matrix<int>, matrix<int>> encryption and decryption
* keys as a pair
*
* @see ::generate_encryption_key
*/
static std::pair<matrix<int>, matrix<int>> generate_keys(size_t size,
int limit1 = 0,
int limit2 = 10) {
matrix<int> encrypt_key = generate_encryption_key(size);
matrix<int> decrypt_key = generate_decryption_key(encrypt_key);
double det2 = determinant_lu(decrypt_key);
while (std::abs(det2) < 0.1 || std::abs(det2) > 1e3) {
encrypt_key = generate_encryption_key(size, limit1, limit2);
decrypt_key = generate_decryption_key(encrypt_key);
det2 = determinant_lu(decrypt_key);
}
return std::make_pair(encrypt_key, decrypt_key);
}
/**
* @brief Encrypt a given text using a given key
*
* @param text string to encrypt
* @param encrypt_key key for encryption
* @return encrypted text
*/
static const std::string encrypt_text(const std::string &text,
const matrix<int> &encrypt_key) {
return codec(text, encrypt_key);
}
/**
* @brief Decrypt a given text using a given key
*
* @param text string to decrypt
* @param decrypt_key key for decryption
* @return decrypted text
*/
static const std::string decrypt_text(const std::string &text,
const matrix<int> &decrypt_key) {
return codec(text, decrypt_key);
}
};
} // namespace ciphers
/**
* @brief Self test 1 - using 3x3 randomly generated key
*
* @param text string to encrypt and decrypt
*/
void test1(const std::string &text) {
// std::string text = "Hello world!";
std::cout << "======Test 1 (3x3 key) ======\nOriginal text:\n\t" << text
<< std::endl;
std::pair<matrix<int>, matrix<int>> p =
ciphers::HillCipher::generate_keys(3, 0, 100);
matrix<int> ekey = p.first;
matrix<int> dkey = p.second;
// matrix<int> ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}};
// std::cout << "Encryption key: \n" << ekey;
std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey);
std::cout << "Encrypted text:\n\t" << gibberish << std::endl;
// matrix<int> dkey = ciphers::HillCipher::generate_decryption_key(ekey);
// std::cout << "Decryption key: \n" << dkey;
std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey);
std::cout << "Reconstruct text:\n\t" << txt_back << std::endl;
std::ofstream out_file("hill_cipher_test1.txt");
out_file << "Block size: " << ekey.size() << "\n";
out_file << "Encryption Key:\n" << ekey;
out_file << "\nDecryption Key:\n" << dkey;
out_file.close();
assert(txt_back == text);
std::cout << "Passed :)\n";
}
/**
* @brief Self test 2 - using 8x8 randomly generated key
*
* @param text string to encrypt and decrypt
*/
void test2(const std::string &text) {
// std::string text = "Hello world!";
std::cout << "======Test 2 (8x8 key) ======\nOriginal text:\n\t" << text
<< std::endl;
std::pair<matrix<int>, matrix<int>> p =
ciphers::HillCipher::generate_keys(8, 0, 3);
matrix<int> ekey = p.first;
matrix<int> dkey = p.second;
std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey);
std::cout << "Encrypted text:\n\t" << gibberish << std::endl;
std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey);
std::cout << "Reconstruct text:\n\t" << txt_back << std::endl;
std::ofstream out_file("hill_cipher_test2.txt");
out_file << "Block size: " << ekey.size() << "\n";
out_file << "Encryption Key:\n" << ekey;
out_file << "\nDecryption Key:\n" << dkey;
out_file.close();
assert(txt_back.compare(0, text.size(), text) == 0);
std::cout << "Passed :)\n";
}
/** Main function */
int main() {
std::srand(std::time(nullptr));
std::cout << "Key dictionary: (" << std::strlen(ciphers::STRKEY) << ")\n\t"
<< ciphers::STRKEY << "\n";
std::string text = "This is a simple text with numb3r5 and exclamat!0n.";
test1(text);
test2(text);
return 0;
}

View File

@@ -1,53 +0,0 @@
#include <iostream.h>
#include <conio.h>
#include <math.h>
float eq(float i)
{
return (pow(i, 3) - (4 * i) - 9); // original equation
}
void main()
{
float a, b, x, z;
clrscr();
for (int i = 0; i < 100; i++)
{
z = eq(i);
if (z >= 0)
{
b = i;
a = --i;
goto START;
}
}
START:
cout << "\nFirst initial: " << a;
cout << "\nSecond initial: " << b;
for (i = 0; i < 100; i++)
{
x = (a + b) / 2;
z = eq(x);
cout << "\n\nz: " << z << "\t[" << a << " , " << b << " | Bisect: " << x << "]";
if (z < 0)
{
a = x;
}
else
{
b = x;
}
if (z > 0 && z < 0.0009) // stoping criteria
{
goto END;
}
}
END:
cout << "\n\nRoot: " << x;
getch();
}

View File

@@ -1,63 +0,0 @@
#include <iostream>
using namespace std;
int main()
{
int mat_size, i, j, step;
cout << "Matrix size: ";
cin >> mat_size;
double mat[mat_size + 1][mat_size + 1], x[mat_size][mat_size + 1];
cout << endl
<< "Enter value of the matrix: " << endl;
for (i = 0; i < mat_size; i++)
{
for (j = 0; j <= mat_size; j++)
{
cin >> mat[i][j]; //Enter (mat_size*mat_size) value of the matrix.
}
}
for (step = 0; step < mat_size - 1; step++)
{
for (i = step; i < mat_size - 1; i++)
{
double a = (mat[i + 1][step] / mat[step][step]);
for (j = step; j <= mat_size; j++)
mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]);
}
}
cout << endl
<< "Matrix using Gaussian Elimination method: " << endl;
for (i = 0; i < mat_size; i++)
{
for (j = 0; j <= mat_size; j++)
{
x[i][j] = mat[i][j];
cout << mat[i][j] << " ";
}
cout << endl;
}
cout << endl
<< "Value of the Gaussian Elimination method: " << endl;
for (i = mat_size - 1; i >= 0; i--)
{
double sum = 0;
for (j = mat_size - 1; j > i; j--)
{
x[i][j] = x[j][j] * x[i][j];
sum = x[i][j] + sum;
}
if (x[i][i] == 0)
x[i][i] = 0;
else
x[i][i] = (x[i][mat_size] - sum) / (x[i][i]);
cout << "x" << i << "= " << x[i][i] << endl;
}
return 0;
}

View File

@@ -1,53 +0,0 @@
#include <iostream.h>
#include <conio.h>
#include <math.h>
float eq(float i)
{
return (pow(i, 3) - (4 * i) - 9); // original equation
}
float eq_der(float i)
{
return ((3 * pow(i, 2)) - 4); // derivative of equation
}
void main()
{
float a, b, z, c, m, n;
clrscr();
for (int i = 0; i < 100; i++)
{
z = eq(i);
if (z >= 0)
{
b = i;
a = --i;
goto START;
}
}
START:
cout << "\nFirst initial: " << a;
cout << "\nSecond initial: " << b;
c = (a + b) / 2;
for (i = 0; i < 100; i++)
{
float h;
m = eq(c);
n = eq_der(c);
z = c - (m / n);
c = z;
if (m > 0 && m < 0.009) // stoping criteria
{
goto END;
}
}
END:
cout << "\n\nRoot: " << z;
getch();
}

View File

@@ -1,49 +0,0 @@
#include <iostream.h>
#include <conio.h>
#include <math.h>
float eq(float i)
{
return (pow(i, 3) - (4 * i) - 9); // original equation
}
void main()
{
float a, b, z, c, m, n;
clrscr();
for (int i = 0; i < 100; i++)
{
z = eq(i);
if (z >= 0)
{
b = i;
a = --i;
goto START;
}
}
START:
cout << "\nFirst initial: " << a;
cout << "\nSecond initial: " << b;
for (i = 0; i < 100; i++)
{
float h, d;
m = eq(a);
n = eq(b);
c = ((a * n) - (b * m)) / (n - m);
a = b;
b = c;
z = eq(c);
if (z > 0 && z < 0.09) // stoping criteria
{
goto END;
}
}
END:
cout << "\n\nRoot: " << c;
getch();
}

View File

@@ -1,35 +0,0 @@
#include<stdlib.h>
#include <math.h>
#include <iostream>
float eq(float i) {
return (pow(i, 3) - (4 * i) - 9); // origial equation
}
int main() {
float a, b, z, c, m, n;
system("clear");
for (int i = 0; i < 100; i++) {
z = eq(i);
if (z >= 0) {
b = i;
a = --i;
goto START;
}
}
START:
std::cout << "\nFirst initial: " << a;
std::cout << "\nSecond initial: " << b;
for (int i = 0; i < 100; i++) {
float h, d;
m = eq(a);
n = eq(b);
c = ((a * n) - (b * m)) / (n - m);
a = c;
z = eq(c);
if (z > 0 && z < 0.09) { // stoping criteria
goto END;
}
}
END:
std::cout << "\n\nRoot: " << c;
system("pause");
}

View File

@@ -1,349 +0,0 @@
/**
* Program that gets the number of data samples and number of features per
* sample along with output per sample. It applies OLS regression to compute
* the regression output for additional test data samples.
**/
#include <iomanip>
#include <iostream>
#include <vector>
template <typename T>
std::ostream &operator<<(std::ostream &out,
std::vector<std::vector<T>> const &v) {
const int width = 10;
const char separator = ' ';
for (size_t row = 0; row < v.size(); row++) {
for (size_t col = 0; col < v[row].size(); col++)
out << std::left << std::setw(width) << std::setfill(separator)
<< v[row][col];
out << std::endl;
}
return out;
}
template <typename T>
std::ostream &operator<<(std::ostream &out, std::vector<T> const &v) {
const int width = 15;
const char separator = ' ';
for (size_t row = 0; row < v.size(); row++)
out << std::left << std::setw(width) << std::setfill(separator) << v[row];
return out;
}
template <typename T>
inline bool is_square(std::vector<std::vector<T>> const &A) {
// Assuming A is square matrix
size_t N = A.size();
for (size_t i = 0; i < N; i++)
if (A[i].size() != N)
return false;
return true;
}
/**
* matrix multiplication
**/
template <typename T>
std::vector<std::vector<T>> operator*(std::vector<std::vector<T>> const &A,
std::vector<std::vector<T>> const &B) {
// Number of rows in A
size_t N_A = A.size();
// Number of columns in B
size_t N_B = B[0].size();
std::vector<std::vector<T>> result(N_A);
if (A[0].size() != B.size()) {
std::cerr << "Number of columns in A != Number of rows in B ("
<< A[0].size() << ", " << B.size() << ")" << std::endl;
return result;
}
for (size_t row = 0; row < N_A; row++) {
std::vector<T> v(N_B);
for (size_t col = 0; col < N_B; col++) {
v[col] = static_cast<T>(0);
for (size_t j = 0; j < B.size(); j++)
v[col] += A[row][j] * B[j][col];
}
result[row] = v;
}
return result;
}
template <typename T>
std::vector<T> operator*(std::vector<std::vector<T>> const &A,
std::vector<T> const &B) {
// Number of rows in A
size_t N_A = A.size();
std::vector<T> result(N_A);
if (A[0].size() != B.size()) {
std::cerr << "Number of columns in A != Number of rows in B ("
<< A[0].size() << ", " << B.size() << ")" << std::endl;
return result;
}
for (size_t row = 0; row < N_A; row++) {
result[row] = static_cast<T>(0);
for (size_t j = 0; j < B.size(); j++)
result[row] += A[row][j] * B[j];
}
return result;
}
template <typename T>
std::vector<float> operator*(float const scalar, std::vector<T> const &A) {
// Number of rows in A
size_t N_A = A.size();
std::vector<float> result(N_A);
for (size_t row = 0; row < N_A; row++) {
result[row] += A[row] * static_cast<float>(scalar);
}
return result;
}
template <typename T>
std::vector<float> operator*(std::vector<T> const &A, float const scalar) {
// Number of rows in A
size_t N_A = A.size();
std::vector<float> result(N_A);
for (size_t row = 0; row < N_A; row++)
result[row] = A[row] * static_cast<float>(scalar);
return result;
}
template <typename T>
std::vector<float> operator/(std::vector<T> const &A, float const scalar) {
return (1.f / scalar) * A;
}
template <typename T>
std::vector<T> operator-(std::vector<T> const &A, std::vector<T> const &B) {
// Number of rows in A
size_t N = A.size();
std::vector<T> result(N);
if (B.size() != N) {
std::cerr << "Vector dimensions shouldbe identical!" << std::endl;
return A;
}
for (size_t row = 0; row < N; row++)
result[row] = A[row] - B[row];
return result;
}
template <typename T>
std::vector<T> operator+(std::vector<T> const &A, std::vector<T> const &B) {
// Number of rows in A
size_t N = A.size();
std::vector<T> result(N);
if (B.size() != N) {
std::cerr << "Vector dimensions shouldbe identical!" << std::endl;
return A;
}
for (size_t row = 0; row < N; row++)
result[row] = A[row] + B[row];
return result;
}
/**
* Get matrix inverse using Row-trasnformations
**/
template <typename T>
std::vector<std::vector<float>>
get_inverse(std::vector<std::vector<T>> const &A) {
// Assuming A is square matrix
size_t N = A.size();
std::vector<std::vector<float>> inverse(N);
for (size_t row = 0; row < N; row++) {
// preallocatae a resultant identity matrix
inverse[row] = std::vector<float>(N);
for (size_t col = 0; col < N; col++)
inverse[row][col] = (row == col) ? 1.f : 0.f;
}
if (!is_square(A)) {
std::cerr << "A must be a square matrix!" << std::endl;
return inverse;
}
// preallocatae a temporary matrix identical to A
std::vector<std::vector<float>> temp(N);
for (size_t row = 0; row < N; row++) {
std::vector<float> v(N);
for (size_t col = 0; col < N; col++)
v[col] = static_cast<float>(A[row][col]);
temp[row] = v;
}
// start transformations
for (size_t row = 0; row < N; row++) {
for (size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) {
// this to ensure diagonal elements are not 0
temp[row] = temp[row] + temp[row2];
inverse[row] = inverse[row] + inverse[row2];
}
for (size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) {
// this to further ensure diagonal elements are not 0
for (size_t row2 = 0; row2 < N; row2++) {
temp[row2][row] = temp[row2][row] + temp[row2][col2];
inverse[row2][row] = inverse[row2][row] + inverse[row2][col2];
}
}
if (temp[row][row] == 0) {
// Probably a low-rank matrix and hence singular
std::cerr << "Low-rank matrix, no inverse!" << std::endl;
return inverse;
}
// set diagonal to 1
float divisor = static_cast<float>(temp[row][row]);
temp[row] = temp[row] / divisor;
inverse[row] = inverse[row] / divisor;
// Row transformations
for (size_t row2 = 0; row2 < N; row2++) {
if (row2 == row)
continue;
float factor = temp[row2][row];
temp[row2] = temp[row2] - factor * temp[row];
inverse[row2] = inverse[row2] - factor * inverse[row];
}
}
return inverse;
}
/**
* matrix transpose
**/
template <typename T>
std::vector<std::vector<T>>
get_transpose(std::vector<std::vector<T>> const &A) {
std::vector<std::vector<T>> result(A[0].size());
for (size_t row = 0; row < A[0].size(); row++) {
std::vector<T> v(A.size());
for (size_t col = 0; col < A.size(); col++)
v[col] = A[col][row];
result[row] = v;
}
return result;
}
template <typename T>
std::vector<float> fit_OLS_regressor(std::vector<std::vector<T>> const &X,
std::vector<T> const &Y) {
// NxF
std::vector<std::vector<T>> X2 = X;
for (size_t i = 0; i < X2.size(); i++)
// add Y-intercept -> Nx(F+1)
X2[i].push_back(1);
// (F+1)xN
std::vector<std::vector<T>> Xt = get_transpose(X2);
// (F+1)x(F+1)
std::vector<std::vector<T>> tmp = get_inverse(Xt * X2);
// (F+1)xN
std::vector<std::vector<float>> out = tmp * Xt;
// cout << endl
// << "Projection matrix: " << X2 * out << endl;
// Fx1,1 -> (F+1)^th element is the independent constant
return out * Y;
}
/**
* Given data and OLS model coeffficients, predict
* regression estimates
**/
template <typename T>
std::vector<float> predict_OLS_regressor(std::vector<std::vector<T>> const &X,
std::vector<float> const &beta) {
std::vector<float> result(X.size());
for (size_t rows = 0; rows < X.size(); rows++) {
// -> start with constant term
result[rows] = beta[X[0].size()];
for (size_t cols = 0; cols < X[0].size(); cols++)
result[rows] += beta[cols] * X[rows][cols];
}
// Nx1
return result;
}
int main() {
size_t N, F;
std::cout << "Enter number of features: ";
// number of features = columns
std::cin >> F;
std::cout << "Enter number of samples: ";
// number of samples = rows
std::cin >> N;
std::vector<std::vector<float>> data(N);
std::vector<float> Y(N);
std::cout
<< "Enter training data. Per sample, provide features ad one output."
<< std::endl;
for (size_t rows = 0; rows < N; rows++) {
std::vector<float> v(F);
std::cout << "Sample# " << rows + 1 << ": ";
for (size_t cols = 0; cols < F; cols++)
// get the F features
std::cin >> v[cols];
data[rows] = v;
// get the corresponding output
std::cin >> Y[rows];
}
std::vector<float> beta = fit_OLS_regressor(data, Y);
std::cout << std::endl << std::endl << "beta:" << beta << std::endl;
size_t T;
std::cout << "Enter number of test samples: ";
// number of test sample inputs
std::cin >> T;
std::vector<std::vector<float>> data2(T);
// vector<float> Y2(T);
for (size_t rows = 0; rows < T; rows++) {
std::cout << "Sample# " << rows + 1 << ": ";
std::vector<float> v(F);
for (size_t cols = 0; cols < F; cols++)
std::cin >> v[cols];
data2[rows] = v;
}
std::vector<float> out = predict_OLS_regressor(data2, beta);
for (size_t rows = 0; rows < T; rows++)
std::cout << out[rows] << std::endl;
return 0;
}

View File

@@ -1,37 +0,0 @@
#include <conio.h>
#include <iostream.h>
#include <math.h>
float eq(float y)
{
return ((3 * y) - (cos(y)) - 2);
}
float eqd(float y)
{
return ((0.5) * ((cos(y)) + 2));
}
void main()
{
float y, x1, x2, x3, sum, s, a, f1, f2, gd;
int i, n;
clrscr();
for (i = 0; i < 10; i++)
{
sum = eq(y);
cout << "value of equation at " << i << " " << sum << "\n";
y++;
}
cout << "enter the x1->";
cin >> x1;
cout << "enter the no iteration to perform->\n";
cin >> n;
for (i = 0; i <= n; i++)
{
x2 = eqd(x1);
cout << "\nenter the x2->" << x2;
x1 = x2;
}
getch();
}

View File

@@ -1,176 +0,0 @@
#include <iostream>
#include <queue>
using namespace std;
typedef struct node
{
int data;
int height;
struct node *left;
struct node *right;
} node;
int max(int a, int b)
{
return a > b ? a : b;
}
// Returns a new Node
node *createNode(int data)
{
node *nn = new node();
nn->data = data;
nn->height = 0;
nn->left = NULL;
nn->right = NULL;
return nn;
}
// Returns height of tree
int height(node *root)
{
if (root == NULL)
return 0;
return 1 + max(height(root->left), height(root->right));
}
// Returns difference between height of left and right subtree
int getBalance(node *root)
{
return height(root->left) - height(root->right);
}
// Returns Node after Right Rotation
node *rightRotate(node *root)
{
node *t = root->left;
node *u = t->right;
t->right = root;
root->left = u;
return t;
}
// Returns Node after Left Rotation
node *leftRotate(node *root)
{
node *t = root->right;
node *u = t->left;
t->left = root;
root->right = u;
return t;
}
// Returns node with minimum value in the tree
node *minValue(node *root)
{
if (root->left == NULL)
return root;
return minValue(root->left);
}
// Balanced Insertion
node *insert(node *root, int item)
{
node *nn = createNode(item);
if (root == NULL)
return nn;
if (item < root->data)
root->left = insert(root->left, item);
else
root->right = insert(root->right, item);
int b = getBalance(root);
if (b > 1)
{
if (getBalance(root->left) < 0)
root->left = leftRotate(root->left); // Left-Right Case
return rightRotate(root); // Left-Left Case
}
else if (b < -1)
{
if (getBalance(root->right) > 0)
root->right = rightRotate(root->right); // Right-Left Case
return leftRotate(root); // Right-Right Case
}
return root;
}
// Balanced Deletion
node *deleteNode(node *root, int key)
{
if (root == NULL)
return root;
if (key < root->data)
root->left = deleteNode(root->left, key);
else if (key > root->data)
root->right = deleteNode(root->right, key);
else
{
// Node to be deleted is leaf node or have only one Child
if (!root->right)
{
node *temp = root->left;
delete (root);
root = NULL;
return temp;
}
else if (!root->left)
{
node *temp = root->right;
delete (root);
root = NULL;
return temp;
}
// Node to be deleted have both left and right subtrees
node *temp = minValue(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
// Balancing Tree after deletion
return root;
}
// LevelOrder (Breadth First Search)
void levelOrder(node *root)
{
queue<node *> q;
q.push(root);
while (!q.empty())
{
root = q.front();
cout << root->data << " ";
q.pop();
if (root->left)
q.push(root->left);
if (root->right)
q.push(root->right);
}
}
int main()
{
// Testing AVL Tree
node *root = NULL;
int i;
for (i = 1; i <= 7; i++)
root = insert(root, i);
cout << "LevelOrder: ";
levelOrder(root);
root = deleteNode(root, 1); // Deleting key with value 1
cout << "\nLevelOrder: ";
levelOrder(root);
root = deleteNode(root, 4); // Deletin key with value 4
cout << "\nLevelOrder: ";
levelOrder(root);
return 0;
}

View File

@@ -1,218 +0,0 @@
#include <iostream>
using namespace std;
struct node
{
int val;
node *left;
node *right;
};
struct queue
{
node *t[100];
int front;
int rear;
};
queue q;
void enqueue(node *n)
{
q.t[q.rear++] = n;
}
node *dequeue()
{
return (q.t[q.front++]);
}
void Insert(node *n, int x)
{
if (x < n->val)
{
if (n->left == NULL)
{
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->left = temp;
}
else
{
Insert(n->left, x);
}
}
else
{
if (n->right == NULL)
{
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->left = temp;
}
else
{
Insert(n->right, x);
}
}
}
int findMaxInLeftST(node *n)
{
while (n->right != NULL)
{
n = n->right;
}
return n->val;
}
void Remove(node *p, node *n, int x)
{
if (n->val == x)
{
if (n->right == NULL && n->left == NULL)
{
if (x < p->val)
{
p->right = NULL;
}
else
{
p->left = NULL;
}
}
else if (n->right == NULL)
{
if (x < p->val)
{
p->right = n->left;
}
else
{
p->left = n->left;
}
}
else if (n->left == NULL)
{
if (x < p->val)
{
p->right = n->right;
}
else
{
p->left = n->right;
}
}
else
{
int y = findMaxInLeftST(n->left);
n->val = y;
Remove(n, n->right, y);
}
}
else if (x < n->val)
{
Remove(n, n->left, x);
}
else
{
Remove(n, n->right, x);
}
}
void BFT(node *n)
{
if (n != NULL)
{
cout << n->val << " ";
enqueue(n->left);
enqueue(n->right);
BFT(dequeue());
}
}
void Pre(node *n)
{
if (n != NULL)
{
cout << n->val << " ";
Pre(n->left);
Pre(n->right);
}
}
void In(node *n)
{
if (n != NULL)
{
In(n->left);
cout << n->val << " ";
In(n->right);
}
}
void Post(node *n)
{
if (n != NULL)
{
Post(n->left);
Post(n->right);
cout << n->val << " ";
}
}
int main()
{
q.front = 0;
q.rear = 0;
int value;
int ch;
node *root = new node;
cout << "\nEnter the value of root node :";
cin >> value;
root->val = value;
root->left = NULL;
root->right = NULL;
do
{
cout << "\n1. Insert";
cout << "\n2. Delete";
cout << "\n3. Breadth First";
cout << "\n4. Preorder Depth First";
cout << "\n5. Inorder Depth First";
cout << "\n6. Postorder Depth First";
cout << "\nEnter Your Choice : ";
cin >> ch;
int x;
switch (ch)
{
case 1:
cout << "\nEnter the value to be Inserted : ";
cin >> x;
Insert(root, x);
break;
case 2:
cout << "\nEnter the value to be Deleted : ";
cin >> x;
Remove(root, root, x);
break;
case 3:
BFT(root);
break;
case 4:
Pre(root);
break;
case 5:
In(root);
break;
case 6:
Post(root);
break;
}
} while (ch != 0);
}

View File

@@ -1,158 +0,0 @@
// A C++ program to demonstrate common Binary Heap Operations
#include <iostream>
#include <climits>
using namespace std;
// Prototype of a utility function to swap two integers
void swap(int *x, int *y);
// A class for Min Heap
class MinHeap
{
int *harr; // pointer to array of elements in heap
int capacity; // maximum possible size of min heap
int heap_size; // Current number of elements in min heap
public:
// Constructor
MinHeap(int capacity);
// to heapify a subtree with the root at given index
void MinHeapify(int);
int parent(int i) { return (i - 1) / 2; }
// to get index of left child of node at index i
int left(int i) { return (2 * i + 1); }
// to get index of right child of node at index i
int right(int i) { return (2 * i + 2); }
// to extract the root which is the minimum element
int extractMin();
// Decreases key value of key at index i to new_val
void decreaseKey(int i, int new_val);
// Returns the minimum key (key at root) from min heap
int getMin() { return harr[0]; }
// Deletes a key stored at index i
void deleteKey(int i);
// Inserts a new key 'k'
void insertKey(int k);
};
// Constructor: Builds a heap from a given array a[] of given size
MinHeap::MinHeap(int cap)
{
heap_size = 0;
capacity = cap;
harr = new int[cap];
}
// Inserts a new key 'k'
void MinHeap::insertKey(int k)
{
if (heap_size == capacity)
{
cout << "\nOverflow: Could not insertKey\n";
return;
}
// First insert the new key at the end
heap_size++;
int i = heap_size - 1;
harr[i] = k;
// Fix the min heap property if it is violated
while (i != 0 && harr[parent(i)] > harr[i])
{
swap(&harr[i], &harr[parent(i)]);
i = parent(i);
}
}
// Decreases value of key at index 'i' to new_val. It is assumed that
// new_val is smaller than harr[i].
void MinHeap::decreaseKey(int i, int new_val)
{
harr[i] = new_val;
while (i != 0 && harr[parent(i)] > harr[i])
{
swap(&harr[i], &harr[parent(i)]);
i = parent(i);
}
}
// Method to remove minimum element (or root) from min heap
int MinHeap::extractMin()
{
if (heap_size <= 0)
return INT_MAX;
if (heap_size == 1)
{
heap_size--;
return harr[0];
}
// Store the minimum value, and remove it from heap
int root = harr[0];
harr[0] = harr[heap_size - 1];
heap_size--;
MinHeapify(0);
return root;
}
// This function deletes key at index i. It first reduced value to minus
// infinite, then calls extractMin()
void MinHeap::deleteKey(int i)
{
decreaseKey(i, INT_MIN);
extractMin();
}
// A recursive method to heapify a subtree with the root at given index
// This method assumes that the subtrees are already heapified
void MinHeap::MinHeapify(int i)
{
int l = left(i);
int r = right(i);
int smallest = i;
if (l < heap_size && harr[l] < harr[i])
smallest = l;
if (r < heap_size && harr[r] < harr[smallest])
smallest = r;
if (smallest != i)
{
swap(&harr[i], &harr[smallest]);
MinHeapify(smallest);
}
}
// A utility function to swap two elements
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
// Driver program to test above functions
int main()
{
MinHeap h(11);
h.insertKey(3);
h.insertKey(2);
h.deleteKey(1);
h.insertKey(15);
h.insertKey(5);
h.insertKey(4);
h.insertKey(45);
cout << h.extractMin() << " ";
cout << h.getMin() << " ";
h.decreaseKey(2, 1);
cout << h.getMin();
return 0;
}

View File

@@ -1,188 +0,0 @@
#include <iostream>
using namespace std;
struct list
{
int data[50];
int top = 0;
bool isSorted = false;
int BinarySearch(int *array, int first, int last, int x)
{
if (last < first)
{
return -1;
}
int mid = (first + last) / 2;
if (array[mid] == x)
return mid;
else if (x < array[mid])
return (BinarySearch(array, first, mid - 1, x));
else if (x > array[mid])
return (BinarySearch(array, mid + 1, last, x));
}
int LinarSearch(int *array, int x)
{
for (int i = 0; i < top; i++)
{
if (array[i] == x)
{
return i;
}
}
return -1;
}
int Search(int x)
{
int pos = -1;
if (isSorted)
{
pos = BinarySearch(data, 0, top - 1, x);
}
else
{
pos = LinarSearch(data, x);
}
if (pos != -1)
{
cout << "\nElement found at position : " << pos;
}
else
{
cout << "\nElement not found";
}
return pos;
}
void Sort()
{
int i, j, pos;
for (i = 0; i < top; i++)
{
int min = data[i];
for (j = i + 1; j < top; j++)
{
if (data[j] < min)
{
pos = j;
min = data[pos];
}
}
int temp = data[i];
data[i] = data[pos];
data[pos] = temp;
}
isSorted = true;
}
void insert(int x)
{
if (!isSorted)
{
if (top == 49)
{
cout << "\nOverflow";
}
else
{
data[top] = x;
top++;
}
}
else
{
int pos = 0;
for (int i = 0; i < top - 1; i++)
{
if (data[i] <= x && x <= data[i + 1])
{
pos = i + 1;
break;
}
}
if (pos == 0)
{
pos = top - 1;
}
for (int i = top; i > pos; i--)
{
data[i] = data[i - 1];
}
top++;
data[pos] = x;
}
}
void Remove(int x)
{
int pos = Search(x);
cout << "\n"
<< data[pos] << " deleted";
for (int i = pos; i < top; i++)
{
data[i] = data[i + 1];
}
top--;
}
void Show()
{
for (int i = 0; i < top; i++)
{
cout << data[i] << "\t";
}
}
};
int main()
{
list L;
int choice;
int x;
do
{
cout << "\n1.Insert";
cout << "\n2.Delete";
cout << "\n3.Search";
cout << "\n4.Sort";
cout << "\n5.Print";
cout << "\n\nEnter Your Choice : ";
cin >> choice;
switch (choice)
{
case 1:
cout << "\nEnter the element to be inserted : ";
cin >> x;
L.insert(x);
break;
case 2:
cout << "\nEnter the element to be removed : ";
cin >> x;
L.Remove(x);
break;
case 3:
cout << "\nEnter the element to be searched : ";
cin >> x;
L.Search(x);
break;
case 4:
L.Sort();
break;
case 5:
L.Show();
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -1,108 +0,0 @@
#include <iostream>
#include <queue>
/**************************
@author shrutisheoran
**************************/
using namespace std;
struct Btree
{
int data;
struct Btree *left; //Pointer to left subtree
struct Btree *right; //Pointer to right subtree
};
void insert(Btree **root, int d)
{
Btree *nn = new Btree(); //Creating new node
nn->data = d;
nn->left = NULL;
nn->right = NULL;
if (*root == NULL)
{
*root = nn;
return;
}
else
{
queue<Btree *> q;
// Adding root node to queue
q.push(*root);
while (!q.empty())
{
Btree *node = q.front();
// Removing parent node from queue
q.pop();
if (node->left)
// Adding left child of removed node to queue
q.push(node->left);
else
{
// Adding new node if no left child is present
node->left = nn;
return;
}
if (node->right)
// Adding right child of removed node to queue
q.push(node->right);
else
{
// Adding new node if no right child is present
node->right = nn;
return;
}
}
}
}
void morrisInorder(Btree *root)
{
Btree *curr = root;
Btree *temp;
while (curr)
{
if (curr->left == NULL)
{
cout << curr->data << " ";
// If left of current node is NULL then curr is shifted to right
curr = curr->right;
}
else
{
// Left of current node is stored in temp
temp = curr->left;
// Moving to extreme right of temp
while (temp->right && temp->right != curr)
temp = temp->right;
// If extreme right is null it is made to point to currrent node (will be used for backtracking)
if (temp->right == NULL)
{
temp->right = curr;
// current node is made to point its left subtree
curr = curr->left;
}
// If extreme right already points to currrent node it it set to null
else if (temp->right == curr)
{
cout << curr->data << " ";
temp->right = NULL;
// current node is made to point its right subtree
curr = curr->right;
}
}
}
}
int main()
{
// Testing morrisInorder funtion
Btree *root = NULL;
int i;
for (i = 1; i <= 7; i++)
insert(&root, i);
cout << "Morris Inorder: ";
morrisInorder(root);
return 0;
}

View File

@@ -1,75 +0,0 @@
#include <iostream>
using namespace std;
int queue[10];
int front = 0;
int rear = 0;
void Enque(int x)
{
if (rear == 10)
{
cout << "\nOverflow";
}
else
{
queue[rear++] = x;
}
}
void Deque()
{
if (front == rear)
{
cout << "\nUnderflow";
}
else
{
cout << "\n"
<< queue[front++] << " deleted";
for (int i = front; i < rear; i++)
{
queue[i - front] = queue[i];
}
rear = rear - front;
front = 0;
}
}
void show()
{
for (int i = front; i < rear; i++)
{
cout << queue[i] << "\t";
}
}
int main()
{
int ch, x;
do
{
cout << "\n1. Enque";
cout << "\n2. Deque";
cout << "\n3. Print";
cout << "\nEnter Your Choice : ";
cin >> ch;
if (ch == 1)
{
cout << "\nInsert : ";
cin >> x;
Enque(x);
}
else if (ch == 2)
{
Deque();
}
else if (ch == 3)
{
show();
}
} while (ch != 0);
return 0;
}

View File

@@ -1,79 +0,0 @@
#include <iostream>
using namespace std;
int *stack;
int top = 0, size;
void push(int x)
{
if (top == size)
{
cout << "\nOverflow";
}
else
{
stack[top++] = x;
}
}
void pop()
{
if (top == 0)
{
cout << "\nUnderflow";
}
else
{
cout << "\n"
<< stack[--top] << " deleted";
}
}
void show()
{
for (int i = 0; i < top; i++)
{
cout << stack[i] << "\n";
}
}
void topmost()
{
cout << "\nTopmost element: " << stack[top - 1];
}
int main()
{
cout << "\nEnter Size of stack : ";
cin >> size;
stack = new int[size];
int ch, x;
do
{
cout << "\n1. Push";
cout << "\n2. Pop";
cout << "\n3. Print";
cout << "\n4. Print topmost element:";
cout << "\nEnter Your Choice : ";
cin >> ch;
if (ch == 1)
{
cout << "\nInsert : ";
cin >> x;
push(x);
}
else if (ch == 2)
{
pop();
}
else if (ch == 3)
{
show();
}
else if (ch == 4)
{
topmost();
}
} while (ch != 0);
return 0;
}

View File

@@ -1,73 +0,0 @@
#include <iostream>
using namespace std;
struct node
{
int val;
node *next;
};
node *top;
void push(int x)
{
node *n = new node;
n->val = x;
n->next = top;
top = n;
}
void pop()
{
if (top == NULL)
{
cout << "\nUnderflow";
}
else
{
node *t = top;
cout << "\n"
<< t->val << " deleted";
top = top->next;
delete t;
}
}
void show()
{
node *t = top;
while (t != NULL)
{
cout << t->val << "\n";
t = t->next;
}
}
int main()
{
int ch, x;
do
{
cout << "\n1. Push";
cout << "\n2. Pop";
cout << "\n3. Print";
cout << "\nEnter Your Choice : ";
cin >> ch;
if (ch == 1)
{
cout << "\nInsert : ";
cin >> x;
push(x);
}
else if (ch == 2)
{
pop();
}
else if (ch == 3)
{
show();
}
} while (ch != 0);
return 0;
}

View File

@@ -1,45 +0,0 @@
/*
* Simple data structure CLL (Cicular Linear Linked List)
* */
#include <cstring>
#include <cctype>
#include <iostream>
#include <cstdlib>
#ifndef CLL_H
#define CLL_H
/*The data structure is a linear linked list of integers */
struct node
{
int data;
node * next;
};
class cll
{
public:
cll(); /* Construct without parameter */
~cll();
void display(); /* Show the list */
/******************************************************
* Useful method for list
*******************************************************/
void insert_front(int new_data); /* Insert a new value at head */
void insert_tail(int new_data); /* Insert a new value at tail */
int get_size(); /* Get total element in list */
bool find_item(int item_to_find); /* Find an item in list */
/******************************************************
* Overloading method for list
*******************************************************/
int operator*(); /* Returns the info contained in head */
/* Overload the pre-increment operator.
The iterator is advanced to the next node. */
void operator++();
protected:
node * head;
int total; /* Total element in a list */
};
#endif

View File

@@ -1,44 +0,0 @@
#include "cll.h"
using namespace std;
int main()
{
/* Test CLL */
cout << "----------- Test construct -----------" << endl;
cll list1;
list1.display();
cout << "----------- Test insert front -----------" << endl;
list1.insert_front(5);
cout << "After insert 5 at front: "<<endl;
list1.display();
cout << "After insert 10 3 7 at front: "<<endl;
list1.insert_front(10);
list1.insert_front(3);
list1.insert_front(7);
list1.display();
cout << "----------- Test insert tail -----------" << endl;
cout << "After insert 18 19 20 at tail: "<<endl;
list1.insert_tail(18);
list1.insert_tail(19);
list1.insert_tail(20);
list1.display();
cout << "----------- Test find item -----------" << endl;
if (list1.find_item(10))
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
if (!list1.find_item(30))
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
cout << "----------- Test * operator -----------" << endl;
int value = *list1;
cout << "Value at *list1: " << value <<endl;
cout << "----------- Test ++ operator -----------" << endl;
list1.display();
++list1;
cout << "After ++list1: " <<endl;
list1.display();
return 0;
}

View File

@@ -1,11 +0,0 @@
CC= g++
CFLAGS = -c -Wall
all: cll
cll.o: cll.cpp main_cll.cpp
$(CC) $(CFLAGS) cll.cpp main_cll.cpp
cll: cll.o
$(CC) main_cll.o cll.o -o cll
clean:
rm *o cll

View File

@@ -1,64 +0,0 @@
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
vector<int> root, rnk;
void CreateSet(int n) {
root = vector<int> (n+1);
rnk = vector<int> (n+1, 1);
for (int i = 1; i <= n; ++i) {
root[i] = i;
}
}
int Find(int x) {
if (root[x] == x) {
return x;
}
return root[x] = Find(root[x]);
}
bool InSameUnion(int x, int y) {
return Find(x) == Find(y);
}
void Union(int x, int y) {
int a = Find(x), b = Find(y);
if (a != b) {
if (rnk[a] < rnk[b]) {
root[a] = b;
} else if (rnk[a] > rnk[b]) {
root[b] = a;
} else {
root[a] = b;
++rnk[b];
}
}
}
int main() {
// tests CreateSet & Find
int n = 100;
CreateSet(n);
for (int i = 1; i <= 100; ++i) {
if (root[i] != i) {
cout << "Fail" << endl;
break;
}
}
// tests InSameUnion & Union
cout << "1 and 2 are initially not in the same subset" << endl;
if (InSameUnion(1, 2)) {
cout << "Fail" << endl;
}
Union(1, 2);
cout << "1 and 2 are now in the same subset" << endl;
if (!InSameUnion(1, 2)) {
cout << "Fail" << endl;
}
return 0;
}

View File

@@ -1,138 +0,0 @@
#include <iostream>
#include<cstdio>
#include<cstdlib>
struct node {
int val;
node *prev;
node *next;
}*start;
class double_linked_list {
public:
double_linked_list() {
start = NULL;
}
void insert(int x);
void remove(int x);
void search(int x);
void show();
void reverseShow();
};
void double_linked_list::insert(int x) {
node *t = start;
if (start != NULL) {
while (t->next != NULL) {
t = t->next;
}
node *n = new node;
t->next = n;
n->prev = t;
n->val = x;
n->next = NULL;
} else {
node *n = new node;
n->val = x;
n->prev = NULL;
n->next = NULL;
start = n;
}
}
void double_linked_list::remove(int x) {
node *t = start;
while (t != NULL && t->val != x) {
t = t-> next;
}
if (t == NULL) {
return;
}
if (t->prev == NULL) {
if (t->next == NULL) {
start = NULL;
} else {
start = t->next;
start->prev = NULL;
}
} else if (t->next == NULL) {
t->prev->next = NULL;
} else {
t->prev->next = t->next;
t->next->prev = t->prev;
}
delete t;
}
void double_linked_list::search(int x) {
node *t = start;
int found = 0;
while (t != NULL) {
if (t->val == x) {
std::cout << "\nFound";
found = 1;
break;
}
t = t->next;
}
if (found == 0) {
std::cout << "\nNot Found";
}
}
void double_linked_list::show() {
node *t = start;
while (t != NULL) {
std::cout << t->val << "\t";
t = t->next;
}
}
void double_linked_list::reverseShow() {
node *t = start;
while (t != NULL && t->next != NULL) {
t = t->next;
}
while (t != NULL) {
std::cout << t->val << "\t";
t = t->prev;
}
}
int main() {
int choice, x;
double_linked_list ob;
do {
std::cout << "\n1. Insert";
std::cout << "\n2. Delete";
std::cout << "\n3. Search";
std::cout << "\n4. Forward print";
std::cout << "\n5. Reverse print";
std::cout << "\n\nEnter you choice : ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "\nEnter the element to be inserted : ";
std::cin >> x;
ob.insert(x);
break;
case 2:
std::cout << "\nEnter the element to be removed : ";
std::cin >> x;
ob.remove(x);
break;
case 3:
std::cout << "\nEnter the element to be searched : ";
std::cin >> x;
ob.search(x);
break;
case 4:
ob.show();
break;
case 5:
ob.reverseShow();
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -1,106 +0,0 @@
/* The difference between the pointer implementation of linked list and array implementation of linked list:
1. The NULL is represented by -1;
2. Limited size. (in the following case it is 100 nodes at max). But we can reuse the nodes that are to be deleted by again linking it bacj to the list.
*/
#include <iostream>
using namespace std;
struct Node
{
int data;
int next;
};
Node AvailArray[100]; //array that will act as nodes of a linked list.
int head = -1;
int avail = 0;
void initialise_list()
{
for (int i = 0; i <= 98; i++)
{
AvailArray[i].next = i + 1;
}
AvailArray[99].next = -1; //indicating the end of the linked list.
}
int getnode() //This will return the index of the first free node present in the avail list
{
int NodeIndexToBeReturned = avail;
avail = AvailArray[avail].next;
return NodeIndexToBeReturned;
}
void freeNode(int nodeToBeDeleted) //This function when called will delete the node with the index presented as an argument, and will put back that node into the array.
{
AvailArray[nodeToBeDeleted].next = avail;
avail = nodeToBeDeleted;
}
void insertAtTheBeginning(int data) //The function will insert the given data into the front of the linked list.
{
int newNode = getnode();
AvailArray[newNode].data = data;
AvailArray[newNode].next = head;
head = newNode;
}
void insertAtTheEnd(int data)
{
int newNode = getnode();
int temp = head;
while (AvailArray[temp].next != -1)
{
temp = AvailArray[temp].next;
}
//temp is now pointing to the end node.
AvailArray[newNode].data = data;
AvailArray[newNode].next = -1;
AvailArray[temp].next = newNode;
}
void display()
{
int temp = head;
while (temp != -1)
{
cout << AvailArray[temp].data << "->";
temp = AvailArray[temp].next;
}
cout << "-1" << endl;
;
}
int main()
{
initialise_list();
int x, y, z;
for (;;)
{
cout << "1. Insert At The Beginning" << endl;
cout << "2. Insert At The End" << endl;
cout << "3. Display" << endl;
cout << "4.Exit" << endl;
cout << "Enter Your choice" << endl;
cin >> z;
switch (z)
{
case 1:
cout << "Enter the number you want to enter" << endl;
cin >> x;
insertAtTheBeginning(x);
break;
case 2:
cout << "Enter the number you want to enter" << endl;
cin >> y;
insertAtTheEnd(y);
break;
case 3:
cout << "The linked list contains the following element in order" << endl;
display();
break;
case 4:
exit(0);
default:
cout << "The entered choice is not correct" << endl;
}
}
}

View File

@@ -1,135 +0,0 @@
#include <iostream>
struct node {
int val;
node *next;
};
node *start;
void insert(int x) {
node *t = start;
node *n = new node;
n->val = x;
n->next = NULL;
if (start != NULL) {
while (t->next != NULL) {
t = t->next;
}
t->next = n;
} else {
start = n;
}
}
void remove(int x) {
if (start == NULL) {
std::cout << "\nLinked List is empty\n";
return;
} else if (start->val == x) {
node *temp = start;
start = start->next;
delete temp;
return;
}
node *temp = start, *parent = start;
while (temp != NULL && temp->val != x) {
parent = temp;
temp = temp->next;
}
if (temp == NULL) {
std::cout << std::endl << x << " not found in list\n";
return;
}
parent->next = temp->next;
delete temp;
}
void search(int x) {
node *t = start;
int found = 0;
while (t != NULL) {
if (t->val == x) {
std::cout << "\nFound";
found = 1;
break;
}
t = t->next;
}
if (found == 0) {
std::cout << "\nNot Found";
}
}
void show() {
node *t = start;
while (t != NULL) {
std::cout << t->val << "\t";
t = t->next;
}
}
void reverse() {
node *first = start;
if (first != NULL) {
node *second = first->next;
while (second != NULL) {
node *tem = second->next;
second->next = first;
first = second;
second = tem;
}
start->next = NULL;
start = first;
} else {
std::cout << "\nEmpty list";
}
}
int main() {
int choice, x;
do {
std::cout << "\n1. Insert";
std::cout << "\n2. Delete";
std::cout << "\n3. Search";
std::cout << "\n4. Print";
std::cout << "\n5. Reverse";
std::cout << "\n0. Exit";
std::cout << "\n\nEnter you choice : ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "\nEnter the element to be inserted : ";
std::cin >> x;
insert(x);
break;
case 2:
std::cout << "\nEnter the element to be removed : ";
std::cin >> x;
remove(x);
break;
case 3:
std::cout << "\nEnter the element to be searched : ";
std::cin >> x;
search(x);
break;
case 4:
show();
std::cout << "\n";
break;
case 5:
std::cout << "The reversed list: \n";
reverse();
show();
std::cout << "\n";
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -1,11 +0,0 @@
CC= g++
CFLAGS = -c -Wall
all: test_queue
queue.o: queue.cpp
$(CC) $(CFLAGS) queue.cpp
test_queue: queue.o
$(CC) test_queue.cpp queue.o -o queue
clean:
rm *o queue

View File

@@ -1,90 +0,0 @@
#include <iostream>
#include <assert.h>
#include "queue.h"
using namespace std;
/* Default constructor*/
template <class Kind>
queue<Kind>::queue()
{
queueFront = NULL;
queueRear = NULL;
size = 0;
}
/* Destructor */
template <class Kind>
queue<Kind>::~queue()
{
}
/* Display for testing */
template <class Kind>
void queue<Kind>::display()
{
node<Kind> *current = queueFront;
cout << "Front --> ";
while(current != NULL) {
cout<<current->data<< " ";
current = current -> next;
}
cout <<endl;
cout << "Size of queue: " << size << endl;
}
/* Determine whether the queue is empty */
template <class Kind>
bool queue<Kind>::isEmptyQueue()
{
return (queueFront == NULL);
}
/* Clear queue */
template <class Kind>
void queue<Kind>::clear()
{
queueFront = NULL;
}
/* Add new item to the queue */
template <class Kind>
void queue<Kind>::enQueue(Kind item)
{
node<Kind> *newNode;
newNode = new node<Kind>;
newNode->data = item;
newNode->next = NULL;
if (queueFront == NULL) {
queueFront = newNode;
queueRear = newNode;
} else {
queueRear->next = newNode;
queueRear = queueRear->next;
}
size++;
}
/* Return the top element of the queue */
template <class Kind>
Kind queue<Kind>::front()
{
assert(queueFront != NULL);
return queueFront->data;
}
/* Remove the element of the queue */
template <class Kind>
void queue<Kind>::deQueue()
{
node<Kind> *temp;
if(!isEmptyQueue()) {
temp = queueFront;
queueFront = queueFront->next;
delete temp;
size--;
} else {
cout << "Queue is empty !" << endl;
}
}

View File

@@ -1,34 +0,0 @@
/* This class specifies the basic operation on a queue as a linked list */
#ifndef QUEUE_H
#define QUEUE_H
/* Definition of the node */
template <class Kind>
struct node
{
Kind data;
node<Kind> *next;
};
/* Definition of the queue class */
template <class Kind>
class queue
{
public:
void display(); /* Show queue */
queue(); /* Default constructor*/
~queue(); /* Destructor */
bool isEmptyQueue(); /* Determine whether the queue is empty */
void enQueue (Kind item); /* Add new item to the queue */
Kind front(); /* Return the first element of the queue */
void deQueue(); /* Remove the top element of the queue */
void clear();
private:
node<Kind> *queueFront; /* Pointer to the front of the queue */
node<Kind> *queueRear; /* Pointer to the rear of the queue */
int size;
};
#endif

View File

@@ -1,38 +0,0 @@
#include <iostream>
#include <string>
#include "queue.h"
#include "queue.cpp"
using namespace std;
int main()
{
queue<string> q;
cout << "---------------------- Test construct ----------------------" << endl;
q.display();
cout << "---------------------- Test isEmptyQueue ----------------------" << endl;
if(q.isEmptyQueue())
cout << "PASS" <<endl;
else
cout << "FAIL" <<endl;
cout << "---------------------- Test enQueue ----------------------" << endl;
cout << "After Hai, Jeff, Tom, Jkingston go into queue: "<<endl;
q.enQueue("Hai");
q.enQueue("Jeff");
q.enQueue("Tom");
q.enQueue("Jkingston");
q.display();
cout << "---------------------- Test front ----------------------" << endl;
string value = q.front();
if (value == "Hai")
cout << "PASS" <<endl;
else
cout << "FAIL" <<endl;
cout << "---------------------- Test deQueue ----------------------" << endl;
q.display();
q.deQueue();
q.deQueue();
cout << "After Hai, Jeff left the queue: "<< endl;
q.display();
return 0;
}

View File

@@ -1,98 +0,0 @@
/*
Write a program to implement Queue using linkedlist.
*/
#include<iostream>
struct linkedlist{
int data;
linkedlist *next;
};
class stack_linkedList{
public:
linkedlist *front;
linkedlist *rear;
stack_linkedList(){
front=rear=NULL;
}
void enqueue(int);
int dequeue();
void display();
};
void stack_linkedList::enqueue(int ele){
linkedlist *temp=new linkedlist();
temp->data=ele;
temp->next=NULL;
if(front==NULL)
front=rear=temp;
else{
rear->next=temp;
rear=temp;
}
}
int stack_linkedList::dequeue(){
linkedlist *temp;
int ele;
if(front==NULL)
std::cout<<"\nStack is empty";
else{
temp=front;
ele=temp->data;
if(front==rear) //if length of queue is 1;
rear=rear->next;
front=front->next;
delete(temp);
}
return ele;
}
void stack_linkedList::display(){
if(front==NULL)
std::cout<<"\nStack is empty";
else {
linkedlist *temp;
temp=front;
while(temp!=NULL){
std::cout<<temp->data<<" ";
temp=temp->next;
}
}
}
int main(){
int op,data;
stack_linkedList ob;
std::cout<<"\n1. enqueue(Insertion) ";
std::cout<<"\n2. dequeue(Deletion)";
std::cout<<"\n3. Display";
std::cout<<"\n4. Exit";
while(1){
std::cout<<"\nEnter your choice ";
std::cin>>op;
if(op==1)
{
std::cout<<"Enter data ";
std::cin>>data;
ob.enqueue(data);
}
else if(op==2)
data=ob.dequeue();
else if(op==3)
ob.display();
else if(op==4)
exit(0);
else
std::cout<<"\nWrong choice ";
}
return 0;
}

View File

@@ -1,13 +0,0 @@
CC= g++
CFLAGS = -c -Wall
all: main test_stack
stack.o: stack.cpp
$(CC) $(CFLAGS) stack.cpp
test_stack: stack.o
$(CC) test_stack.cpp stack.o -o stk
main: stack.o
$(CC) main.cpp stack.o -o main
clean:
rm *o stk main

View File

@@ -1,114 +0,0 @@
#include <iostream>
#include <assert.h>
#include "stack.h"
using namespace std;
/* Default constructor*/
template <class Type>
stack<Type>::stack()
{
stackTop = NULL;
size = 0;
}
/* Destructor */
template <class Type>
stack<Type>::~stack()
{
}
/* Display for testing */
template <class Type>
void stack<Type>::display()
{
node<Type> *current = stackTop;
cout << "Top --> ";
while(current != NULL) {
cout<<current->data<< " ";
current = current -> next;
}
cout <<endl;
cout << "Size of stack: " << size << endl;
}
/* Determine whether the stack is empty */
template <class Type>
bool stack<Type>::isEmptyStack()
{
return (stackTop == NULL);
}
/* Clear stack */
template <class Type>
void stack<Type>::clear()
{
stackTop = NULL;
}
/* Add new item to the stack */
template <class Type>
void stack<Type>::push(Type item)
{
node<Type> *newNode;
newNode = new node<Type>;
newNode->data = item;
newNode->next = stackTop;
stackTop = newNode;
size++;
}
/* Return the top element of the stack */
template <class Type>
Type stack<Type>::top()
{
assert(stackTop != NULL);
return stackTop->data;
}
/* Remove the top element of the stack */
template <class Type>
void stack<Type>::pop()
{
node<Type> *temp;
if(!isEmptyStack()) {
temp = stackTop;
stackTop = stackTop->next;
delete temp;
size--;
} else {
cout << "Stack is empty !" << endl;
}
}
/* Operator "=" */
template <class Type>
stack<Type> stack<Type>::operator=(stack<Type> & otherStack)
{
node<Type> *newNode, *current, *last;
if (stackTop != NULL) /* If stack is no empty, make it empty */
stackTop = NULL;
if (otherStack.stackTop == NULL)
stackTop = NULL;
else {
current = otherStack.stackTop;
stackTop = new node<Type>;
stackTop->data = current->data;
stackTop->next = NULL;
last = stackTop;
current = current ->next;
/* Copy the remaining stack */
while (current != NULL)
{
newNode = new node<Type>;
newNode->data = current->data;
newNode->next = NULL;
last->next = newNode;
last = newNode;
current = current->next;
}
}
size = otherStack.size;
return *this;
}

View File

@@ -1,35 +0,0 @@
/* This class specifies the basic operation on a stack as a linked list */
#ifndef STACK_H
#define STACK_H
/* Definition of the node */
template <class Type>
struct node
{
Type data;
node<Type> *next;
};
/* Definition of the stack class */
template <class Type>
class stack
{
public:
void display(); /* Show stack */
stack(); /* Default constructor*/
~stack(); /* Destructor */
bool isEmptyStack(); /* Determine whether the stack is empty */
void push (Type item); /* Add new item to the stack */
Type top(); /* Return the top element of the stack */
void pop(); /* Remove the top element of the stack */
void clear();
stack<Type> operator=(stack<Type> & otherStack);
// Overload "=" the assignment operator.
private:
node<Type> *stackTop; /* Pointer to the stack */
int size;
};
#endif

View File

@@ -1,54 +0,0 @@
#include <iostream>
#include "stack.h"
#include "stack.cpp"
using namespace std;
int main()
{
stack<int> stk;
cout << "---------------------- Test construct ----------------------" << endl;
stk.display();
cout << "---------------------- Test isEmptyStack ----------------------" << endl;
if(stk.isEmptyStack())
cout << "PASS" <<endl;
else
cout << "FAIL" <<endl;
cout << "---------------------- Test push ----------------------" << endl;
cout << "After pushing 10 20 30 40 into stack: "<<endl;
stk.push(10);
stk.push(20);
stk.push(30);
stk.push(40);
stk.display();
cout << "---------------------- Test top ----------------------" << endl;
int value = stk.top();
if (value == 40)
cout << "PASS" <<endl;
else
cout << "FAIL" <<endl;
cout << "---------------------- Test pop ----------------------" << endl;
stk.display();
stk.pop();
stk.pop();
cout << "After popping 2 times: "<< endl;
stk.display();
cout << "---------------------- Test overload = operator ----------------------" << endl;
stack<int> stk1;
cout << "stk current: "<< endl;
stk.display();
cout << endl << "Assign stk1 = stk "<< endl;
stk1 = stk;
stk1.display();
cout << endl<< "After pushing 8 9 10 into stk1:" <<endl;
stk1.push(8);
stk1.push(9);
stk1.push(10);
stk1.display();
cout << endl << "stk current: " <<endl;
stk.display();
cout << "Assign back stk = stk1:" << endl;
stk = stk1;
stk.display();
return 0;
}

View File

@@ -1,90 +0,0 @@
#include <stdio.h>
#include <stdbool.h>
#include <iostream>
#include <string>
// structure definition
typedef struct trie {
struct trie * arr[26];
bool isEndofWord;
} trie;
// create a new node for trie
trie * createNode() {
trie * nn = new trie();
for (int i = 0; i < 26; i++)
nn -> arr[i] = NULL;
nn -> isEndofWord = false;
return nn;
}
// insert string into the trie
void insert(trie * root, std::string str) {
for (int i = 0; i < str.length(); i++) {
int j = str[i] - 'a';
if (root -> arr[j]) {
root = root -> arr[j];
} else {
root -> arr[j] = createNode();
root = root -> arr[j];
}
}
root -> isEndofWord = true;
}
// search a string exists inside the trie
bool search(trie * root, std::string str, int index) {
if (index == str.length()) {
if (!root -> isEndofWord)
return false;
return true;
}
int j = str[index] - 'a';
if (!root -> arr[j])
return false;
return search(root -> arr[j], str, index + 1);
}
/*
removes the string if it is not a prefix of any other
string, if it is then just sets the endofword to false, else
removes the given string
*/
bool deleteString(trie * root, std::string str, int index) {
if (index == str.length()) {
if (!root -> isEndofWord)
return false;
root -> isEndofWord = false;
for (int i = 0; i < 26; i++)
return false;
return true;
}
int j = str[index] - 'a';
if (!root -> arr[j])
return false;
bool
var = deleteString(root, str, index + 1);
if (var) {
root -> arr[j] = NULL;
if (root -> isEndofWord) {
return false;
} else {
int i;
for (i = 0; i < 26; i++)
if (root -> arr[i])
return false;
return true;
}
}
}
int main() {
trie * root = createNode();
insert(root, "hello");
insert(root, "world");
int a = search(root, "hello", 0);
int b = search(root, "word", 0);
printf("%d %d ", a, b);
return 0;
}

View File

@@ -0,0 +1,20 @@
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".cpp" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
if(OpenMP_CXX_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
endif()
install(TARGETS ${testname} DESTINATION "bin/data_structures")
endforeach( testsourcefile ${APP_SOURCES} )
add_subdirectory(cll)

148
data_structures/avltree.cpp Normal file
View File

@@ -0,0 +1,148 @@
/**
* \file
* \brief A simple tree implementation using nodes
*
* \todo update code to use C++ STL library features and OO structure
* \warning This program is a poor implementation and does not utilize any of
* the C++ STL features.
*/
#include <algorithm>
#include <iostream>
#include <queue>
typedef struct node {
int data;
int height;
struct node *left;
struct node *right;
} node;
/** Create and return a new Node */
node *createNode(int data) {
node *nn = new node();
nn->data = data;
nn->height = 0;
nn->left = NULL;
nn->right = NULL;
return nn;
}
/** Returns height of tree */
int height(node *root) {
if (root == NULL)
return 0;
return 1 + std::max(height(root->left), height(root->right));
}
/** Returns difference between height of left and right subtree */
int getBalance(node *root) { return height(root->left) - height(root->right); }
/** Returns Node after Right Rotation */
node *rightRotate(node *root) {
node *t = root->left;
node *u = t->right;
t->right = root;
root->left = u;
return t;
}
/** Returns Node after Left Rotation */
node *leftRotate(node *root) {
node *t = root->right;
node *u = t->left;
t->left = root;
root->right = u;
return t;
}
/** Returns node with minimum value in the tree */
node *minValue(node *root) {
if (root->left == NULL)
return root;
return minValue(root->left);
}
/** Balanced Insertion */
node *insert(node *root, int item) {
node *nn = createNode(item);
if (root == NULL)
return nn;
if (item < root->data)
root->left = insert(root->left, item);
else
root->right = insert(root->right, item);
int b = getBalance(root);
if (b > 1) {
if (getBalance(root->left) < 0)
root->left = leftRotate(root->left); // Left-Right Case
return rightRotate(root); // Left-Left Case
} else if (b < -1) {
if (getBalance(root->right) > 0)
root->right = rightRotate(root->right); // Right-Left Case
return leftRotate(root); // Right-Right Case
}
return root;
}
/** Balanced Deletion */
node *deleteNode(node *root, int key) {
if (root == NULL)
return root;
if (key < root->data)
root->left = deleteNode(root->left, key);
else if (key > root->data)
root->right = deleteNode(root->right, key);
else {
// Node to be deleted is leaf node or have only one Child
if (!root->right) {
node *temp = root->left;
delete (root);
root = NULL;
return temp;
} else if (!root->left) {
node *temp = root->right;
delete (root);
root = NULL;
return temp;
}
// Node to be deleted have both left and right subtrees
node *temp = minValue(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
// Balancing Tree after deletion
return root;
}
/** LevelOrder (Breadth First Search) */
void levelOrder(node *root) {
std::queue<node *> q;
q.push(root);
while (!q.empty()) {
root = q.front();
std::cout << root->data << " ";
q.pop();
if (root->left)
q.push(root->left);
if (root->right)
q.push(root->right);
}
}
/** Main function */
int main() {
// Testing AVL Tree
node *root = NULL;
int i;
for (i = 1; i <= 7; i++) root = insert(root, i);
std::cout << "LevelOrder: ";
levelOrder(root);
root = deleteNode(root, 1); // Deleting key with value 1
std::cout << "\nLevelOrder: ";
levelOrder(root);
root = deleteNode(root, 4); // Deletin key with value 4
std::cout << "\nLevelOrder: ";
levelOrder(root);
return 0;
}

View File

@@ -0,0 +1,174 @@
/**
* \file
* \brief A simple tree implementation using structured nodes
*
* \todo update code to use C++ STL library features and OO structure
* \warning This program is a poor implementation - C style - and does not
* utilize any of the C++ STL features.
*/
#include <iostream>
struct node {
int val;
node *left;
node *right;
};
struct Queue {
node *t[100];
int front;
int rear;
};
Queue queue;
void enqueue(node *n) { queue.t[queue.rear++] = n; }
node *dequeue() { return (queue.t[queue.front++]); }
void Insert(node *n, int x) {
if (x < n->val) {
if (n->left == NULL) {
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->left = temp;
} else {
Insert(n->left, x);
}
} else {
if (n->right == NULL) {
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->right = temp;
} else {
Insert(n->right, x);
}
}
}
int findMaxInLeftST(node *n) {
while (n->right != NULL) {
n = n->right;
}
return n->val;
}
void Remove(node *p, node *n, int x) {
if (n->val == x) {
if (n->right == NULL && n->left == NULL) {
if (x < p->val) {
p->right = NULL;
} else {
p->left = NULL;
}
} else if (n->right == NULL) {
if (x < p->val) {
p->right = n->left;
} else {
p->left = n->left;
}
} else if (n->left == NULL) {
if (x < p->val) {
p->right = n->right;
} else {
p->left = n->right;
}
} else {
int y = findMaxInLeftST(n->left);
n->val = y;
Remove(n, n->right, y);
}
} else if (x < n->val) {
Remove(n, n->left, x);
} else {
Remove(n, n->right, x);
}
}
void BFT(node *n) {
if (n != NULL) {
std::cout << n->val << " ";
enqueue(n->left);
enqueue(n->right);
BFT(dequeue());
}
}
void Pre(node *n) {
if (n != NULL) {
std::cout << n->val << " ";
Pre(n->left);
Pre(n->right);
}
}
void In(node *n) {
if (n != NULL) {
In(n->left);
std::cout << n->val << " ";
In(n->right);
}
}
void Post(node *n) {
if (n != NULL) {
Post(n->left);
Post(n->right);
std::cout << n->val << " ";
}
}
int main() {
queue.front = 0;
queue.rear = 0;
int value;
int ch;
node *root = new node;
std::cout << "\nEnter the value of root node :";
std::cin >> value;
root->val = value;
root->left = NULL;
root->right = NULL;
do {
std::cout << "\n1. Insert"
<< "\n2. Delete"
<< "\n3. Breadth First"
<< "\n4. Preorder Depth First"
<< "\n5. Inorder Depth First"
<< "\n6. Postorder Depth First";
std::cout << "\nEnter Your Choice : ";
std::cin >> ch;
int x;
switch (ch) {
case 1:
std::cout << "\nEnter the value to be Inserted : ";
std::cin >> x;
Insert(root, x);
break;
case 2:
std::cout << "\nEnter the value to be Deleted : ";
std::cin >> x;
Remove(root, root, x);
break;
case 3:
BFT(root);
break;
case 4:
Pre(root);
break;
case 5:
In(root);
break;
case 6:
Post(root);
break;
}
} while (ch != 0);
return 0;
}

View File

@@ -0,0 +1,142 @@
/**
* \file
* \brief A C++ program to demonstrate common Binary Heap Operations
*/
#include <climits>
#include <iostream>
#include <utility>
/** A class for Min Heap */
class MinHeap {
int *harr; ///< pointer to array of elements in heap
int capacity; ///< maximum possible size of min heap
int heap_size; ///< Current number of elements in min heap
public:
/** Constructor: Builds a heap from a given array a[] of given size
* \param[in] capacity initial heap capacity
*/
explicit MinHeap(int cap) {
heap_size = 0;
capacity = cap;
harr = new int[cap];
}
/** to heapify a subtree with the root at given index */
void MinHeapify(int);
int parent(int i) { return (i - 1) / 2; }
/** to get index of left child of node at index i */
int left(int i) { return (2 * i + 1); }
/** to get index of right child of node at index i */
int right(int i) { return (2 * i + 2); }
/** to extract the root which is the minimum element */
int extractMin();
/** Decreases key value of key at index i to new_val */
void decreaseKey(int i, int new_val);
/** Returns the minimum key (key at root) from min heap */
int getMin() { return harr[0]; }
/** Deletes a key stored at index i */
void deleteKey(int i);
/** Inserts a new key 'k' */
void insertKey(int k);
~MinHeap() { delete[] harr; }
};
// Inserts a new key 'k'
void MinHeap::insertKey(int k) {
if (heap_size == capacity) {
std::cout << "\nOverflow: Could not insertKey\n";
return;
}
// First insert the new key at the end
heap_size++;
int i = heap_size - 1;
harr[i] = k;
// Fix the min heap property if it is violated
while (i != 0 && harr[parent(i)] > harr[i]) {
std::swap(harr[i], harr[parent(i)]);
i = parent(i);
}
}
/** Decreases value of key at index 'i' to new_val. It is assumed that new_val
* is smaller than harr[i].
*/
void MinHeap::decreaseKey(int i, int new_val) {
harr[i] = new_val;
while (i != 0 && harr[parent(i)] > harr[i]) {
std::swap(harr[i], harr[parent(i)]);
i = parent(i);
}
}
// Method to remove minimum element (or root) from min heap
int MinHeap::extractMin() {
if (heap_size <= 0)
return INT_MAX;
if (heap_size == 1) {
heap_size--;
return harr[0];
}
// Store the minimum value, and remove it from heap
int root = harr[0];
harr[0] = harr[heap_size - 1];
heap_size--;
MinHeapify(0);
return root;
}
/** This function deletes key at index i. It first reduced value to minus
* infinite, then calls extractMin()
*/
void MinHeap::deleteKey(int i) {
decreaseKey(i, INT_MIN);
extractMin();
}
/** A recursive method to heapify a subtree with the root at given index
* This method assumes that the subtrees are already heapified
*/
void MinHeap::MinHeapify(int i) {
int l = left(i);
int r = right(i);
int smallest = i;
if (l < heap_size && harr[l] < harr[i])
smallest = l;
if (r < heap_size && harr[r] < harr[smallest])
smallest = r;
if (smallest != i) {
std::swap(harr[i], harr[smallest]);
MinHeapify(smallest);
}
}
// Driver program to test above functions
int main() {
MinHeap h(11);
h.insertKey(3);
h.insertKey(2);
h.deleteKey(1);
h.insertKey(15);
h.insertKey(5);
h.insertKey(4);
h.insertKey(45);
std::cout << h.extractMin() << " ";
std::cout << h.getMin() << " ";
h.decreaseKey(2, 1);
std::cout << h.getMin();
return 0;
}

View File

@@ -1,24 +1,19 @@
#include <iostream>
using namespace std;
struct node
{
struct node {
int data;
struct node *next;
};
class Queue
{
class Queue {
node *front;
node *rear;
public:
Queue()
{
public:
Queue() {
front = NULL;
rear = NULL;
}
void createNode(int val)
{
void createNode(int val) {
node *ptr;
node *nn;
nn = new node;
@@ -28,14 +23,10 @@ public:
front = nn;
rear = nn;
}
void enqueue(int val)
{
if (front == NULL || rear == NULL)
{
void enqueue(int val) {
if (front == NULL || rear == NULL) {
createNode(val);
}
else
{
} else {
node *ptr;
node *nn;
ptr = front;
@@ -46,28 +37,23 @@ public:
rear = nn;
}
}
void dequeue()
{
void dequeue() {
node *n;
n = front;
front = front->next;
delete (n);
}
void traverse()
{
void traverse() {
node *ptr;
ptr = front;
do
{
cout << ptr->data << " ";
do {
std::cout << ptr->data << " ";
ptr = ptr->next;
} while (ptr != rear->next);
cout << front->data;
cout << endl;
std::cout << front->data << std::endl;
}
};
int main(void)
{
int main(void) {
Queue q;
q.enqueue(10);
q.enqueue(20);

View File

@@ -0,0 +1,5 @@
add_executable( cll
cll.cpp
main_cll.cpp
)
install(TARGETS cll DESTINATION "bin/data_structures")

View File

@@ -5,49 +5,42 @@
using namespace std;
/* Constructor */
cll::cll()
{
cll::cll() {
head = NULL;
total = 0;
}
cll::~cll()
{
/* Desstructure, no need to fill */
cll::~cll() { /* Desstructure, no need to fill */
}
/* Display a list. and total element */
void cll::display()
{
void cll::display() {
if (head == NULL)
cout << "List is empty !" << endl;
else
{
else {
cout << "CLL list: ";
node *current = head;
for (int i = 0; i < total; i++)
{
for (int i = 0; i < total; i++) {
cout << current->data << " -> ";
current = current ->next;
current = current->next;
}
cout << head->data << endl;
cout << "Total element: "<< total <<endl;
cout << "Total element: " << total << endl;
}
}
/* List insert a new value at head in list */
void cll::insert_front(int new_data)
{
void cll::insert_front(int new_data) {
node *newNode;
newNode = new node;
newNode->data = new_data;
newNode->next = NULL;
if(head==NULL) {
if (head == NULL) {
head = newNode;
head -> next = head;
head->next = head;
} else {
node *current = head;
while (current -> next != head) {
while (current->next != head) {
current = current->next;
}
newNode->next = head;
@@ -58,18 +51,17 @@ void cll::insert_front(int new_data)
}
/* List insert a new value at head in list */
void cll::insert_tail(int new_data)
{
void cll::insert_tail(int new_data) {
node *newNode;
newNode = new node;
newNode->data = new_data;
newNode->next = NULL;
if(head==NULL) {
if (head == NULL) {
head = newNode;
head -> next = head;
head->next = head;
} else {
node *current = head;
while (current -> next != head) {
while (current->next != head) {
current = current->next;
}
current->next = newNode;
@@ -79,22 +71,17 @@ void cll::insert_tail(int new_data)
}
/* Get total element in list */
int cll::get_size()
{
return total;
}
int cll::get_size() { return total; }
/* Return true if the requested item (sent in as an argument)
is in the list, otherwise return false */
bool cll::find_item(int item_to_find)
{
bool cll::find_item(int item_to_find) {
if (head == NULL) {
cout << "List is empty !" << endl;
return false;
} else {
node *current = head;
while (current -> next != head) {
while (current->next != head) {
if (current->data == item_to_find)
return true;
current = current->next;
@@ -104,24 +91,20 @@ bool cll::find_item(int item_to_find)
}
/* Overloading method*/
int cll::operator*()
{
return head->data;
}
int cll::operator*() { return head->data; }
/* Overload the pre-increment operator.
The iterator is advanced to the next node. */
void cll::operator++()
{
void cll::operator++() {
if (head == NULL) {
cout << "List is empty !" << endl;
} else {
node *current = head;
while (current -> next != head) {
current = current -> next;
while (current->next != head) {
current = current->next;
}
current->next = head -> next;
head = head -> next;
current->next = head->next;
head = head->next;
}
total--;
}

43
data_structures/cll/cll.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* Simple data structure CLL (Cicular Linear Linked List)
* */
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <iostream>
#ifndef CLL_H
#define CLL_H
/*The data structure is a linear linked list of integers */
struct node {
int data;
node* next;
};
class cll {
public:
cll(); /* Construct without parameter */
~cll();
void display(); /* Show the list */
/******************************************************
* Useful method for list
*******************************************************/
void insert_front(int new_data); /* Insert a new value at head */
void insert_tail(int new_data); /* Insert a new value at tail */
int get_size(); /* Get total element in list */
bool find_item(int item_to_find); /* Find an item in list */
/******************************************************
* Overloading method for list
*******************************************************/
int operator*(); /* Returns the info contained in head */
/* Overload the pre-increment operator.
The iterator is advanced to the next node. */
void operator++();
protected:
node* head;
int total; /* Total element in a list */
};
#endif

View File

@@ -0,0 +1,43 @@
#include "cll.h"
using namespace std;
int main() {
/* Test CLL */
cout << "----------- Test construct -----------" << endl;
cll list1;
list1.display();
cout << "----------- Test insert front -----------" << endl;
list1.insert_front(5);
cout << "After insert 5 at front: " << endl;
list1.display();
cout << "After insert 10 3 7 at front: " << endl;
list1.insert_front(10);
list1.insert_front(3);
list1.insert_front(7);
list1.display();
cout << "----------- Test insert tail -----------" << endl;
cout << "After insert 18 19 20 at tail: " << endl;
list1.insert_tail(18);
list1.insert_tail(19);
list1.insert_tail(20);
list1.display();
cout << "----------- Test find item -----------" << endl;
if (list1.find_item(10))
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
if (!list1.find_item(30))
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
cout << "----------- Test * operator -----------" << endl;
int value = *list1;
cout << "Value at *list1: " << value << endl;
cout << "----------- Test ++ operator -----------" << endl;
list1.display();
++list1;
cout << "After ++list1: " << endl;
list1.display();
return 0;
}

View File

@@ -0,0 +1,114 @@
/**
*
* \file
* \brief [Disjoint Sets Data Structure
* (Disjoint Sets)](https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
*
* \author [leoyang429](https://github.com/leoyang429)
*
* \details
* A disjoint set data structure (also called union find or merge find set)
* is a data structure that tracks a set of elements partitioned into a number
* of disjoint (non-overlapping) subsets.
* Some situations where disjoint sets can be used are-
* to find connected components of a graph, kruskal's algorithm for finding
* Minimum Spanning Tree etc.
* There are two operation which we perform on disjoint sets -
* 1) Union
* 2) Find
*
*/
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
vector<int> root, rank;
/**
*
* Function to create a set
* @param n number of element
*
*/
void CreateSet(int n) {
root = vector<int>(n + 1);
rank = vector<int>(n + 1, 1);
for (int i = 1; i <= n; ++i) {
root[i] = i;
}
}
/**
*
* Find operation takes a number x and returns the set to which this number
* belongs to.
* @param x element of some set
* @return set to which x belongs to
*
*/
int Find(int x) {
if (root[x] == x) {
return x;
}
return root[x] = Find(root[x]);
}
/**
*
* A utility function to check if x and y are from same set or not
* @param x element of some set
* @param y element of some set
*
*/
bool InSameUnion(int x, int y) { return Find(x) == Find(y); }
/**
*
* Union operation combines two disjoint sets to make a single set
* in this union function we pass two elements and check if they are
* from different sets then combine those sets
* @param x element of some set
* @param y element of some set
*
*/
void Union(int x, int y) {
int a = Find(x), b = Find(y);
if (a != b) {
if (rank[a] < rank[b]) {
root[a] = b;
} else if (rank[a] > rank[b]) {
root[b] = a;
} else {
root[a] = b;
++rank[b];
}
}
}
/** Main function */
int main() {
// tests CreateSet & Find
int n = 100;
CreateSet(n);
for (int i = 1; i <= 100; ++i) {
if (root[i] != i) {
cout << "Fail" << endl;
break;
}
}
// tests InSameUnion & Union
cout << "1 and 2 are initially not in the same subset" << endl;
if (InSameUnion(1, 2)) {
cout << "Fail" << endl;
}
Union(1, 2);
cout << "1 and 2 are now in the same subset" << endl;
if (!InSameUnion(1, 2)) {
cout << "Fail" << endl;
}
return 0;
}

View File

@@ -0,0 +1,136 @@
#include <cstdio>
#include <cstdlib>
#include <iostream>
struct node {
int val;
node *prev;
node *next;
} * start;
class double_linked_list {
public:
double_linked_list() { start = NULL; }
void insert(int x);
void remove(int x);
void search(int x);
void show();
void reverseShow();
};
void double_linked_list::insert(int x) {
node *t = start;
if (start != NULL) {
while (t->next != NULL) {
t = t->next;
}
node *n = new node;
t->next = n;
n->prev = t;
n->val = x;
n->next = NULL;
} else {
node *n = new node;
n->val = x;
n->prev = NULL;
n->next = NULL;
start = n;
}
}
void double_linked_list::remove(int x) {
node *t = start;
while (t != NULL && t->val != x) {
t = t->next;
}
if (t == NULL) {
return;
}
if (t->prev == NULL) {
if (t->next == NULL) {
start = NULL;
} else {
start = t->next;
start->prev = NULL;
}
} else if (t->next == NULL) {
t->prev->next = NULL;
} else {
t->prev->next = t->next;
t->next->prev = t->prev;
}
delete t;
}
void double_linked_list::search(int x) {
node *t = start;
int found = 0;
while (t != NULL) {
if (t->val == x) {
std::cout << "\nFound";
found = 1;
break;
}
t = t->next;
}
if (found == 0) {
std::cout << "\nNot Found";
}
}
void double_linked_list::show() {
node *t = start;
while (t != NULL) {
std::cout << t->val << "\t";
t = t->next;
}
}
void double_linked_list::reverseShow() {
node *t = start;
while (t != NULL && t->next != NULL) {
t = t->next;
}
while (t != NULL) {
std::cout << t->val << "\t";
t = t->prev;
}
}
int main() {
int choice, x;
double_linked_list ob;
do {
std::cout << "\n1. Insert";
std::cout << "\n2. Delete";
std::cout << "\n3. Search";
std::cout << "\n4. Forward print";
std::cout << "\n5. Reverse print";
std::cout << "\n\nEnter you choice : ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "\nEnter the element to be inserted : ";
std::cin >> x;
ob.insert(x);
break;
case 2:
std::cout << "\nEnter the element to be removed : ";
std::cin >> x;
ob.remove(x);
break;
case 3:
std::cout << "\nEnter the element to be searched : ";
std::cin >> x;
ob.search(x);
break;
case 4:
ob.show();
break;
case 5:
ob.reverseShow();
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -0,0 +1,134 @@
#include <iostream>
struct node {
int val;
node *next;
};
node *start;
void insert(int x) {
node *t = start;
node *n = new node;
n->val = x;
n->next = NULL;
if (start != NULL) {
while (t->next != NULL) {
t = t->next;
}
t->next = n;
} else {
start = n;
}
}
void remove(int x) {
if (start == NULL) {
std::cout << "\nLinked List is empty\n";
return;
} else if (start->val == x) {
node *temp = start;
start = start->next;
delete temp;
return;
}
node *temp = start, *parent = start;
while (temp != NULL && temp->val != x) {
parent = temp;
temp = temp->next;
}
if (temp == NULL) {
std::cout << std::endl << x << " not found in list\n";
return;
}
parent->next = temp->next;
delete temp;
}
void search(int x) {
node *t = start;
int found = 0;
while (t != NULL) {
if (t->val == x) {
std::cout << "\nFound";
found = 1;
break;
}
t = t->next;
}
if (found == 0) {
std::cout << "\nNot Found";
}
}
void show() {
node *t = start;
while (t != NULL) {
std::cout << t->val << "\t";
t = t->next;
}
}
void reverse() {
node *first = start;
if (first != NULL) {
node *second = first->next;
while (second != NULL) {
node *tem = second->next;
second->next = first;
first = second;
second = tem;
}
start->next = NULL;
start = first;
} else {
std::cout << "\nEmpty list";
}
}
int main() {
int choice, x;
do {
std::cout << "\n1. Insert";
std::cout << "\n2. Delete";
std::cout << "\n3. Search";
std::cout << "\n4. Print";
std::cout << "\n5. Reverse";
std::cout << "\n0. Exit";
std::cout << "\n\nEnter you choice : ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "\nEnter the element to be inserted : ";
std::cin >> x;
insert(x);
break;
case 2:
std::cout << "\nEnter the element to be removed : ";
std::cin >> x;
remove(x);
break;
case 3:
std::cout << "\nEnter the element to be searched : ";
std::cin >> x;
search(x);
break;
case 4:
show();
std::cout << "\n";
break;
case 5:
std::cout << "The reversed list: \n";
reverse();
show();
std::cout << "\n";
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -0,0 +1,114 @@
/**
* \file
* \brief Linked list implementation using Arrays
*
* The difference between the pointer implementation of linked list and array
* implementation of linked list:
* 1. The NULL is represented by -1;
* 2. Limited size. (in the following case it is 100 nodes at max). But we can
* reuse the nodes that are to be deleted by again linking it bacj to the list.
*/
#include <iostream>
struct Node {
int data;
int next;
};
Node AvailArray[100]; ///< array that will act as nodes of a linked list.
int head = -1;
int avail = 0;
void initialise_list() {
for (int i = 0; i <= 98; i++) {
AvailArray[i].next = i + 1;
}
AvailArray[99].next = -1; // indicating the end of the linked list.
}
/** This will return the index of the first free node present in the avail list
*/
int getnode() {
int NodeIndexToBeReturned = avail;
avail = AvailArray[avail].next;
return NodeIndexToBeReturned;
}
/** This function when called will delete the node with
* the index presented as an argument, and will put
* back that node into the array.
*/
void freeNode(int nodeToBeDeleted) {
AvailArray[nodeToBeDeleted].next = avail;
avail = nodeToBeDeleted;
}
/** The function will insert the given data
* into the front of the linked list.
*/
void insertAtTheBeginning(int data) {
int newNode = getnode();
AvailArray[newNode].data = data;
AvailArray[newNode].next = head;
head = newNode;
}
void insertAtTheEnd(int data) {
int newNode = getnode();
int temp = head;
while (AvailArray[temp].next != -1) {
temp = AvailArray[temp].next;
}
// temp is now pointing to the end node.
AvailArray[newNode].data = data;
AvailArray[newNode].next = -1;
AvailArray[temp].next = newNode;
}
void display() {
int temp = head;
while (temp != -1) {
std::cout << AvailArray[temp].data << "->";
temp = AvailArray[temp].next;
}
std::cout << "-1" << std::endl;
}
/** Main function */
int main() {
initialise_list();
int x, y, z;
for (;;) {
std::cout << "1. Insert At The Beginning" << std::endl;
std::cout << "2. Insert At The End" << std::endl;
std::cout << "3. Display" << std::endl;
std::cout << "4.Exit" << std::endl;
std::cout << "Enter Your choice" << std::endl;
std::cin >> z;
switch (z) {
case 1:
std::cout << "Enter the number you want to enter" << std::endl;
std::cin >> x;
insertAtTheBeginning(x);
break;
case 2:
std::cout << "Enter the number you want to enter" << std::endl;
std::cin >> y;
insertAtTheEnd(y);
break;
case 3:
std::cout
<< "The linked list contains the following element in order"
<< std::endl;
display();
break;
case 4:
return 0;
default:
std::cout << "The entered choice is not correct" << std::endl;
}
}
return 0;
}

View File

@@ -0,0 +1,156 @@
/**
* @file list_array.cpp
* @todo Add documentation
* @warning The sorting algorithm is erroneous
*/
#include <iostream>
struct list {
int data[50];
int top = 0;
bool isSorted = false;
int BinarySearch(int *array, int first, int last, int x) {
if (last < first) {
return -1;
}
int mid = (first + last) / 2;
if (array[mid] == x)
return mid;
else if (x < array[mid])
return (BinarySearch(array, first, mid - 1, x));
else if (x > array[mid])
return (BinarySearch(array, mid + 1, last, x));
std::cerr << __func__ << ":" << __LINE__ << ": Undefined condition\n";
return -1;
}
int LinarSearch(int *array, int x) {
for (int i = 0; i < top; i++) {
if (array[i] == x) {
return i;
}
}
return -1;
}
int Search(int x) {
int pos = -1;
if (isSorted) {
pos = BinarySearch(data, 0, top - 1, x);
} else {
pos = LinarSearch(data, x);
}
if (pos != -1) {
std::cout << "\nElement found at position : " << pos;
} else {
std::cout << "\nElement not found";
}
return pos;
}
void Sort() {
int i, j, pos;
for (i = 0; i < top; i++) {
int min = data[i];
for (j = i + 1; j < top; j++) {
if (data[j] < min) {
pos = j;
min = data[pos];
}
}
int temp = data[i];
data[i] = data[pos];
data[pos] = temp;
}
isSorted = true;
}
void insert(int x) {
if (!isSorted) {
if (top == 49) {
std::cout << "\nOverflow";
} else {
data[top] = x;
top++;
}
} else {
int pos = 0;
for (int i = 0; i < top - 1; i++) {
if (data[i] <= x && x <= data[i + 1]) {
pos = i + 1;
break;
}
}
if (pos == 0) {
pos = top - 1;
}
for (int i = top; i > pos; i--) {
data[i] = data[i - 1];
}
top++;
data[pos] = x;
}
}
void Remove(int x) {
int pos = Search(x);
std::cout << "\n" << data[pos] << " deleted";
for (int i = pos; i < top; i++) {
data[i] = data[i + 1];
}
top--;
}
void Show() {
for (int i = 0; i < top; i++) {
std::cout << data[i] << "\t";
}
}
};
int main() {
list L;
int choice;
int x;
do {
std::cout << "\n1.Insert";
std::cout << "\n2.Delete";
std::cout << "\n3.Search";
std::cout << "\n4.Sort";
std::cout << "\n5.Print";
std::cout << "\n\nEnter Your Choice : ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "\nEnter the element to be inserted : ";
std::cin >> x;
L.insert(x);
break;
case 2:
std::cout << "\nEnter the element to be removed : ";
std::cin >> x;
L.Remove(x);
break;
case 3:
std::cout << "\nEnter the element to be searched : ";
std::cin >> x;
L.Search(x);
break;
case 4:
L.Sort();
break;
case 5:
L.Show();
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -0,0 +1,92 @@
#include <iostream>
#include <queue>
/**************************
@author shrutisheoran
**************************/
using namespace std;
struct Btree {
int data;
struct Btree *left; // Pointer to left subtree
struct Btree *right; // Pointer to right subtree
};
void insert(Btree **root, int d) {
Btree *nn = new Btree(); // Creating new node
nn->data = d;
nn->left = NULL;
nn->right = NULL;
if (*root == NULL) {
*root = nn;
return;
} else {
queue<Btree *> q;
// Adding root node to queue
q.push(*root);
while (!q.empty()) {
Btree *node = q.front();
// Removing parent node from queue
q.pop();
if (node->left)
// Adding left child of removed node to queue
q.push(node->left);
else {
// Adding new node if no left child is present
node->left = nn;
return;
}
if (node->right)
// Adding right child of removed node to queue
q.push(node->right);
else {
// Adding new node if no right child is present
node->right = nn;
return;
}
}
}
}
void morrisInorder(Btree *root) {
Btree *curr = root;
Btree *temp;
while (curr) {
if (curr->left == NULL) {
cout << curr->data << " ";
// If left of current node is NULL then curr is shifted to right
curr = curr->right;
} else {
// Left of current node is stored in temp
temp = curr->left;
// Moving to extreme right of temp
while (temp->right && temp->right != curr) temp = temp->right;
// If extreme right is null it is made to point to currrent node
// (will be used for backtracking)
if (temp->right == NULL) {
temp->right = curr;
// current node is made to point its left subtree
curr = curr->left;
}
// If extreme right already points to currrent node it it set to
// null
else if (temp->right == curr) {
cout << curr->data << " ";
temp->right = NULL;
// current node is made to point its right subtree
curr = curr->right;
}
}
}
}
int main() {
// Testing morrisInorder funtion
Btree *root = NULL;
int i;
for (i = 1; i <= 7; i++) insert(&root, i);
cout << "Morris Inorder: ";
morrisInorder(root);
return 0;
}

88
data_structures/queue.h Normal file
View File

@@ -0,0 +1,88 @@
/* This class specifies the basic operation on a queue as a linked list */
#ifndef DATA_STRUCTURES_QUEUE_H_
#define DATA_STRUCTURES_QUEUE_H_
#include <cassert>
#include <iostream>
/** Definition of the node */
template <class Kind>
struct node {
Kind data;
node<Kind> *next;
};
/** Definition of the queue class */
template <class Kind>
class queue {
public:
/** Show queue */
void display() {
node<Kind> *current = queueFront;
std::cout << "Front --> ";
while (current != NULL) {
std::cout << current->data << " ";
current = current->next;
}
std::cout << std::endl;
std::cout << "Size of queue: " << size << std::endl;
}
/** Default constructor*/
queue() {
queueFront = NULL;
queueRear = NULL;
size = 0;
}
/** Destructor */
~queue() {}
/** Determine whether the queue is empty */
bool isEmptyQueue() { return (queueFront == NULL); }
/** Add new item to the queue */
void enQueue(Kind item) {
node<Kind> *newNode;
newNode = new node<Kind>;
newNode->data = item;
newNode->next = NULL;
if (queueFront == NULL) {
queueFront = newNode;
queueRear = newNode;
} else {
queueRear->next = newNode;
queueRear = queueRear->next;
}
size++;
}
/** Return the first element of the queue */
Kind front() {
assert(queueFront != NULL);
return queueFront->data;
}
/** Remove the top element of the queue */
void deQueue() {
node<Kind> *temp;
if (!isEmptyQueue()) {
temp = queueFront;
queueFront = queueFront->next;
delete temp;
size--;
} else {
std::cout << "Queue is empty !" << std::endl;
}
}
/** Clear queue */
void clear() { queueFront = NULL; }
private:
node<Kind> *queueFront; /**< Pointer to the front of the queue */
node<Kind> *queueRear; /**< Pointer to the rear of the queue */
int size;
};
#endif // DATA_STRUCTURES_QUEUE_H_

View File

@@ -58,8 +58,7 @@ void Queue_Array::display() {
if (front == -1) {
std::cout << "\nStack is empty";
} else {
for (int i = front; i <= rear; i++)
std::cout << arr[i] << " ";
for (int i = front; i <= rear; i++) std::cout << arr[i] << " ";
}
}

View File

@@ -0,0 +1,57 @@
#include <iostream>
using namespace std;
int queue[10];
int front = 0;
int rear = 0;
void Enque(int x) {
if (rear == 10) {
cout << "\nOverflow";
} else {
queue[rear++] = x;
}
}
void Deque() {
if (front == rear) {
cout << "\nUnderflow";
}
else {
cout << "\n" << queue[front++] << " deleted";
for (int i = front; i < rear; i++) {
queue[i - front] = queue[i];
}
rear = rear - front;
front = 0;
}
}
void show() {
for (int i = front; i < rear; i++) {
cout << queue[i] << "\t";
}
}
int main() {
int ch, x;
do {
cout << "\n1. Enque";
cout << "\n2. Deque";
cout << "\n3. Print";
cout << "\nEnter Your Choice : ";
cin >> ch;
if (ch == 1) {
cout << "\nInsert : ";
cin >> x;
Enque(x);
} else if (ch == 2) {
Deque();
} else if (ch == 3) {
show();
}
} while (ch != 0);
return 0;
}

View File

@@ -1,18 +1,15 @@
#include <iostream>
using namespace std;
struct node
{
struct node {
int val;
node *next;
};
node *front, *rear;
void Enque(int x)
{
if (rear == NULL)
{
void Enque(int x) {
if (rear == NULL) {
node *n = new node;
n->val = x;
n->next = NULL;
@@ -20,9 +17,7 @@ void Enque(int x)
front = n;
}
else
{
else {
node *n = new node;
n->val = x;
n->next = NULL;
@@ -31,17 +26,12 @@ void Enque(int x)
}
}
void Deque()
{
if (rear == NULL && front == NULL)
{
void Deque() {
if (rear == NULL && front == NULL) {
cout << "\nUnderflow";
}
else
{
} else {
node *t = front;
cout << "\n"
<< t->val << " deleted";
cout << "\n" << t->val << " deleted";
front = front->next;
delete t;
if (front == NULL)
@@ -49,38 +39,29 @@ void Deque()
}
}
void show()
{
void show() {
node *t = front;
while (t != NULL)
{
while (t != NULL) {
cout << t->val << "\t";
t = t->next;
}
}
int main()
{
int main() {
int ch, x;
do
{
do {
cout << "\n1. Enque";
cout << "\n2. Deque";
cout << "\n3. Print";
cout << "\nEnter Your Choice : ";
cin >> ch;
if (ch == 1)
{
if (ch == 1) {
cout << "\nInsert : ";
cin >> x;
Enque(x);
}
else if (ch == 2)
{
} else if (ch == 2) {
Deque();
}
else if (ch == 3)
{
} else if (ch == 3) {
show();
}
} while (ch != 0);

View File

@@ -0,0 +1,86 @@
/*
Write a program to implement Queue using linkedlist.
*/
#include <iostream>
struct linkedlist {
int data;
linkedlist *next;
};
class stack_linkedList {
public:
linkedlist *front;
linkedlist *rear;
stack_linkedList() { front = rear = NULL; }
void enqueue(int);
int dequeue();
void display();
};
void stack_linkedList::enqueue(int ele) {
linkedlist *temp = new linkedlist();
temp->data = ele;
temp->next = NULL;
if (front == NULL)
front = rear = temp;
else {
rear->next = temp;
rear = temp;
}
}
int stack_linkedList::dequeue() {
linkedlist *temp;
int ele;
if (front == NULL)
std::cout << "\nStack is empty";
else {
temp = front;
ele = temp->data;
if (front == rear) // if length of queue is 1;
rear = rear->next;
front = front->next;
delete (temp);
}
return ele;
}
void stack_linkedList::display() {
if (front == NULL)
std::cout << "\nStack is empty";
else {
linkedlist *temp;
temp = front;
while (temp != NULL) {
std::cout << temp->data << " ";
temp = temp->next;
}
}
}
int main() {
int op, data;
stack_linkedList ob;
std::cout << "\n1. enqueue(Insertion) ";
std::cout << "\n2. dequeue(Deletion)";
std::cout << "\n3. Display";
std::cout << "\n4. Exit";
while (1) {
std::cout << "\nEnter your choice ";
std::cin >> op;
if (op == 1) {
std::cout << "Enter data ";
std::cin >> data;
ob.enqueue(data);
} else if (op == 2)
data = ob.dequeue();
else if (op == 3)
ob.display();
else if (op == 4)
exit(0);
else
std::cout << "\nWrong choice ";
}
return 0;
}

View File

@@ -0,0 +1,221 @@
/**
* @file skip_list.cpp
* @brief Data structure for fast searching and insertion in \f$O(\log n)\f$
* time
* @details
* A skip list is a data structure that is used for storing a sorted list of
* items with a help of hierarchy of linked lists that connect increasingly
* sparse subsequences of the items
*
* References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/),
* [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code
* @author [enqidu](https://github.com/enqidu)
* @author [Krishna Vedala](https://github.com/kvedala)
*/
#include <array>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <vector>
/** \namespace data_structure
* \brief Data-structure algorithms
*/
namespace data_structure {
constexpr int MAX_LEVEL = 2; ///< Maximum level of skip list
constexpr float PROBABILITY = 0.5; ///< Current probability for "coin toss"
/**
* Node structure [Key][Node*, Node*...]
*/
struct Node {
int key; ///< key integer
void* value; ///< pointer of value
std::vector<std::shared_ptr<Node>>
forward; ///< nodes of the given one in all levels
/**
* Creates node with provided key, level and value
* @param key is number that is used for comparision
* @param level is the maximum level node's going to added
*/
Node(int key, int level, void* value = nullptr) : key(key), value(value) {
// Initialization of forward vector
for (int i = 0; i < (level + 1); i++) {
forward.push_back(nullptr);
}
}
};
/**
* SkipList class implementation with basic methods
*/
class SkipList {
int level; ///< Maximum level of the skiplist
std::shared_ptr<Node> header; ///< Pointer to the header node
public:
/**
* Skip List constructor. Initializes header, start
* Node for searching in the list
*/
SkipList() {
level = 0;
// Header initialization
header = std::shared_ptr<Node>(new Node(-1, MAX_LEVEL));
}
/**
* Returns random level of the skip list.
* Every higher level is 2 times less likely.
* @return random level for skip list
*/
int randomLevel() {
int lvl = 0;
while (static_cast<float>(std::rand()) / RAND_MAX < PROBABILITY &&
lvl < MAX_LEVEL)
lvl++;
return lvl;
}
/**
* Inserts elements with given key and value;
* It's level is computed by randomLevel() function.
* @param key is number that is used for comparision
* @param value pointer to a value, that can be any type
*/
void insertElement(int key, void* value) {
std::cout << "Inserting" << key << "...";
std::shared_ptr<Node> x = header;
std::array<std::shared_ptr<Node>, MAX_LEVEL + 1> update;
update.fill(nullptr);
for (int i = level; i >= 0; i--) {
while (x->forward[i] != nullptr && x->forward[i]->key < key)
x = x->forward[i];
update[i] = x;
}
x = x->forward[0];
bool doesnt_exist = (x == nullptr || x->key != key);
if (doesnt_exist) {
int rlevel = randomLevel();
if (rlevel > level) {
for (int i = level + 1; i < rlevel + 1; i++) update[i] = header;
// Update current level
level = rlevel;
}
std::shared_ptr<Node> n =
std::shared_ptr<Node>(new Node(key, rlevel, value));
for (int i = 0; i <= rlevel; i++) {
n->forward[i] = update[i]->forward[i];
update[i]->forward[i] = n;
}
std::cout << "Inserted" << std::endl;
} else {
std::cout << "Exists" << std::endl;
}
}
/**
* Deletes an element by key and prints if has been removed successfully
* @param key is number that is used for comparision.
*/
void deleteElement(int key) {
std::shared_ptr<Node> x = header;
std::array<std::shared_ptr<Node>, MAX_LEVEL + 1> update;
update.fill(nullptr);
for (int i = level; i >= 0; i--) {
while (x->forward[i] != nullptr && x->forward[i]->key < key)
x = x->forward[i];
update[i] = x;
}
x = x->forward[0];
bool doesnt_exist = (x == nullptr || x->key != key);
if (!doesnt_exist) {
for (int i = 0; i <= level; i++) {
if (update[i]->forward[i] != x)
break;
update[i]->forward[i] = x->forward[i];
}
/* Remove empty levels*/
while (level > 0 && header->forward[level] == nullptr) level--;
std::cout << "Deleted" << std::endl;
} else {
std::cout << "Doesn't exist" << std::endl;
}
}
/**
* Searching element in skip list structure
* @param key is number that is used for comparision
* @return pointer to the value of the node
*/
void* searchElement(int key) {
std::shared_ptr<Node> x = header;
std::cout << "Searching for " << key << std::endl;
for (int i = level; i >= 0; i--) {
while (x->forward[i] && x->forward[i]->key < key) x = x->forward[i];
}
x = x->forward[0];
if (x && x->key == key) {
std::cout << "Found" << std::endl;
return x->value;
} else {
std::cout << "Not Found" << std::endl;
return nullptr;
}
}
/**
* Display skip list level
*/
void displayList() {
std::cout << "Displaying list:\n";
for (int i = 0; i <= level; i++) {
std::shared_ptr<Node> node = header->forward[i];
std::cout << "Level " << (i) << ": ";
while (node != nullptr) {
std::cout << node->key << " ";
node = node->forward[i];
}
std::cout << std::endl;
}
}
};
} // namespace data_structure
/**
* Main function:
* Creates and inserts random 2^[number of levels]
* elements into the skip lists and than displays it
*/
int main() {
std::srand(std::time(nullptr));
data_structure::SkipList lst;
for (int j = 0; j < (1 << (data_structure::MAX_LEVEL + 1)); j++) {
int k = (std::rand() % (1 << (data_structure::MAX_LEVEL + 2)) + 1);
lst.insertElement(k, &j);
}
lst.displayList();
return 0;
}

150
data_structures/stack.h Normal file
View File

@@ -0,0 +1,150 @@
/**
* @file stack.h
* @author danghai
* @brief This class specifies the basic operation on a stack as a linked list
**/
#ifndef DATA_STRUCTURES_STACK_H_
#define DATA_STRUCTURES_STACK_H_
#include <cassert>
#include <iostream>
/** Definition of the node as a linked-list
* \tparam Type type of data nodes of the linked list should contain
*/
template <class Type>
struct node {
Type data; ///< data at current node
node<Type> *next; ///< pointer to the next ::node instance
};
/** Definition of the stack class
* \tparam Type type of data nodes of the linked list in the stack should
* contain
*/
template <class Type>
class stack {
public:
/** Show stack */
void display() {
node<Type> *current = stackTop;
std::cout << "Top --> ";
while (current != nullptr) {
std::cout << current->data << " ";
current = current->next;
}
std::cout << std::endl;
std::cout << "Size of stack: " << size << std::endl;
}
/** Default constructor*/
stack() {
stackTop = nullptr;
size = 0;
}
/** Copy constructor*/
explicit stack(const stack<Type> &otherStack) {
node<Type> *newNode, *current, *last;
/* If stack is no empty, make it empty */
if (stackTop != nullptr) {
stackTop = nullptr;
}
if (otherStack.stackTop == nullptr) {
stackTop = nullptr;
} else {
current = otherStack.stackTop;
stackTop = new node<Type>;
stackTop->data = current->data;
stackTop->next = nullptr;
last = stackTop;
current = current->next;
/* Copy the remaining stack */
while (current != nullptr) {
newNode = new node<Type>;
newNode->data = current->data;
newNode->next = nullptr;
last->next = newNode;
last = newNode;
current = current->next;
}
}
size = otherStack.size;
}
/** Destructor */
~stack() {}
/** Determine whether the stack is empty */
bool isEmptyStack() { return (stackTop == nullptr); }
/** Add new item to the stack */
void push(Type item) {
node<Type> *newNode;
newNode = new node<Type>;
newNode->data = item;
newNode->next = stackTop;
stackTop = newNode;
size++;
}
/** Return the top element of the stack */
Type top() {
assert(stackTop != nullptr);
return stackTop->data;
}
/** Remove the top element of the stack */
void pop() {
node<Type> *temp;
if (!isEmptyStack()) {
temp = stackTop;
stackTop = stackTop->next;
delete temp;
size--;
} else {
std::cout << "Stack is empty !" << std::endl;
}
}
/** Clear stack */
void clear() { stackTop = nullptr; }
/** Overload "=" the assignment operator */
stack<Type> &operator=(const stack<Type> &otherStack) {
node<Type> *newNode, *current, *last;
/* If stack is no empty, make it empty */
if (stackTop != nullptr) {
stackTop = nullptr;
}
if (otherStack.stackTop == nullptr) {
stackTop = nullptr;
} else {
current = otherStack.stackTop;
stackTop = new node<Type>;
stackTop->data = current->data;
stackTop->next = nullptr;
last = stackTop;
current = current->next;
/* Copy the remaining stack */
while (current != nullptr) {
newNode = new node<Type>;
newNode->data = current->data;
newNode->next = nullptr;
last->next = newNode;
last = newNode;
current = current->next;
}
}
size = otherStack.size;
return *this;
}
private:
node<Type> *stackTop; /**< Pointer to the stack */
int size; ///< size of stack
};
#endif // DATA_STRUCTURES_STACK_H_

View File

@@ -0,0 +1,58 @@
#include <iostream>
int *stack;
int stack_idx = 0, stack_size;
void push(int x) {
if (stack_idx == stack_size) {
std::cout << "\nOverflow";
} else {
stack[stack_idx++] = x;
}
}
void pop() {
if (stack_idx == 0) {
std::cout << "\nUnderflow";
} else {
std::cout << "\n" << stack[--stack_idx] << " deleted";
}
}
void show() {
for (int i = 0; i < stack_idx; i++) {
std::cout << stack[i] << "\n";
}
}
void topmost() { std::cout << "\nTopmost element: " << stack[stack_idx - 1]; }
int main() {
std::cout << "\nEnter stack_size of stack : ";
std::cin >> stack_size;
stack = new int[stack_size];
int ch, x;
do {
std::cout << "\n0. Exit";
std::cout << "\n1. Push";
std::cout << "\n2. Pop";
std::cout << "\n3. Print";
std::cout << "\n4. Print topmost element:";
std::cout << "\nEnter Your Choice : ";
std::cin >> ch;
if (ch == 1) {
std::cout << "\nInsert : ";
std::cin >> x;
push(x);
} else if (ch == 2) {
pop();
} else if (ch == 3) {
show();
} else if (ch == 4) {
topmost();
}
} while (ch != 0);
delete[] stack;
return 0;
}

View File

@@ -0,0 +1,56 @@
#include <iostream>
struct node {
int val;
node *next;
};
node *top_var;
void push(int x) {
node *n = new node;
n->val = x;
n->next = top_var;
top_var = n;
}
void pop() {
if (top_var == NULL) {
std::cout << "\nUnderflow";
} else {
node *t = top_var;
std::cout << "\n" << t->val << " deleted";
top_var = top_var->next;
delete t;
}
}
void show() {
node *t = top_var;
while (t != NULL) {
std::cout << t->val << "\n";
t = t->next;
}
}
int main() {
int ch, x;
do {
std::cout << "\n1. Push";
std::cout << "\n2. Pop";
std::cout << "\n3. Print";
std::cout << "\nEnter Your Choice : ";
std::cin >> ch;
if (ch == 1) {
std::cout << "\nInsert : ";
std::cin >> x;
push(x);
} else if (ch == 2) {
pop();
} else if (ch == 3) {
show();
}
} while (ch != 0);
return 0;
}

View File

@@ -0,0 +1,41 @@
#include <iostream>
#include <string>
#include "./queue.h"
int main() {
queue<std::string> q;
std::cout << "---------------------- Test construct ----------------------"
<< std::endl;
q.display();
std::cout
<< "---------------------- Test isEmptyQueue ----------------------"
<< std::endl;
if (q.isEmptyQueue())
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
std::cout << "---------------------- Test enQueue ----------------------"
<< std::endl;
std::cout << "After Hai, Jeff, Tom, Jkingston go into queue: " << std::endl;
q.enQueue("Hai");
q.enQueue("Jeff");
q.enQueue("Tom");
q.enQueue("Jkingston");
q.display();
std::cout << "---------------------- Test front ----------------------"
<< std::endl;
std::string value = q.front();
if (value == "Hai")
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
std::cout << "---------------------- Test deQueue ----------------------"
<< std::endl;
q.display();
q.deQueue();
q.deQueue();
std::cout << "After Hai, Jeff left the queue: " << std::endl;
q.display();
return 0;
}

View File

@@ -0,0 +1,59 @@
#include <iostream>
#include "./stack.h"
int main() {
stack<int> stk;
std::cout << "---------------------- Test construct ----------------------"
<< std::endl;
stk.display();
std::cout
<< "---------------------- Test isEmptyStack ----------------------"
<< std::endl;
if (stk.isEmptyStack())
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
std::cout << "---------------------- Test push ----------------------"
<< std::endl;
std::cout << "After pushing 10 20 30 40 into stack: " << std::endl;
stk.push(10);
stk.push(20);
stk.push(30);
stk.push(40);
stk.display();
std::cout << "---------------------- Test top ----------------------"
<< std::endl;
int value = stk.top();
if (value == 40)
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
std::cout << "---------------------- Test pop ----------------------"
<< std::endl;
stk.display();
stk.pop();
stk.pop();
std::cout << "After popping 2 times: " << std::endl;
stk.display();
std::cout << "---------------------- Test overload = operator "
"----------------------"
<< std::endl;
stack<int> stk1;
std::cout << "stk current: " << std::endl;
stk.display();
std::cout << std::endl << "Assign stk1 = stk " << std::endl;
stk1 = stk;
stk1.display();
std::cout << std::endl << "After pushing 8 9 10 into stk1:" << std::endl;
stk1.push(8);
stk1.push(9);
stk1.push(10);
stk1.display();
std::cout << std::endl << "stk current: " << std::endl;
stk.display();
std::cout << "Assign back stk = stk1:" << std::endl;
stk = stk1;
stk.display();
return 0;
}

View File

@@ -8,29 +8,26 @@
* ./main student.txt
************************************************************
* */
#include <iostream>
#include <iomanip>
#include <cassert>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <assert.h>
#include "stack.h"
#include "stack.cpp"
#include "./stack.h"
using namespace std;
int main(int argc, char * argv[]) {
int main(int argc, char* argv[]) {
double GPA;
double highestGPA;
string name;
std::string name;
assert(argc == 2);
ifstream infile;
stack<string> stk;
std::ifstream infile;
stack<std::string> stk;
infile.open(argv[1]);
cout << fixed << showpoint;
cout << setprecision(2);
std::cout << std::fixed << std::showpoint;
std::cout << std::setprecision(2);
infile >> GPA >> name;
highestGPA = GPA;
@@ -44,12 +41,12 @@ int main(int argc, char * argv[]) {
}
infile >> GPA >> name;
}
cout << "Highest GPA: " << highestGPA <<endl;
cout << "Students the highest GPA are: " << endl;
std::cout << "Highest GPA: " << highestGPA << std::endl;
std::cout << "Students the highest GPA are: " << std::endl;
while (!stk.isEmptyStack()) {
cout << stk.top() << endl;
std::cout << stk.top() << std::endl;
stk.pop();
}
cout << endl;
std::cout << std::endl;
return 0;
}

View File

@@ -2,93 +2,76 @@
#include <list>
using namespace std;
struct node
{
struct node {
int val;
node *left;
node *right;
};
void CreateTree(node *curr, node *n, int x, char pos)
{
if (n != NULL)
{
void CreateTree(node *curr, node *n, int x, char pos) {
if (n != NULL) {
char ch;
cout << "\nLeft or Right of " << n->val << " : ";
cin >> ch;
if (ch == 'l')
CreateTree(n, n->left, x, ch);
else if (ch == 'r')
CreateTree(n, n->right, x, ch);
}
else
{
cout << "\nLeft or Right of " << n->val << " : ";
cin >> ch;
if (ch == 'l')
CreateTree(n, n->left, x, ch);
else if (ch == 'r')
CreateTree(n, n->right, x, ch);
} else {
node *t = new node;
t->val = x;
t->left = NULL;
t->right = NULL;
if (pos == 'l')
{
if (pos == 'l') {
curr->left = t;
}
else if (pos == 'r')
{
} else if (pos == 'r') {
curr->right = t;
}
}
}
void BFT(node *n)
{
list<node*> queue;
void BFT(node *n) {
list<node *> queue;
queue.push_back(n);
while(!queue.empty())
{
while (!queue.empty()) {
n = queue.front();
cout << n->val << " ";
queue.pop_front();
if(n->left != NULL)
if (n->left != NULL)
queue.push_back(n->left);
if(n->right != NULL)
if (n->right != NULL)
queue.push_back(n->right);
}
}
void Pre(node *n)
{
if (n != NULL)
{
void Pre(node *n) {
if (n != NULL) {
cout << n->val << " ";
Pre(n->left);
Pre(n->right);
}
}
void In(node *n)
{
if (n != NULL)
{
void In(node *n) {
if (n != NULL) {
In(n->left);
cout << n->val << " ";
In(n->right);
}
}
void Post(node *n)
{
if (n != NULL)
{
void Post(node *n) {
if (n != NULL) {
Post(n->left);
Post(n->right);
cout << n->val << " ";
}
}
int main()
{
int main() {
int value;
int ch;
node *root = new node;
@@ -97,8 +80,7 @@ int main()
root->val = value;
root->left = NULL;
root->right = NULL;
do
{
do {
cout << "\n1. Insert";
cout << "\n2. Breadth First";
cout << "\n3. Preorder Depth First";
@@ -107,8 +89,7 @@ int main()
cout << "\nEnter Your Choice : ";
cin >> ch;
switch (ch)
{
switch (ch) {
case 1:
int x;
char pos;

View File

@@ -1,8 +1,8 @@
/**
* Copyright 2020 @author Anmol3299
* @file
*
* A basic implementation of trie class to store only lower-case strings.
* @author Anmol3299
* \brief A basic implementation of trie class to store only lower-case strings.
*/
#include <iostream> // for io operations
#include <memory> // for std::shared_ptr<>
@@ -35,7 +35,8 @@ class Trie {
* Function to check if a node has some children which can form words.
* @param node whose character array of pointers need to be checked for
* children.
* @return if a child is found, it returns @ true, else it returns @ false.
* @return `true` if a child is found
* @return `false` if a child is not found
*/
inline static bool hasChildren(std::shared_ptr<TrieNode> node) {
for (size_t i = 0; i < ALPHABETS; i++) {
@@ -98,7 +99,7 @@ class Trie {
}
public:
// constructor to initialise the root of the trie.
/// constructor to initialise the root of the trie.
Trie() : m_root(std::make_shared<TrieNode>()) {}
/**

View File

@@ -0,0 +1,91 @@
#include <stdbool.h>
#include <stdio.h>
#include <iostream>
#include <string>
// structure definition
typedef struct trie {
struct trie* arr[26];
bool isEndofWord;
} trie;
// create a new node for trie
trie* createNode() {
trie* nn = new trie();
for (int i = 0; i < 26; i++) nn->arr[i] = NULL;
nn->isEndofWord = false;
return nn;
}
// insert string into the trie
void insert(trie* root, std::string str) {
for (int i = 0; i < str.length(); i++) {
int j = str[i] - 'a';
if (root->arr[j]) {
root = root->arr[j];
} else {
root->arr[j] = createNode();
root = root->arr[j];
}
}
root->isEndofWord = true;
}
// search a string exists inside the trie
bool search(trie* root, std::string str, int index) {
if (index == str.length()) {
if (!root->isEndofWord)
return false;
return true;
}
int j = str[index] - 'a';
if (!root->arr[j])
return false;
return search(root->arr[j], str, index + 1);
}
/*
removes the string if it is not a prefix of any other
string, if it is then just sets the endofword to false, else
removes the given string
*/
bool deleteString(trie* root, std::string str, int index) {
if (index == str.length()) {
if (!root->isEndofWord)
return false;
root->isEndofWord = false;
for (int i = 0; i < 26; i++) return false;
return true;
}
int j = str[index] - 'a';
if (!root->arr[j])
return false;
bool var = deleteString(root, str, index + 1);
if (var) {
root->arr[j] = NULL;
if (root->isEndofWord) {
return false;
} else {
int i;
for (i = 0; i < 26; i++)
if (root->arr[i])
return false;
return true;
}
}
/* should not return here */
std::cout << __func__ << ":" << __LINE__ << "Should not reach this line\n";
return false;
}
int main() {
trie* root = createNode();
insert(root, "hello");
insert(root, "world");
int a = search(root, "hello", 0);
int b = search(root, "word", 0);
printf("%d %d ", a, b);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
//0-1 Knapsack problem - Dynamic programming
//#include <bits/stdc++.h>
#include <iostream>
using namespace std;
//void Print(int res[20][20], int i, int j, int capacity)
//{
// if(i==0 || j==0)
// {
// return;
// }
// if(res[i-1][j]==res[i][j-1])
// {
// if(i<=capacity)
// {
// cout<<i<<" ";
// }
//
// Print(res, i-1, j-1, capacity-i);
// }
// else if(res[i-1][j]>res[i][j-1])
// {
// Print(res, i-1,j, capacity);
// }
// else if(res[i][j-1]>res[i-1][j])
// {
// Print(res, i,j-1, capacity);
// }
//}
int Knapsack(int capacity, int n, int weight[], int value[])
{
int res[20][20];
for (int i = 0; i < n + 1; ++i)
{
for (int j = 0; j < capacity + 1; ++j)
{
if (i == 0 || j == 0)
res[i][j] = 0;
else if (weight[i - 1] <= j)
res[i][j] = max(value[i - 1] + res[i - 1][j - weight[i - 1]], res[i - 1][j]);
else
res[i][j] = res[i - 1][j];
}
}
// Print(res, n, capacity, capacity);
// cout<<"\n";
return res[n][capacity];
}
int main()
{
int n;
cout << "Enter number of items: ";
cin >> n;
int weight[n], value[n];
cout << "Enter weights: ";
for (int i = 0; i < n; ++i)
{
cin >> weight[i];
}
cout << "Enter values: ";
for (int i = 0; i < n; ++i)
{
cin >> value[i];
}
int capacity;
cout << "Enter capacity: ";
cin >> capacity;
cout << Knapsack(capacity, n, weight, value);
return 0;
}

View File

@@ -0,0 +1,66 @@
// 0-1 Knapsack problem - Dynamic programming
//#include <bits/stdc++.h>
#include <iostream>
using namespace std;
// void Print(int res[20][20], int i, int j, int capacity)
//{
// if(i==0 || j==0)
// {
// return;
// }
// if(res[i-1][j]==res[i][j-1])
// {
// if(i<=capacity)
// {
// cout<<i<<" ";
// }
//
// Print(res, i-1, j-1, capacity-i);
// }
// else if(res[i-1][j]>res[i][j-1])
// {
// Print(res, i-1,j, capacity);
// }
// else if(res[i][j-1]>res[i-1][j])
// {
// Print(res, i,j-1, capacity);
// }
//}
int Knapsack(int capacity, int n, int weight[], int value[]) {
int res[20][20];
for (int i = 0; i < n + 1; ++i) {
for (int j = 0; j < capacity + 1; ++j) {
if (i == 0 || j == 0)
res[i][j] = 0;
else if (weight[i - 1] <= j)
res[i][j] = max(value[i - 1] + res[i - 1][j - weight[i - 1]],
res[i - 1][j]);
else
res[i][j] = res[i - 1][j];
}
}
// Print(res, n, capacity, capacity);
// cout<<"\n";
return res[n][capacity];
}
int main() {
int n;
cout << "Enter number of items: ";
cin >> n;
int weight[n], value[n];
cout << "Enter weights: ";
for (int i = 0; i < n; ++i) {
cin >> weight[i];
}
cout << "Enter values: ";
for (int i = 0; i < n; ++i) {
cin >> value[i];
}
int capacity;
cout << "Enter capacity: ";
cin >> capacity;
cout << Knapsack(capacity, n, weight, value);
return 0;
}

View File

@@ -1,128 +0,0 @@
#include <iostream>
#include <limits.h>
using namespace std;
//Wrapper class for storing an edge
class Edge
{
public:
int src, dst, weight;
};
//Wrapper class for storing a graph
class Graph
{
public:
int vertexNum, edgeNum;
Edge *edges;
//Constructs a graph with V vertices and E edges
Graph(int V, int E)
{
this->vertexNum = V;
this->edgeNum = E;
this->edges = (Edge *)malloc(E * sizeof(Edge));
}
//Adds the given edge to the graph
void addEdge(int src, int dst, int weight)
{
static int edgeInd = 0;
if (edgeInd < this->edgeNum)
{
Edge newEdge;
newEdge.src = src;
newEdge.dst = dst;
newEdge.weight = weight;
this->edges[edgeInd++] = newEdge;
}
}
};
//Utility function to print distances
void print(int dist[], int V)
{
cout << "\nVertex Distance" << endl;
for (int i = 0; i < V; i++)
{
if (dist[i] != INT_MAX)
cout << i << "\t" << dist[i] << endl;
else
cout << i << "\tINF" << endl;
}
}
//The main function that finds the shortest path from given source
//to all other vertices using Bellman-Ford.It also detects negative
//weight cycle
void BellmanFord(Graph graph, int src)
{
int V = graph.vertexNum;
int E = graph.edgeNum;
int dist[V];
//Initialize distances array as INF for all except source
//Intialize source as zero
for (int i = 0; i < V; i++)
dist[i] = INT_MAX;
dist[src] = 0;
//Calculate shortest path distance from source to all edges
//A path can contain maximum (|V|-1) edges
for (int i = 0; i <= V - 1; i++)
for (int j = 0; j < E; j++)
{
int u = graph.edges[j].src;
int v = graph.edges[j].dst;
int w = graph.edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + w < dist[v])
dist[v] = dist[u] + w;
}
//Iterate inner loop once more to check for negative cycle
for (int j = 0; j < E; j++)
{
int u = graph.edges[j].src;
int v = graph.edges[j].dst;
int w = graph.edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + w < dist[v])
{
cout << "Graph contains negative weight cycle. Hence, shortest distance not guaranteed." << endl;
return;
}
}
print(dist, V);
return;
}
//Driver Function
int main()
{
int V, E, gsrc;
int src, dst, weight;
cout << "Enter number of vertices: ";
cin >> V;
cout << "Enter number of edges: ";
cin >> E;
Graph G(V, E);
for (int i = 0; i < E; i++)
{
cout << "\nEdge " << i + 1 << "\nEnter source: ";
cin >> src;
cout << "Enter destination: ";
cin >> dst;
cout << "Enter weight: ";
cin >> weight;
G.addEdge(src, dst, weight);
}
cout << "\nEnter source: ";
cin >> gsrc;
BellmanFord(G, gsrc);
return 0;
}

View File

@@ -1,50 +0,0 @@
#include <iostream>
#include <climits>
using namespace std;
// Function to find the Minimum number of coins required to get Sum S
int findMinCoins(int arr[], int n, int N)
{
// dp[i] = no of coins required to get a total of i
int dp[N + 1];
// 0 coins are needed for 0 sum
dp[0] = 0;
for (int i = 1; i <= N; i++)
{
// initialize minimum number of coins needed to infinity
dp[i] = INT_MAX;
int res = INT_MAX;
// do for each coin
for (int c = 0; c < n; c++)
{
if (i - arr[c] >= 0) // check if coins doesn't become negative by including it
res = dp[i - arr[c]];
// if total can be reached by including current coin c,
// update minimum number of coins needed dp[i]
if (res != INT_MAX)
dp[i] = min(dp[i], res + 1);
}
}
// The Minimum No of Coins Required for N = dp[N]
return dp[N];
}
int main()
{
// No of Coins We Have
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]);
// Total Change Required
int N = 15;
cout << "Minimum Number of Coins Required " << findMinCoins(arr, n, N) << "\n";
return 0;
}

View File

@@ -1,28 +0,0 @@
/*Given a rod of length n inches and an array of prices that
contains prices of all pieces of size smaller than n. Determine
the maximum value obtainable by cutting up the rod and selling
the pieces.*/
#include <iostream>
using namespace std;
int cutrod(int p[], int n)
{
int r[n + 1];
r[0] = 0;
for (int j = 0; j < n; j++)
{
int q = INT_MIN;
for (int i = 0; i <= j; i++)
{
q = max(q, p[i] + r[j - i]);
}
r[j + 1] = q;
}
return r[n];
}
int main()
{
int price[] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
cout << cutrod(price, 30);
return 0;
}

View File

@@ -1,24 +0,0 @@
#include <iostream>
using namespace std;
int fib(int n)
{
int res[3];
res[0] = 0;
res[1] = 1;
for (int i = 2; i <= n; i++)
{
res[2] = res[1] + res[0];
res[0] = res[1];
res[1] = res[2];
}
return res[1];
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter n: ";
cin >> n;
cout << "Fibonacci number is ";
cout << fib(n) << endl;
return 0;
}

View File

@@ -1,26 +0,0 @@
#include <iostream>
using namespace std;
int arr[1000000];
int fib(int n)
{
if (arr[n] == -1)
{
if (n <= 1)
arr[n] = n;
else
arr[n] = fib(n - 1) + fib(n - 2);
}
return arr[n];
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter n: ";
cin >> n;
for (int i = 0; i < n + 1; ++i)
{
arr[i] = -1;
}
cout << "Fibonacci number is " << fib(n) << endl;
return 0;
}

View File

@@ -1,112 +0,0 @@
#include <iostream>
#include <limits.h>
#include <string.h>
using namespace std;
//Wrapper class for storing a graph
class Graph
{
public:
int vertexNum;
int **edges;
//Constructs a graph with V vertices and E edges
Graph(int V)
{
this->vertexNum = V;
this->edges = (int **)malloc(V * sizeof(int *));
for (int i = 0; i < V; i++)
{
this->edges[i] = (int *)malloc(V * sizeof(int));
for (int j = 0; j < V; j++)
this->edges[i][j] = INT_MAX;
this->edges[i][i] = 0;
}
}
//Adds the given edge to the graph
void addEdge(int src, int dst, int weight)
{
this->edges[src][dst] = weight;
}
};
//Utility function to print distances
void print(int dist[], int V)
{
cout << "\nThe Distance matrix for Floyd - Warshall" << endl;
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i * V + j] != INT_MAX)
cout << dist[i * V + j] << "\t";
else
cout << "INF"
<< "\t";
}
cout << endl;
}
}
//The main function that finds the shortest path from a vertex
//to all other vertices using Floyd-Warshall Algorithm.
void FloydWarshall(Graph graph)
{
int V = graph.vertexNum;
int dist[V][V];
//Initialise distance array
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist[i][j] = graph.edges[i][j];
//Calculate distances
for (int k = 0; k < V; k++)
//Choose an intermediate vertex
for (int i = 0; i < V; i++)
//Choose a source vertex for given intermediate
for (int j = 0; j < V; j++)
//Choose a destination vertex for above source vertex
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][k] + dist[k][j] < dist[i][j])
//If the distance through intermediate vertex is less than direct edge then update value in distance array
dist[i][j] = dist[i][k] + dist[k][j];
//Convert 2d array to 1d array for print
int dist1d[V * V];
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist1d[i * V + j] = dist[i][j];
print(dist1d, V);
}
//Driver Function
int main()
{
int V, E;
int src, dst, weight;
cout << "Enter number of vertices: ";
cin >> V;
cout << "Enter number of edges: ";
cin >> E;
Graph G(V);
for (int i = 0; i < E; i++)
{
cout << "\nEdge " << i + 1 << "\nEnter source: ";
cin >> src;
cout << "Enter destination: ";
cin >> dst;
cout << "Enter weight: ";
cin >> weight;
G.addEdge(src, dst, weight);
}
FloydWarshall(G);
return 0;
}

View File

@@ -1,82 +0,0 @@
//Longest common subsequence - Dynamic Programming
#include <iostream>
using namespace std;
void Print(int trace[20][20], int m, int n, string a)
{
if (m == 0 || n == 0)
{
return;
}
if (trace[m][n] == 1)
{
Print(trace, m - 1, n - 1, a);
cout << a[m - 1];
}
else if (trace[m][n] == 2)
{
Print(trace, m - 1, n, a);
}
else if (trace[m][n] == 3)
{
Print(trace, m, n - 1, a);
}
}
int lcs(string a, string b)
{
int m = a.length(), n = b.length();
int res[m + 1][n + 1];
int trace[20][20];
// fills up the arrays with zeros.
for (int i = 0; i < m + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
res[i][j] = 0;
trace[i][j] = 0;
}
}
for (int i = 0; i < m + 1; ++i)
{
for (int j = 0; j < n + 1; ++j)
{
if (i == 0 || j == 0)
{
res[i][j] = 0;
trace[i][j] = 0;
}
else if (a[i - 1] == b[j - 1])
{
res[i][j] = 1 + res[i - 1][j - 1];
trace[i][j] = 1; // 1 means trace the matrix in upper left diagonal direction.
}
else
{
if (res[i - 1][j] > res[i][j - 1])
{
res[i][j] = res[i - 1][j];
trace[i][j] = 2; // 2 means trace the matrix in upwards direction.
}
else
{
res[i][j] = res[i][j - 1];
trace[i][j] = 3; // means trace the matrix in left direction.
}
}
}
}
Print(trace, m, n, a);
return res[m][n];
}
int main()
{
string a, b;
cin >> a >> b;
cout << lcs(a, b);
return 0;
}

View File

@@ -1,46 +0,0 @@
//Program to calculate length of longest increasing subsequence in an array
// in O(n log n)
// tested on : https://cses.fi/problemset/task/1145/
#include <iostream>
using namespace std;
int LIS(int arr[], int n)
{
set < int > active; // The current built LIS.
active.insert(arr[0]);
// Loop through every element.
for (int i = 1; i < n; ++i)
{
auto get = active.lower_bound(arr[i]);
if (get == active.end())
{
active.insert(arr[i]);
} // current element is the greatest so LIS increases by 1.
else
{
int val = * get; // we find the position where arr[i] will be in the LIS. If it is in the LIS already we do nothing
if (val > arr[i])
{
// else we remove the bigger element and add a smaller element (which is arr[i]) and continue;
active.erase(get);
active.insert(arr[i]);
}
}
}
return active.size(); // size of the LIS.
}
int main(int argc, char const * argv[])
{
int n;
cout << "Enter size of array: ";
cin >> n;
int a[n];
cout << "Enter array elements: ";
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
cout << LIS(a, n) << endl;
return 0;
}

View File

@@ -1,39 +0,0 @@
//Program to calculate length of longest increasing subsequence in an array
#include <bits/stdc++.h>
using namespace std;
int LIS(int a[], int n)
{
int lis[n];
for (int i = 0; i < n; ++i)
{
lis[i] = 1;
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < i; ++j)
{
if (a[i] > a[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
}
}
int res = 0;
for (int i = 0; i < n; ++i)
{
res = max(res, lis[i]);
}
return res;
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter size of array: ";
cin >> n;
int a[n];
cout << "Enter array elements: ";
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
cout << LIS(a, n) << endl;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More