Merge branch 'TheAlgorithms:master' into master

This commit is contained in:
DaveAxiom
2021-10-31 23:25:26 -04:00
committed by GitHub
441 changed files with 32598 additions and 4228 deletions

167
.clang-format Normal file
View File

@@ -0,0 +1,167 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
- Regex: '^<.*'
Priority: 2
SortPriority: 0
- Regex: '.*'
Priority: 3
SortPriority: 0
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ''
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
...

6
.clang-tidy Normal file
View File

@@ -0,0 +1,6 @@
---
Checks: '-*,google-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,openmp-*,performance-*,portability-*,modernize-*'
WarningsAsErrors: '*,-clang-diagnostic-implicitly-unsigned-literal,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 80, AccessModifierOffset: -4 }'

65
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,65 @@
name: Bug report
description: Create a report to help us improve. Report bugs found while using the project
title: "[BUG]"
labels: [bug]
body:
- type: markdown
attributes:
value: "Provide a general summary of the issue in the Title above"
- type: textarea
id: description
attributes:
label: Description
description: Provide a general summary of the issue in the Title above
validations:
required: true
- type: input
id: expectedbhv
attributes:
label: Expected behavior
description: Tell us what should happen
validations:
required: true
- type: input
id: actualbhv
attributes:
label: Actual behavior
description: Tell us what happens instead
validations:
required: true
- type: input
id: possiblefix
attributes:
label: Possible fix
description: Not obligatory, but suggest a fix or reason for the bug
validations:
required: false
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: |
Provide a link to a live example, or an unambiguous set of steps to
reproduce this bug. Include code to reproduce, if relevant
placeholder: |
1.
2.
3.
4.
validations:
required: true
- type: textarea
id: context
attributes:
label: Context
description: How has this bug affected you? What were you trying to accomplish?
validations:
required: true
- type: textarea
id: extrainformation
attributes:
label: Additional information
description: Is there anything else we should know about this bug?
validations:
required: false

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -0,0 +1,38 @@
name: Feature request
description: Suggest features, propose improvements, discuss new ideas.
title: "[FEATURE]"
labels: [enhancement]
body:
- type: markdown
attributes:
value: Provide a general summary of the issue in the Title above
- type: textarea
id: description
attributes:
label: Detailed description
description: Provide a detailed description of the change or addition you are proposing
validations:
required: true
- type: textarea
id: context
attributes:
label: Context
description: |
Why is this change important to you? How would you use it?
How can it benefit other users?
validations:
required: true
- type: textarea
id: possibleimpl
attributes:
label: Possible implementation
description: Not obligatory, but suggest an idea for implementing addition or change
validations:
required: false
- type: textarea
id: extrainformation
attributes:
label: Additional information
description: Is there anything else we should know about this feature?
validations:
required: false

22
.github/ISSUE_TEMPLATE/other.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Other
description: Use this for any other issues. Do NOT create blank issues
title: "[OTHER]"
labels: [triage]
body:
- type: markdown
attributes:
value: "# Other issue"
- type: textarea
id: issuedescription
attributes:
label: What would you like to share?
description: Provide a clear and concise explanation of your issue.
validations:
required: true
- type: textarea
id: extrainfo
attributes:
label: Additional information
description: Is there anything else we should know about this issue?
validations:
required: false

24
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,24 @@
#### Description of Change
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md
-->
#### References
<!-- Add any reference to previous pull-request or issue -->
#### 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/blob/master/CONTRIBUTING.md#File-Name-guidelines)
- [ ] Added tests and example, test must pass
- [ ] Relevant documentation/comments is changed or added
- [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md#Commit-Guidelines)
- [ ] Search previous suggestions before making a new one, as yours may be a duplicate.
- [ ] 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 -->

14
.github/workflows/approved-label.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
on: pull_request_review
name: Add "approved" label when approved
jobs:
add_label:
name: Add "approved" label when approved
runs-on: ubuntu-latest
steps:
- name: Add "approved" label when approved
uses: pullreminders/label-when-approved-action@master
env:
APPROVALS: "1"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ADD_LABEL: "approved"
REMOVE_LABEL: ""

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

@@ -0,0 +1,166 @@
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 clang-format-10
- 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 '*.c' -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}"
if [ ${fname} != ${new_fname} ]
then
echo " ${fname} --> ${new_fname}"
git "mv" "${fname}" ${new_fname}
fi
done
git commit -am "formatting filenames ${GITHUB_SHA::8}" || true
- name: Update DIRECTORY.md
shell: python
run: |
import os
from typing import Iterator
URL_BASE = "https://github.com/TheAlgorithms/C/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 diff DIRECTORY.md
git add DIRECTORY.md
git commit -m "updating 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", "-p=build", "--fix", *cpp_files, "--"],
check=True, text=True, stderr=subprocess.STDOUT)
subprocess.run(["clang-format-10", "-i", *cpp_files],
check=True, text=True, stderr=subprocess.STDOUT)
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 and "project_euler" not in file and "data_structure" not in file]
nodir_file_bad_files = len(nodir_files) - 1
if nodir_file_bad_files:
print(f"{len(nodir_files)} files are not in one and only one directory:")
print("\n".join(nodir_files) + "\n")
bad_files = nodir_file_bad_files + len(upper_files + space_files)
if bad_files:
sys.exit(bad_files)
- name: Commit and push changes
run: |
git commit -am "clang-format and clang-tidy fixes for ${GITHUB_SHA::8}" || true
git push --force origin HEAD:$GITHUB_REF || true
build:
name: Compile checks
runs-on: ${{ matrix.os }}
needs: [MainSequence]
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@master
with:
submodules: true
- run: cmake -B ./build -S .
- run: cmake --build build

48
.github/workflows/codeql_analysis.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: "CodeQL"
on: [push, pull_request]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@main
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@main
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@main
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

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

18
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '0 0 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4
with:
stale-issue-message: 'This issue has been automatically marked as abandoned because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-issue-message: 'Please ping one of the maintainers once you add more information and updates here. If this is not the case and you need some help, feel free to ask for help in our [Gitter](https://gitter.im/TheAlgorithms) channel or our [Discord server](https://discord.gg/c7MnfGFGa6). Thank you for your contributions!'
stale-pr-message: 'This pull request has been automatically marked as abandoned because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-pr-message: 'Please ping one of the maintainers once you commit the changes requested or make improvements on the code. If this is not the case and you need some help, feel free to ask for help in our [Gitter](https://gitter.im/TheAlgorithms) channel or our [Discord server](https://discord.gg/c7MnfGFGa6). Thank you for your contributions!'
exempt-issue-labels: 'dont-close,approved'
exempt-pr-labels: 'dont-close,approved'
days-before-stale: 30
days-before-close: 7

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
*.swp
*.exe
*.out
.vscode/
build/

11
.gitpod.dockerfile Normal file
View File

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

17
.gitpod.yml Normal file
View File

@@ -0,0 +1,17 @@
image:
file: .gitpod.dockerfile
github:
prebuilds:
addBadge: true
addComment: false
addCheck: false
master: 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==

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"C_Cpp.clang_format_style": "{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 80, AccessModifierOffset: -4 }",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"files.insertFinalNewline": true,
}

112
CMakeLists.txt Normal file
View File

@@ -0,0 +1,112 @@
cmake_minimum_required(VERSION 3.6)
project(Algorithms_in_C
LANGUAGES C
VERSION 1.0.0
DESCRIPTION "Set of algorithms implemented in C."
)
# Set compilation standards
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED YES)
if(MSVC)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
# add_compile_options(/Za)
endif(MSVC)
# check for math library
# addresses a bug when linking on OSX
find_library(MATH_LIBRARY m)
# Optional flag - can be set by user
# Default "ON"
option(USE_OPENMP "flag to use OpenMP for multithreading" ON)
if(USE_OPENMP)
find_package(OpenMP)
if (OpenMP_C_FOUND)
message(STATUS "Building with OpenMP Multithreading.")
else()
message(STATUS "No OpenMP found, no multithreading.")
endif()
endif()
## Check for some required header files
include(CheckIncludeFile)
include(CheckSymbolExists)
check_include_file(stdbool.h HAS_STDBOOL_H)
check_include_file(inttypes.h HAS_INTTYPES_H)
check_include_file(complex.h HAS_COMPLEX_H)
if(HAS_COMPLEX_H)
check_symbol_exists(complex complex.h HAS_COMPLEX_TYPE)
endif(HAS_COMPLEX_H)
if (NOT HAS_STDBOOL_H)
message(FATAL_ERROR "Missing required header: 'stdbool.h'")
endif()
if (NOT HAS_INTTYPES_H)
message(FATAL_ERROR "Missing required header: 'inttypes.h'")
endif()
## Add subdirectories containing CMakeLists.txt
# to configure and compile files in the respective folders
add_subdirectory(developer_tools)
add_subdirectory(hash)
add_subdirectory(misc)
add_subdirectory(games)
add_subdirectory(audio)
add_subdirectory(sorting)
add_subdirectory(geometry)
add_subdirectory(graphics)
add_subdirectory(searching)
add_subdirectory(conversions)
add_subdirectory(client_server)
add_subdirectory(project_euler)
add_subdirectory(machine_learning)
add_subdirectory(numerical_methods)
## Configure Doxygen documentation system
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_GENERATE_TREEVIEW YES)
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
set(DOXYGEN_STRIP_CODE_COMMENTS NO)
set(DOXYGEN_ENABLE_PREPROCESSING YES)
set(DOXYGEN_EXT_LINKS_IN_WINDOW YES)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_CLANG_ASSISTED_PARSING YES)
set(DOXYGEN_FILE_PATTERNS *.c *.h *.md)
set(DOXYGEN_MATHJAX_EXTENSIONS TeX/AMSmath TeX/AMSsymbols)
set(DOXYGEN_TAGFILES "doc/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/")
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()
## Enable tool to generate binary distribution files
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

76
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at 1anuppanwar@gmail.com, dynamitechetan@gmail.com, nikhilkala8@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
<https://www.contributor-covenant.org/faq>

218
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,218 @@
# CONTRIBUTION GUIDELINES
## Before contributing
Welcome to [TheAlgorithms/C](https://github.com/TheAlgorithms/C)! Before submitting pull requests, please make sure that you have **read the whole guidelines**. If you have any doubts about this contribution guide, please open [an issue](https://github.com/TheAlgorithms/C/issues/new/choose) or ask in our [Discord server](https://discord.gg/c7MnfGFGa6), and clearly state your concerns.
## Contributing
### Maintainer/reviewer
**Please check the [reviewer code](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/REVIEWER_CODE.md) file for maintainers and reviewers.**
### Contributor
Being a contributor at The Algorithms, we request you to follow the points mentioned below:
- You did your own work.
- No plagiarism allowed. Any plagiarized work will not be merged.
- Your work will be distributed under the [GNU General Public License v3.0](https://github.com/TheAlgorithms/C/blob/master/LICENSE) once your pull request has been merged.
- Please follow the repository guidelines and standards mentioned below.
**New implementation** New implementations are welcome!
You can add new algorithms or data structures which are **not present in the repository** or that can **improve** the old implementations (**documentation**, **improving test cases**, removing bugs or in any other resonable sense)
**Issues** Please avoid opening issues asking to be "assigned” to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request, and it will be evaluated by project maintainers.
### Making Changes
#### Code
- Please use the directory structure of the repository.
- Make sure the file extensions should be `*.h` `*.c`
- Organize your code using the **`struct`** keyword
- If an implementation of the algorithm already exists, please refer to the [file-name section below](#file-name-guidelines).
- You can suggest reasonable changes to existing algorithms.
- 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 [__CMake__](https://cmake.org/) on all the 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 the use of these guidelines.**
#### Documentation
- Make sure you put useful comments in your code. Do not comment on obvious things.
- 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 must not contain grammatical errors.
- Do not update [`README.md`](https://github.com/TheAlgorithms/C/blob/master/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`](https://github.com/TheAlgorithms/C/blob/master/README.md).
- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repository website](https://thealgorithms.github.io/C). Please ensure the code is documented in this structure. A sample implementation is given below.
#### Test
- Make sure to add examples and test cases in your `main()` function.
- If you find an 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 the expected output. Use the `assert()` function to confirm that the tests will pass. Requires including the `assert.h` library.
#### Typical structure of a program
```c
/**
* @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.c, another_file.c
*/
#include <assert.h> /// for assert
#include /// for `some function here`
/**
* @brief Struct documentation
*/
struct struct_name {
int variable; ///< short info of this variable
char message; ///< short info
};
/**
* @brief Function documentation
* @param param1 one-line info about param1
* @param param2 one-line info about param2
* @returns `true` if ...
* @returns `false` if ...
*/
bool func(int param1, int param2) {
// function statements here
if (/*something bad*/) {
return false;
}
return true;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
/* desciptions of the following test */
assert(func(...) == ...); // this ensures that the algorithm works as expected
// can have multiple checks
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
// code here
return 0;
}
```
#### File name guidelines
- Use lowercase words with ``"_"`` as a separator
- For instance
```markdown
MyNewCStruct.C is incorrect
my_new_c_struct.c is correct format
```
- It will be used to dynamically create a directory of files and implementation.
- File name validation will run on Docker to ensure validity.
- If an implementation of the algorithm already exists and your version is different from that implemented, please use incremental numeric digit as a suffix. For example: if `median_search.c` already exists in the `search` folder, and you are contributing a new implementation, the filename should be `median_search2.c` and for a third implementation, `median_search3.c`.
#### Directory guidelines
- We recommend adding files to existing directories as much as possible.
- Use lowercase words with ``"_"`` as separator ( no spaces or ```"-"``` allowed )
- For instance
```markdown
SomeNew Fancy-Category is incorrect
some_new_fancy_category is correct
```
- Filepaths will be used to dynamically create a directory of our algorithms.
- Filepath validation will run on GitHub Actions to ensure compliance.
#### Commit Guidelines
- It is recommended to keep your changes grouped logically within individual commits. Maintainers find it easier to understand changes that are logically spilt across multiple commits. Try to modify just one or two files in the same directory. Pull requests that span multiple directories are often rejected.
```bash
git add file_xyz.c
git commit -m "your message"
```
Examples of commit messages with semantic prefixes:
```markdown
fix: xyz algorithm bug
feat: add xyx algorithm, struct xyz
test: add test for xyz algorithm
docs: add comments and explanation to xyz algorithm
```
Common prefixes:
- fix: A bug fix
- feat: A new feature
- docs: Documentation changes
- test: Correct existing tests or add new ones
### Pull Requests
- Checkout our [pull request template](https://github.com/TheAlgorithms/C/blob/master/.github/pull_request_template.md)
#### Building Locally
Before submitting a pull request, build the code locally or using the convenient [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C) service.
```bash
cmake -B build -S .
```
#### Static Code Analyzer
We use [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) as a static code analyzer with a configuration in [.clang-tidy](.clang-tidy).
```bash
clang-tidy --fix --quiet -p build subfolder/file_to_check.c --
```
#### Code Formatter
[__clang-format__](https://clang.llvm.org/docs/ClangFormat.html) is used for code forrmating.
- Installation (only needs to be installed once.)
- Mac (using home-brew): `brew install clang-format`
- Mac (using macports): `sudo port install clang-10 +analyzer`
- Windows (MSYS2 64-bit): `pacman -S mingw-w64-x86_64-clang-tools-extra`
- Linux (Debian): `sudo apt-get install clang-format-10 clang-tidy-10`
- Running (all platforms): `clang-format -i -style="file" my_file.c`
#### GitHub Actions
- Enable GitHub Actions on your fork of the repository.
After enabling, it will execute `clang-tidy` and `clang-format` after every a push (not a commit).
- Click on the tab "Actions", then click on the big green button to enable it.
![GitHub Actions](https://user-images.githubusercontent.com/51391473/94609466-6e925100-0264-11eb-9d6f-3706190eab2b.png)
- The result can create another commit if the actions made any changes on your behalf.
- Hence, it is better to wait and check the results of GitHub Actions after every push.
- Run `git pull` in your local clone if these actions made many changes to avoid merge conflicts.
Most importantly,
- Happy coding!

417
DIRECTORY.md Normal file
View File

@@ -0,0 +1,417 @@
# List of all files
## Audio
* [Alaw](https://github.com/TheAlgorithms/C/blob/master/audio/alaw.c)
## Client Server
* [Client](https://github.com/TheAlgorithms/C/blob/master/client_server/client.c)
* [Server](https://github.com/TheAlgorithms/C/blob/master/client_server/server.c)
* [Tcp Full Duplex Client](https://github.com/TheAlgorithms/C/blob/master/client_server/tcp_full_duplex_client.c)
* [Tcp Full Duplex Server](https://github.com/TheAlgorithms/C/blob/master/client_server/tcp_full_duplex_server.c)
* [Tcp Half Duplex Client](https://github.com/TheAlgorithms/C/blob/master/client_server/tcp_half_duplex_client.c)
* [Tcp Half Duplex Server](https://github.com/TheAlgorithms/C/blob/master/client_server/tcp_half_duplex_server.c)
* [Udp Client](https://github.com/TheAlgorithms/C/blob/master/client_server/udp_client.c)
* [Udp Server](https://github.com/TheAlgorithms/C/blob/master/client_server/udp_server.c)
## Conversions
* [Binary To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/binary_to_decimal.c)
* [Binary To Hexadecimal](https://github.com/TheAlgorithms/C/blob/master/conversions/binary_to_hexadecimal.c)
* [Binary To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/binary_to_octal.c)
* [C Atoi Str To Integer](https://github.com/TheAlgorithms/C/blob/master/conversions/c_atoi_str_to_integer.c)
* [Decimal To Any Base](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_any_base.c)
* [Decimal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_binary.c)
* [Decimal To Binary Recursion](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_binary_recursion.c)
* [Decimal To Hexa](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_hexa.c)
* [Decimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal.c)
* [Decimal To Octal Recursion](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal_recursion.c)
* [Hexadecimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal.c)
* [Hexadecimal To Octal2](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal2.c)
* [Infix To Postfix](https://github.com/TheAlgorithms/C/blob/master/conversions/infix_to_postfix.c)
* [Infix To Postfix2](https://github.com/TheAlgorithms/C/blob/master/conversions/infix_to_postfix2.c)
* [Int To String](https://github.com/TheAlgorithms/C/blob/master/conversions/int_to_string.c)
* [Octal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_binary.c)
* [Octal To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_decimal.c)
* [Octal To Hexadecimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_hexadecimal.c)
* [To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/to_decimal.c)
## Data Structures
* Array
* [Carray](https://github.com/TheAlgorithms/C/blob/master/data_structures/array/carray.c)
* [Carray](https://github.com/TheAlgorithms/C/blob/master/data_structures/array/carray.h)
* [Carray Tests](https://github.com/TheAlgorithms/C/blob/master/data_structures/array/carray_tests.c)
* Binary Trees
* [Avl Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/avl_tree.c)
* [Binary Search Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/binary_search_tree.c)
* [Create Node](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/create_node.c)
* [Recursive Traversals](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/recursive_traversals.c)
* [Red Black Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/red_black_tree.c)
* [Segment Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/segment_tree.c)
* [Threaded Binary Trees](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/threaded_binary_trees.c)
* [Words Alphabetical](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/words_alphabetical.c)
* Dictionary
* [Dict](https://github.com/TheAlgorithms/C/blob/master/data_structures/dictionary/dict.c)
* [Dict](https://github.com/TheAlgorithms/C/blob/master/data_structures/dictionary/dict.h)
* [Test Program](https://github.com/TheAlgorithms/C/blob/master/data_structures/dictionary/test_program.c)
* Dynamic Array
* [Dynamic Array](https://github.com/TheAlgorithms/C/blob/master/data_structures/dynamic_array/dynamic_array.c)
* [Dynamic Array](https://github.com/TheAlgorithms/C/blob/master/data_structures/dynamic_array/dynamic_array.h)
* [Main](https://github.com/TheAlgorithms/C/blob/master/data_structures/dynamic_array/main.c)
* Graphs
* [Bellman Ford](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/bellman_ford.c)
* [Bfs](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/bfs.c)
* [Bfs Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/bfs_queue.c)
* [Dfs](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/dfs.c)
* [Dfs Recursive](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/dfs_recursive.c)
* [Dijkstra](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/dijkstra.c)
* [Euler](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/euler.c)
* [Floyd Warshall](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/floyd_warshall.c)
* [Graph](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/graph.c)
* [Graph](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/graph.h)
* [Hamiltonian](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/hamiltonian.c)
* [Kruskal](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/kruskal.c)
* [Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/queue.c)
* [Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/queue.h)
* [Strongly Connected Components](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/strongly_connected_components.c)
* [Topological Sort](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/topological_sort.c)
* [Transitive Closure](https://github.com/TheAlgorithms/C/blob/master/data_structures/graphs/transitive_closure.c)
* Hash Set
* [Hash Set](https://github.com/TheAlgorithms/C/blob/master/data_structures/hash_set/hash_set.c)
* [Hash Set](https://github.com/TheAlgorithms/C/blob/master/data_structures/hash_set/hash_set.h)
* [Main](https://github.com/TheAlgorithms/C/blob/master/data_structures/hash_set/main.c)
* Heap
* [Max Heap](https://github.com/TheAlgorithms/C/blob/master/data_structures/heap/max_heap.c)
* [Min Heap](https://github.com/TheAlgorithms/C/blob/master/data_structures/heap/min_heap.c)
* Linked List
* [Ascending Priority Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/ascending_priority_queue.c)
* [Circular Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/circular_linked_list.c)
* [Doubly Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/doubly_linked_list.c)
* [Merge Linked Lists](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/merge_linked_lists.c)
* [Middle Element In List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/middle_element_in_list.c)
* [Queue Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/queue_linked_list.c)
* [Singly Link List Deletion](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/singly_link_list_deletion.c)
* [Stack Using Linked Lists](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/stack_using_linked_lists.c)
* List
* [List](https://github.com/TheAlgorithms/C/blob/master/data_structures/list/list.c)
* [List](https://github.com/TheAlgorithms/C/blob/master/data_structures/list/list.h)
* [Main](https://github.com/TheAlgorithms/C/blob/master/data_structures/list/main.c)
* Queue
* [Include](https://github.com/TheAlgorithms/C/blob/master/data_structures/queue/include.h)
* [Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/queue/queue.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack.c)
* Stack
* [Main](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/main.c)
* [Parenthesis](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/parenthesis.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/stack.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/stack.h)
* Stack Linked List
* [Main](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/stack_linked_list/main.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/stack_linked_list/stack.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/master/data_structures/stack/stack_linked_list/stack.h)
* Trie
* [Trie](https://github.com/TheAlgorithms/C/blob/master/data_structures/trie/trie.c)
## Developer Tools
* [Malloc Dbg](https://github.com/TheAlgorithms/C/blob/master/developer_tools/malloc_dbg.c)
* [Malloc Dbg](https://github.com/TheAlgorithms/C/blob/master/developer_tools/malloc_dbg.h)
* [Min Printf](https://github.com/TheAlgorithms/C/blob/master/developer_tools/min_printf.h)
* [Test Malloc Dbg](https://github.com/TheAlgorithms/C/blob/master/developer_tools/test_malloc_dbg.c)
* [Test Min Printf](https://github.com/TheAlgorithms/C/blob/master/developer_tools/test_min_printf.c)
## Exercism
* Acronym
* [Acronym](https://github.com/TheAlgorithms/C/blob/master/exercism/acronym/acronym.c)
* [Acronym](https://github.com/TheAlgorithms/C/blob/master/exercism/acronym/acronym.h)
* Hello World
* [Hello World](https://github.com/TheAlgorithms/C/blob/master/exercism/hello_world/hello_world.c)
* [Hello World](https://github.com/TheAlgorithms/C/blob/master/exercism/hello_world/hello_world.h)
* Isogram
* [Isogram](https://github.com/TheAlgorithms/C/blob/master/exercism/isogram/isogram.c)
* [Isogram](https://github.com/TheAlgorithms/C/blob/master/exercism/isogram/isogram.h)
* Rna Transcription
* [Rna Transcription](https://github.com/TheAlgorithms/C/blob/master/exercism/rna_transcription/rna_transcription.c)
* [Rna Transcription](https://github.com/TheAlgorithms/C/blob/master/exercism/rna_transcription/rna_transcription.h)
* Word Count
* [Word Count](https://github.com/TheAlgorithms/C/blob/master/exercism/word_count/word_count.c)
* [Word Count](https://github.com/TheAlgorithms/C/blob/master/exercism/word_count/word_count.h)
## Games
* [Naval Battle](https://github.com/TheAlgorithms/C/blob/master/games/naval_battle.c)
* [Tic Tac Toe](https://github.com/TheAlgorithms/C/blob/master/games/tic_tac_toe.c)
## Geometry
* [Geometry Datatypes](https://github.com/TheAlgorithms/C/blob/master/geometry/geometry_datatypes.h)
* [Quaternions](https://github.com/TheAlgorithms/C/blob/master/geometry/quaternions.c)
* [Vectors 3D](https://github.com/TheAlgorithms/C/blob/master/geometry/vectors_3d.c)
## Graphics
* [Spirograph](https://github.com/TheAlgorithms/C/blob/master/graphics/spirograph.c)
## Greedy Approach
* [Djikstra](https://github.com/TheAlgorithms/C/blob/master/greedy_approach/djikstra.c)
* [Prim](https://github.com/TheAlgorithms/C/blob/master/greedy_approach/prim.c)
## Hash
* [Hash Adler32](https://github.com/TheAlgorithms/C/blob/master/hash/hash_adler32.c)
* [Hash Crc32](https://github.com/TheAlgorithms/C/blob/master/hash/hash_crc32.c)
* [Hash Djb2](https://github.com/TheAlgorithms/C/blob/master/hash/hash_djb2.c)
* [Hash Sdbm](https://github.com/TheAlgorithms/C/blob/master/hash/hash_sdbm.c)
* [Hash Xor8](https://github.com/TheAlgorithms/C/blob/master/hash/hash_xor8.c)
## Leetcode
* Src
* [1](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/1.c)
* [101](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/101.c)
* [104](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/104.c)
* [108](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/108.c)
* [1089](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/1089.c)
* [109](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/109.c)
* [11](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/11.c)
* [110](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/110.c)
* [112](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/112.c)
* [1184](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/1184.c)
* [1189](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/1189.c)
* [12](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/12.c)
* [1207](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/1207.c)
* [121](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/121.c)
* [125](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/125.c)
* [13](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/13.c)
* [136](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/136.c)
* [141](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/141.c)
* [142](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/142.c)
* [153](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/153.c)
* [160](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/160.c)
* [169](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/169.c)
* [173](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/173.c)
* [189](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/189.c)
* [190](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/190.c)
* [191](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/191.c)
* [2](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/2.c)
* [20](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/20.c)
* [201](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/201.c)
* [203](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/203.c)
* [206](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/206.c)
* [21](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/21.c)
* [215](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/215.c)
* [217](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/217.c)
* [226](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/226.c)
* [231](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/231.c)
* [234](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/234.c)
* [24](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/24.c)
* [242](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/242.c)
* [26](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/26.c)
* [268](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/268.c)
* [27](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/27.c)
* [278](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/278.c)
* [28](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/28.c)
* [283](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/283.c)
* [287](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/287.c)
* [29](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/29.c)
* [3](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/3.c)
* [344](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/344.c)
* [35](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/35.c)
* [367](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/367.c)
* [38](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/38.c)
* [387](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/387.c)
* [389](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/389.c)
* [4](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/4.c)
* [404](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/404.c)
* [442](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/442.c)
* [461](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/461.c)
* [476](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/476.c)
* [509](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/509.c)
* [520](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/520.c)
* [53](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/53.c)
* [561](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/561.c)
* [617](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/617.c)
* [647](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/647.c)
* [66](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/66.c)
* [674](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/674.c)
* [7](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/7.c)
* [700](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/700.c)
* [701](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/701.c)
* [704](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/704.c)
* [709](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/709.c)
* [771](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/771.c)
* [8](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/8.c)
* [82](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/82.c)
* [83](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/83.c)
* [852](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/852.c)
* [876](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/876.c)
* [9](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/9.c)
* [905](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/905.c)
* [917](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/917.c)
* [938](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/938.c)
* [94](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/94.c)
* [965](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/965.c)
* [977](https://github.com/TheAlgorithms/C/blob/master/leetcode/src/977.c)
## Machine Learning
* [Adaline Learning](https://github.com/TheAlgorithms/C/blob/master/machine_learning/adaline_learning.c)
* [K Means Clustering](https://github.com/TheAlgorithms/C/blob/master/machine_learning/k_means_clustering.c)
* [Kohonen Som Topology](https://github.com/TheAlgorithms/C/blob/master/machine_learning/kohonen_som_topology.c)
* [Kohonen Som Trace](https://github.com/TheAlgorithms/C/blob/master/machine_learning/kohonen_som_trace.c)
## Misc
* [Armstrong Number](https://github.com/TheAlgorithms/C/blob/master/misc/armstrong_number.c)
* [Cantor Set](https://github.com/TheAlgorithms/C/blob/master/misc/cantor_set.c)
* [Cartesian To Polar](https://github.com/TheAlgorithms/C/blob/master/misc/cartesian_to_polar.c)
* [Catalan](https://github.com/TheAlgorithms/C/blob/master/misc/catalan.c)
* [Collatz](https://github.com/TheAlgorithms/C/blob/master/misc/collatz.c)
* [Demonetization](https://github.com/TheAlgorithms/C/blob/master/misc/demonetization.c)
* [Factorial](https://github.com/TheAlgorithms/C/blob/master/misc/factorial.c)
* [Factorial Large Number](https://github.com/TheAlgorithms/C/blob/master/misc/factorial_large_number.c)
* [Factorial Trailing Zeroes](https://github.com/TheAlgorithms/C/blob/master/misc/factorial_trailing_zeroes.c)
* [Fibonacci](https://github.com/TheAlgorithms/C/blob/master/misc/fibonacci.c)
* [Fibonacci Dp](https://github.com/TheAlgorithms/C/blob/master/misc/fibonacci_dp.c)
* [Fibonacci Fast](https://github.com/TheAlgorithms/C/blob/master/misc/fibonacci_fast.c)
* [Gcd](https://github.com/TheAlgorithms/C/blob/master/misc/gcd.c)
* [Is Armstrong](https://github.com/TheAlgorithms/C/blob/master/misc/is_armstrong.c)
* [Large Factorials](https://github.com/TheAlgorithms/C/blob/master/misc/large_factorials.c)
* [Lcm](https://github.com/TheAlgorithms/C/blob/master/misc/lcm.c)
* [Lerp](https://github.com/TheAlgorithms/C/blob/master/misc/lerp.c)
* [Lexicographic Permutations](https://github.com/TheAlgorithms/C/blob/master/misc/lexicographic_permutations.c)
* [Longest Subsequence](https://github.com/TheAlgorithms/C/blob/master/misc/longest_subsequence.c)
* [Mirror](https://github.com/TheAlgorithms/C/blob/master/misc/mirror.c)
* [Palindrome](https://github.com/TheAlgorithms/C/blob/master/misc/palindrome.c)
* [Pid](https://github.com/TheAlgorithms/C/blob/master/misc/pid.c)
* [Poly Add](https://github.com/TheAlgorithms/C/blob/master/misc/poly_add.c)
* [Postfix Evaluation](https://github.com/TheAlgorithms/C/blob/master/misc/postfix_evaluation.c)
* [Prime](https://github.com/TheAlgorithms/C/blob/master/misc/prime.c)
* [Prime Factoriziation](https://github.com/TheAlgorithms/C/blob/master/misc/prime_factoriziation.c)
* [Prime Seive](https://github.com/TheAlgorithms/C/blob/master/misc/prime_seive.c)
* [Quartile](https://github.com/TheAlgorithms/C/blob/master/misc/quartile.c)
* [Rselect](https://github.com/TheAlgorithms/C/blob/master/misc/rselect.c)
* [Strong Number](https://github.com/TheAlgorithms/C/blob/master/misc/strong_number.c)
* [Sudoku Solver](https://github.com/TheAlgorithms/C/blob/master/misc/sudoku_solver.c)
* [Tower Of Hanoi](https://github.com/TheAlgorithms/C/blob/master/misc/tower_of_hanoi.c)
* [Union Find](https://github.com/TheAlgorithms/C/blob/master/misc/union_find.c)
## Numerical Methods
* [Durand Kerner Roots](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/durand_kerner_roots.c)
* [Gauss Elimination](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/gauss_elimination.c)
* [Gauss Seidel Method](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/gauss_seidel_method.c)
* [Lagrange Theorem](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/lagrange_theorem.c)
* [Lu Decompose](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/lu_decompose.c)
* [Mean](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/mean.c)
* [Median](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/median.c)
* [Newton Raphson Root](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/newton_raphson_root.c)
* [Ode Forward Euler](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/ode_forward_euler.c)
* [Ode Midpoint Euler](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/ode_midpoint_euler.c)
* [Ode Semi Implicit Euler](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/ode_semi_implicit_euler.c)
* [Qr Decompose](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/qr_decompose.h)
* [Qr Decomposition](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/qr_decomposition.c)
* [Qr Eigen Values](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/qr_eigen_values.c)
* [Realtime Stats](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/realtime_stats.c)
* [Simpsons 1 3Rd Rule](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/simpsons_1_3rd_rule.c)
* [Variance](https://github.com/TheAlgorithms/C/blob/master/numerical_methods/variance.c)
## Project Euler
* Problem 1
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_1/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_1/sol2.c)
* [Sol3](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_1/sol3.c)
* [Sol4](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_1/sol4.c)
* Problem 10
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_10/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_10/sol2.c)
* Problem 12
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_12/sol1.c)
* Problem 13
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_13/sol1.c)
* Problem 14
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_14/sol1.c)
* Problem 15
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_15/sol1.c)
* Problem 16
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_16/sol1.c)
* Problem 19
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_19/sol1.c)
* Problem 2
* [So1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_2/so1.c)
* Problem 20
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_20/sol1.c)
* Problem 21
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_21/sol1.c)
* Problem 22
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_22/sol1.c)
* Problem 23
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_23/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_23/sol2.c)
* Problem 25
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_25/sol1.c)
* Problem 26
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_26/sol1.c)
* Problem 3
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_3/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_3/sol2.c)
* Problem 4
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_4/sol.c)
* Problem 401
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_401/sol1.c)
* Problem 5
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol2.c)
* [Sol3](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_5/sol3.c)
* Problem 6
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_6/sol.c)
* Problem 7
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_7/sol.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_7/sol2.c)
* Problem 8
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_8/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_8/sol2.c)
* Problem 9
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_9/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/problem_9/sol2.c)
## Searching
* [Binary Search](https://github.com/TheAlgorithms/C/blob/master/searching/binary_search.c)
* [Exponential Search](https://github.com/TheAlgorithms/C/blob/master/searching/exponential_search.c)
* [Fibonacci Search](https://github.com/TheAlgorithms/C/blob/master/searching/fibonacci_search.c)
* [Floyd Cycle Detection Algorithm](https://github.com/TheAlgorithms/C/blob/master/searching/floyd_cycle_detection_algorithm.c)
* [Interpolation Search](https://github.com/TheAlgorithms/C/blob/master/searching/interpolation_search.c)
* [Jump Search](https://github.com/TheAlgorithms/C/blob/master/searching/jump_search.c)
* [Linear Search](https://github.com/TheAlgorithms/C/blob/master/searching/linear_search.c)
* [Modified Binary Search](https://github.com/TheAlgorithms/C/blob/master/searching/modified_binary_search.c)
* [Other Binary Search](https://github.com/TheAlgorithms/C/blob/master/searching/other_binary_search.c)
* Pattern Search
* [Boyer Moore Search](https://github.com/TheAlgorithms/C/blob/master/searching/pattern_search/boyer_moore_search.c)
* [Naive Search](https://github.com/TheAlgorithms/C/blob/master/searching/pattern_search/naive_search.c)
* [Rabin Karp Search](https://github.com/TheAlgorithms/C/blob/master/searching/pattern_search/rabin_karp_search.c)
* [Sentinel Linear Search](https://github.com/TheAlgorithms/C/blob/master/searching/sentinel_linear_search.c)
* [Ternary Search](https://github.com/TheAlgorithms/C/blob/master/searching/ternary_search.c)
## Sorting
* [Bead Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/bead_sort.c)
* [Binary Insertion Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/binary_insertion_sort.c)
* [Bogo Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/bogo_sort.c)
* [Bubble Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/bubble_sort.c)
* [Bubble Sort 2](https://github.com/TheAlgorithms/C/blob/master/sorting/bubble_sort_2.c)
* [Bubble Sort Recursion](https://github.com/TheAlgorithms/C/blob/master/sorting/bubble_sort_recursion.c)
* [Bucket Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/bucket_sort.c)
* [Cocktail Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/cocktail_sort.c)
* [Comb Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/comb_sort.c)
* [Counting Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/counting_sort.c)
* [Cycle Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/cycle_sort.c)
* [Gnome Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/gnome_sort.c)
* [Heap Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort.c)
* [Heap Sort 2](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort_2.c)
* [Insertion Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort.c)
* [Insertion Sort Recursive](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort_recursive.c)
* [Merge Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort.c)
* [Merge Sort Nr](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort_nr.c)
* [Multikey Quick Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/multikey_quick_sort.c)
* [Odd Even Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/odd_even_sort.c)
* [Pancake Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/pancake_sort.c)
* [Partition Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/partition_sort.c)
* [Pigeonhole Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/pigeonhole_sort.c)
* [Quick Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/quick_sort.c)
* [Radix Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/radix_sort.c)
* [Radix Sort 2](https://github.com/TheAlgorithms/C/blob/master/sorting/radix_sort_2.c)
* [Random Quick Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/random_quick_sort.c)
* [Selection Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/selection_sort.c)
* [Selection Sort Recursive](https://github.com/TheAlgorithms/C/blob/master/sorting/selection_sort_recursive.c)
* [Shaker Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/shaker_sort.c)
* [Shell Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/shell_sort.c)
* [Shell Sort2](https://github.com/TheAlgorithms/C/blob/master/sorting/shell_sort2.c)
* [Stooge Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/stooge_sort.c)

277
Doxyfile Normal file
View File

@@ -0,0 +1,277 @@
#
# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE!
#
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Algorithms_in_C
PROJECT_NUMBER = 1.0.0
PROJECT_BRIEF = "Set of algorithms implemented in C."
PROJECT_LOGO =
OUTPUT_DIRECTORY = /Users/kvedala/GitHub/C/build
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
OUTPUT_TEXT_DIRECTION = None
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
INPUT = /Users/kvedala/GitHub/C
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.idl *.ddl *.odl *.h *.hh *.hxx *.hpp *.h++ *.cs *.d *.php *.php4 *.php5 *.phtml *.inc *.m *.markdown *.md *.mm *.dox *.doc *.txt *.py *.pyw *.f90 *.f95 *.f03 *.f08 *.f18 *.f *.for *.vhd *.vhdl *.ucf *.qsf *.ice
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */.git/* */.svn/* */.hg/* */CMakeFiles/* */_CPack_Packages/* DartConfiguration.tcl CMakeLists.txt CMakeCache.txt
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
SOURCE_BROWSER = NO
INLINE_SOURCES = YES
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE =
USE_MATHJAX = YES
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME =
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
GENERATE_XML = NO
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
DOT_PATH = /Users/kvedala/anaconda3/bin
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

676
LICENSE Normal file
View File

@@ -0,0 +1,676 @@
Copyright (C) 2016-2021 TheAlgorithms and contributors
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

101
README.md
View File

@@ -1,81 +1,40 @@
# C
# 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 -->
## Computer Oriented Statistical Methods
- Gauss_Elimination
- Lagrange_Theorem
- Mean
- Median
- Seidal
- Simpson's_1-3rd_rule.c
- Variance
- statistic (C Lib)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C/context:cpp)
[![CodeQL CI](https://github.com/TheAlgorithms/C/actions/workflows/codeql_analysis.yml/badge.svg)](https://github.com/TheAlgorithms/C/actions/workflows/codeql_analysis.yml)
[![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/blob/master/CONTRIBUTING.md)
![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C?color=red&style=flat-square)
[![Doxygen CI](https://github.com/TheAlgorithms/C/workflows/Doxygen%20CI/badge.svg)](https://TheAlgorithms.github.io/C)
[![Awesome CI](https://github.com/TheAlgorithms/C/workflows/Awesome%20CI%20Workflow/badge.svg)](https://github.com/TheAlgorithms/C/actions?query=workflow%3A%22Awesome+CI+Workflow%22)
[![Income](https://img.shields.io/liberapay/receives/TheAlgorithms.svg?logo=liberapay)](https://liberapay.com/TheAlgorithms)
[![Discord chat](https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA)](https://discord.gg/c7MnfGFGa6)
[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/TheAlgorithms/donate)
## Conversions
- binary_to_decimal
- decimal _to_binary
- decimal_to_hexa
- decimal_to_octal
- to_decimal
## Overview
## Data Structures
- stack
- queue
- dictionary
linked_list
- singly_link_list_deletion
- stack_using_linkedlists
binary_trees
- create_node
- recursive_traversals
trie
- trie
The repository is a collection of open-source implementations of a variety of algorithms implemented in C and licensed under [GPLv3 License](https://github.com/TheAlgorithms/C/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 their associated documentations 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 different algorithm strategies and optimizations.
## Features
## Searching
- Binary_Search
- Other_Binary_Search
- Jump_Search
* The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C](https://en.wikipedia.org/wiki/C_(programming_language)).
* Well documented source code with detailed explanations provide a valuable resource for educators and students alike.
* Each source code is atomic using standard C library [`libc`](https://en.wikipedia.org/wiki/C_standard_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/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 [C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)) 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
## Sorting
- binary_insertion_sort
- BubbleSort
- BogoSort
- InsertionSort
- mergesort
- OtherBubbleSort
- QuickSort
- SelectionSort
- shaker_sort
- HeapSort
## Hashing
- sdbm
- djb2
- xor8 (8 bit)
- adler_32 (32 bit)
[Online Documentation](https://TheAlgorithms.github.io/C) 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.
Click on [Files menu](https://TheAlgorithms.github.io/C/files.html) to see the list of all the files documented with the code.
[Documentation of Algorithms in C](https://thealgorithms.github.io/C) by [The Algorithms Contributors](https://github.com/TheAlgorithms/C/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>
## Misc
- Binning
- Factorial
- Fibonacci
- isArmstrong
- LongestSubSequence
- palindrome
- QUARTILE
- rselect
- strongNumber
- TowerOfHanoi
- Greatest Common Divisor
- Sudoku Solver
## exercism
In this directory you will find (in the right order):
* hello-world
* isogram
* acronym
* word-count
* rna-transcription
## 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/blob/master/CONTRIBUTING.md).

13
REVIEWER_CODE.md Normal file
View File

@@ -0,0 +1,13 @@
# Guidelines for reviewers and maintainers
Following are some guidelines for contributors who are providing reviews to the pull-requests.
1. On any given pull-request, there only one reviewer should be active at a time. Once the reviewer is done, others may add short comments or any further reviews as needed. Again, one at a time.
2. Assigning reviewers should be avoided unless the pull-request is for a particular task the reviewer is more proficient in.
3. Any contributor who has had their code merged into the repo can provide with reviews as they have gone through the repo standards at least once before. The reviewer will be on a first-come-first serve basis.
4. Most repositories have a check-list in the description for pull-requests. Many times, the contributors are not following them and simply remove the checklist or checkthem without taking the time to review the checklist items. These contributors are almost always copying the code from somewhere. These should be pointed out politely and reviews should be blocked until the contributor updates the basic code structure per the checklist and the repo standards.
5. The reviewers should label every pull-request appropriately - including "invalid" as the case may be.
6. Some pull-requests have existing duplicate code or duplicate pull-requests or sometimes, a novice might create a new pull-request for every new commit. This is a daunting task but one of the responsibility of a reviewer.
7. Discourage creating branches on the repo but rather fork the repo to the respective userspace and contribute from that fork.
8. Some repos - C & C++ - have collaboration with GitPod wherein the code and the contribution can be executed and tested online with relative simplicity. It also contains tools necessary to perform debug and CI checks without installing any tools. Encourage contributors to utilize the feature. Reviewers can test the contributed algorithms online without worrying about forks and branches.
9. There should not be any hurry to merge pull-requests. Since the repos are educational, better to get the contributions right even if it takes a bit longer to review. Encourage patience and develop debugging skills of contributors.

14
audio/CMakeLists.txt Normal file
View File

@@ -0,0 +1,14 @@
# 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} *.c )
# 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 ".c" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
install(TARGETS ${testname} DESTINATION "bin/audio")
endforeach( testsourcefile ${APP_SOURCES} )

216
audio/alaw.c Normal file
View File

@@ -0,0 +1,216 @@
/**
* @file
* @author [sunzhenliang](https://github.com/HiSunzhenliang)
* @brief A-law algorithm for encoding and decoding (16bit pcm <=> a-law).
* This is the implementation of [G.711](https://en.wikipedia.org/wiki/G.711)
* in C.
**/
/**
* Linear input code | Compressed code | Linear output code
* ------------------+-----------------+-------------------
* s0000000abcdx | s000abcd | s0000000abcd1
* s0000001abcdx | s001abcd | s0000001abcd1
* s000001abcdxx | s010abcd | s000001abcd10
* s00001abcdxxx | s011abcd | s00001abcd100
* s0001abcdxxxx | s100abcd | s0001abcd1000
* s001abcdxxxxx | s101abcd | s001abcd10000
* s01abcdxxxxxx | s110abcd | s01abcd100000
* s1abcdxxxxxxx | s111abcd | s1abcd1000000
*
* Compressed code: (s | eee | abcd)
**/
#include <assert.h> /// for assert
#include <inttypes.h> /// for appropriate size int types
#include <stdio.h> /// for IO operations
/* length of test inputs */
#define LEN ((size_t)8)
/* input pcm for test */
int16_t pcm[LEN] = {1000, -1000, 1234, 3200, -1314, 0, 32767, -32768};
/* result coded alaw for test */
uint8_t r_coded[LEN] = {250, 122, 230, 156, 97, 213, 170, 42};
/* result decoded for test */
int16_t r_decoded[LEN] = {1008, -1008, 1248, 3264, -1312, 8, 32256, -32256};
/**
* @brief 16bit pcm to 8bit alaw
* @param out unsigned 8bit alaw array
* @param in signed 16bit pcm array
* @param len length of pcm array
* @returns void
*/
void encode(uint8_t *out, int16_t *in, size_t len)
{
uint8_t alaw = 0;
int16_t pcm = 0;
int32_t sign = 0;
int32_t abcd = 0;
int32_t eee = 0;
int32_t mask = 0;
for (size_t i = 0; i < len; i++)
{
pcm = *in++;
/* 0-7 kinds of quantization level from the table above */
eee = 7;
mask = 0x4000; /* 0x4000: '0b0100 0000 0000 0000' */
/* Get sign bit */
sign = (pcm & 0x8000) >> 8;
/* Turn negative pcm to positive */
/* The absolute value of a negative number may be larger than the size
* of the corresponding positive number, so here needs `-pcm -1` after
* taking the opposite number. */
pcm = sign ? (-pcm - 1) : pcm;
/* Get eee and abcd bit */
/* Use mask to locate the first `1` bit and quantization level at the
* same time */
while ((pcm & mask) == 0 && eee > 0)
{
eee--;
mask >>= 1;
}
/* The location of abcd bits is related with quantization level. Check
* the table above to determine how many bits to `>>` to get abcd */
abcd = (pcm >> (eee ? (eee + 3) : 4)) & 0x0f;
/* Put the quantization level number at right bit location to get eee
* bits */
eee <<= 4;
/* Splice results */
alaw = (sign | eee | abcd);
/* The standard specifies that all resulting even bits (LSB
* is even) are inverted before the octet is transmitted. This is to
* provide plenty of 0/1 transitions to facilitate the clock recovery
* process in the PCM receivers. Thus, a silent A-law encoded PCM
* channel has the 8 bit samples coded 0xD5 instead of 0x80 in the
* octets. (Reference from wiki above) */
*out++ = alaw ^ 0xD5;
}
}
/**
* @brief 8bit alaw to 16bit pcm
* @param out signed 16bit pcm array
* @param in unsigned 8bit alaw array
* @param len length of alaw array
* @returns void
*/
void decode(int16_t *out, uint8_t *in, size_t len)
{
uint8_t alaw = 0;
int32_t pcm = 0;
int32_t sign = 0;
int32_t eee = 0;
for (size_t i = 0; i < len; i++)
{
alaw = *in++;
/* Re-toggle toggled bits */
alaw ^= 0xD5;
/* Get sign bit */
sign = alaw & 0x80;
/* Get eee bits */
eee = (alaw & 0x70) >> 4;
/* Get abcd bits and add 1/2 quantization step */
pcm = (alaw & 0x0f) << 4 | 8;
/* If quantization level > 0, there need `1` bit before abcd bits */
pcm += eee ? 0x100 : 0x0;
/* Left shift according quantization level */
pcm <<= eee > 1 ? (eee - 1) : 0;
/* Use the right sign */
*out++ = sign ? -pcm : pcm;
}
}
/**
* @brief Self-test implementations
* @param pcm signed 16bit pcm array
* @param coded unsigned 8bit alaw array
* @param decoded signed 16bit pcm array
* @param len length of test array
* @returns void
*/
static void test(int16_t *pcm, uint8_t *coded, int16_t *decoded, size_t len)
{
/* run encode */
encode(coded, pcm, len);
/* check encode result */
for (size_t i = 0; i < len; i++)
{
assert(coded[i] == r_coded[i]);
}
/* run decode */
decode(decoded, coded, len);
/* check decode result */
for (size_t i = 0; i < len; i++)
{
assert(decoded[i] == r_decoded[i]);
}
}
/**
* @brief Main function
* @param argc commandline argument count (ignored)
* @param argv commandline array of arguments (ignored)
* @returns 0 on exit
*/
int main(int argc, char *argv[])
{
/* output alaw encoded by encode() */
uint8_t coded[LEN];
/* output pcm decoded by decode() from coded[LEN] */
int16_t decoded[LEN];
test(pcm, coded, decoded, LEN); // run self-test implementations
/* print test pcm inputs */
printf("inputs: ");
for (size_t i = 0; i < LEN; i++)
{
printf("%d ", pcm[i]);
}
printf("\n");
/* print encoded alaw */
printf("encode: ");
for (size_t i = 0; i < LEN; i++)
{
printf("%u ", coded[i]);
}
printf("\n");
/* print decoded pcm */
printf("decode: ");
for (size_t i = 0; i < LEN; i++)
{
printf("%d ", decoded[i]);
}
printf("\n");
/* It can be seen that the encoded alaw is smaller than the input PCM, so
* the purpose of compression is achieved. And the decoded PCM is almost the
* same as the original input PCM, which verifies the correctness of the
* decoding. The reason why it is not exactly the same is that there is
* precision loss during encode / decode. */
return 0;
}

View File

@@ -0,0 +1,44 @@
if(WIN32)
check_include_file(winsock2.h WINSOCK_HEADER)
else()
check_include_file(arpa/inet.h ARPA_HEADERS)
endif()
if(ARPA_HEADERS OR WINSOCK_HEADER)
# 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} *.c )
# 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 ".c" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
if(OpenMP_C_FOUND)
target_link_libraries(${testname} PRIVATE OpenMP::OpenMP_C)
endif()
if(MATH_LIBRARY)
target_link_libraries(${testname} PRIVATE ${MATH_LIBRARY})
endif()
# if(HAS_UNISTD)
# target_compile_definitions(${testname} PRIVATE HAS_UNISTD)
# endif()
# if(ARPA_HEADERS)
# target_compile_definitions(${testname} PRIVATE ARPA_HEADERS)
# else()
# target_compile_definitions(${testname} PRIVATE WINSOCK_HEADER)
# endif()
if(WINSOCK_HEADER)
target_link_libraries(${testname} PRIVATE ws2_32) # link winsock library on windows
endif()
install(TARGETS ${testname} DESTINATION "bin/client_server")
endforeach( testsourcefile ${APP_SOURCES} )
else()
message(WARNING "socket headers not found in system.")
endif(ARPA_HEADERS OR WINSOCK_HEADER)

122
client_server/client.c Normal file
View File

@@ -0,0 +1,122 @@
/**
* @file
* @author [Nairit11](https://github.com/Nairit11)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Client side implementation of Server-Client system.
* @see client_server/server.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#include <winsock2.h>
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define read(a, b, c) recv(a, b, c, 0) /**< map BSD name to Winsock */
#define write(a, b, c) send(a, b, c, 0) /**< map BSD name to Winsock */
#define close closesocket /**< map BSD name to Winsock */
#else // if not windows platform
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#define MAX 80 /**< max. characters per message */
#define PORT 8080 /**< port number to connect to */
#define SA struct sockaddr /**< shortname for sockaddr */
/**
* Continuous loop to send and receive over the socket.
* Exits when "exit" is sent from commandline.
* @param sockfd socket handle number
*/
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;)
{
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
{
;
}
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0)
{
printf("Client Exit...\n");
break;
}
}
}
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/**
* @brief Driver code
*/
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
perror("WSA Startup error: \n");
return 0;
}
atexit(cleanup); // register at-exit function
#endif
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
printf("socket creation failed...\n");
exit(0);
}
else
{
printf("Socket successfully created..\n");
}
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) != 0)
{
printf("connection with the server failed...\n");
exit(0);
}
else
{
printf("connected to the server..\n");
}
// function for chat
func(sockfd);
// close the socket
close(sockfd);
return 0;
}

158
client_server/server.c Normal file
View File

@@ -0,0 +1,158 @@
/**
* @file
* @author [Nairit11](https://github.com/Nairit11)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Server side implementation of Server-Client system.
* @see client_server/client.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #ifdef HAS_UNISTD
// #include <unistd.h>
// #endif
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#include <winsock2.h>
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define read(a, b, c) recv(a, b, c, 0) /**< map BSD name to Winsock */
#define write(a, b, c) send(a, b, c, 0) /**< map BSD name to Winsock */
#define close closesocket /**< map BSD name to Winsock */
#else
// if not windows platform
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#define MAX 80 /**< max. characters per message */
#define PORT 8080 /**< port number to connect to */
#define SA struct sockaddr /**< shortname for sockaddr */
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/**
* Continuous loop to send and receive over the socket.
* Exits when "exit" is sent from commandline.
* @param sockfd socket handle number
*/
void func(int sockfd)
{
char buff[MAX];
int n;
// infinite loop for chat
for (;;)
{
bzero(buff, MAX);
// read the message from client and copy it in buffer
read(sockfd, buff, sizeof(buff));
// print buffer which contains the client contents
printf("From client: %s\t To client : ", buff);
bzero(buff, MAX);
n = 0;
// copy server message in the buffer
while ((buff[n++] = getchar()) != '\n')
{
;
}
// and send that buffer to client
write(sockfd, buff, sizeof(buff));
// if msg contains "Exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0)
{
printf("Server Exit...\n");
break;
}
}
}
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
perror("WSA Startup error: \n");
return 0;
}
atexit(cleanup); // register at-exit function
#endif
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket creation failed...\n");
exit(0);
}
else
{
printf("Socket successfully created..\n");
}
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA *)&servaddr, sizeof(servaddr))) != 0)
{
perror("socket bind failed...\n");
exit(0);
}
else
{
printf("Socket successfully binded..\n");
}
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0)
{
perror("Listen failed...\n");
exit(0);
}
else
{
printf("Server listening..\n");
}
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA *)&cli, &len);
if (connfd < 0)
{
perror("server acccept failed...\n");
exit(0);
}
else
{
printf("server acccept the client...\n");
}
// Function for chatting between client and server
func(connfd);
// After chatting close the socket
close(sockfd);
return 0;
}

View File

@@ -0,0 +1,173 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Client-side implementation of [TCP Full Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_full_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send and receive data simultaneously. This is
* implemented by using the `fork` function call so that in the server the child
* process can recieve data and parent process can send data, and in the client
* the child process can send data and the parent process can receive data. It
* runs an infinite loop and can send and receive messages indefinitely until
* the user exits the loop. In this way, the Full Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <unistd.h> /// For miscellaneous symbolic constants and types, and miscellaneous functions
#define PORT 10000 /// Define port over which communication will take place
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
char sendbuff[1024],
recvbuff[1024]; ///< character arrays to read and store string data
/// for communication
struct sockaddr_in
server_addr; ///< asic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
/**
* The TCP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes.
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Client is running...\n");
/**
* Connects the client to the server address using the socket descriptor
* This enables the two to communicate and exchange data
*/
connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Client is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* The fork function call is used to create a child and parent process
* which run and execute code simultaneously
*
* The child process is used to send data and after doing so
* sleeps for 5 seconds to wait for the parent to receive data
*
* The parent process is used to receive data and after doing so
* sleeps for 5 seconds to wait for the child to send data
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* Since the exchange of information between the server and client takes
* place simultaneously this represents FULL DUPLEX COMMUNICATION
*/
pid_t pid;
pid = fork();
if (pid == 0) /// Value of 0 is for child process
{
while (1)
{
bzero(&sendbuff, sizeof(sendbuff));
printf("\nType message here: ");
fgets(sendbuff, 1024, stdin);
send(sockfd, sendbuff, strlen(sendbuff) + 1, 0);
printf("\nMessage sent!\n");
sleep(5);
// break;
}
}
else /// Parent Process
{
while (1)
{
bzero(&recvbuff, sizeof(recvbuff));
recv(sockfd, recvbuff, sizeof(recvbuff), 0);
printf("\nSERVER: %s\n", recvbuff);
sleep(5);
// break;
}
}
/// Close Socket
close(sockfd);
printf("Client is offline...\n");
return 0;
}

View File

@@ -0,0 +1,195 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Server-side implementation of [TCP Full Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_full_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send and receive data simultaneously. This is
* implemented by using the `fork` function call so that in the server the child
* process can recieve data and parent process can send data, and in the client
* the child process can send data and the parent process can receive data. It
* runs an infinite loop and can send and receive messages indefinitely until
* the user exits the loop. In this way, the Full Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <unistd.h> /// For miscellaneous symbolic constants and types, and miscellaneous functions
#define PORT 10000 /// Define port over which communication will take place
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t sockfd,
conn; ///< socket descriptors - Like file handles but for sockets
char recvbuff[1024],
sendbuff[1024]; ///< character arrays to read and store string data
/// for communication
struct sockaddr_in server_addr,
client_addr; ///< asic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
socklen_t ClientLen; /// size of address
/**
* The TCP socket is created using the socket function
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error(); ///< Error if the socket descriptor has a value lower than 0 -
/// socket wasnt created
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Server is running...\n");
/**
* This binds the socket descriptor to the server thus enabling the server
* to listen for connections and communicate with other clients
*/
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error(); /// If binding is unsuccessful
}
/**
* This is to listen for clients or connections made to the server
*
* The limit is currently at 5 but can be increased to listen for
* more connections
*
* It listens to connections through the socket descriptor
*/
listen(sockfd, 5);
printf("Server is listening...\n");
/**
* When a connection is found, a socket is created and connection is
* accepted and established through the socket descriptor
*/
conn = accept(sockfd, (struct sockaddr *)NULL, NULL);
printf("Server is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* The fork function call is used to create a child and parent process
* which run and execute code simultaneously
*
* The child process is used to receive data and after doing so
* sleeps for 5 seconds to wait for the parent to send data
*
* The parent process is used to send data and after doing so
* sleeps for 5 seconds to wait for the child to receive data
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* Since the exchange of information between the server and client takes
* place simultaneously this represents FULL DUPLEX COMMUNICATION
*/
pid_t pid;
pid = fork();
if (pid == 0) /// Value of 0 is for child process
{
while (1)
{
bzero(&recvbuff, sizeof(recvbuff));
recv(conn, recvbuff, sizeof(recvbuff), 0);
printf("\nCLIENT : %s\n", recvbuff);
sleep(5);
// break;
}
}
else /// Parent process
{
while (1)
{
bzero(&sendbuff, sizeof(sendbuff));
printf("\nType message here: ");
fgets(sendbuff, 1024, stdin);
send(conn, sendbuff, strlen(sendbuff) + 1, 0);
printf("\nMessage Sent!\n");
sleep(5);
// break;
}
}
/// Close socket
close(sockfd);
printf("Server is offline...\n");
return 0;
}

View File

@@ -0,0 +1,153 @@
/**
* @file
* @author [Nikhill Vombatkere](https://github.com/NVombat)
* @brief Client-side implementation of [TCP Half Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_half_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* the server and client can both send data but only one at a time. This is
* implemented by using a particular ordering of the `send()` and `recv()`
* functions. When one of the clients or servers is sending, the other can only
* receive and vice-versa. In this way, the Half Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <unistd.h> /// For miscellaneous symbolic constants and types, and miscellaneous functions
#define PORT 8100 /// Define port over which communication will take place
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
struct sockaddr_in
server_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
char serverResponse[10000],
clientResponse[10000]; ///< Character arrays to read and store string
/// data for communication
/**
* The TCP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes.
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Client is running...\n");
/**
* Connects the client to the server address using the socket descriptor
* This enables the two to communicate and exchange data
*/
connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Client is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* First the CLIENT receives the servers message and displays it (recv())
*
* The CLIENT is then prompted to type in a message and send it to the
* server. (send())
*
* The server and client can communicate till one of them exits the
* connection
*
* Since the exchange of information between the server and client take
* place one at a time this represents HALF DUPLEX COMMUNICATION
*/
while (1)
{
bzero(&serverResponse, sizeof(serverResponse));
bzero(&clientResponse, sizeof(clientResponse));
/// Receive Message
recv(sockfd, serverResponse, sizeof(serverResponse), 0);
printf("\nServer message: %s \n", serverResponse);
/// Send Message
printf("\nEnter message here: ");
fgets(clientResponse, 10000, stdin);
send(sockfd, clientResponse, strlen(clientResponse) + 1, 0);
}
/// Close Socket
close(sockfd);
printf("Client is offline...\n");
return 0;
}

View File

@@ -0,0 +1,177 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Server-side implementation of [TCP Half Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_half_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send data but only one at a time. This is
* implemented by using a particular ordering of the `send()` and `recv()`
* functions. When one of the clients or servers is sending, the other can only
* receive and vice-versa. In this way, the Half Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <unistd.h> /// For miscellaneous symbolic constants and types, and miscellaneous functions
#define PORT 8100 /// Define port over which communication will take place
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t sockfd,
conn; ///< socket descriptors - Like file handles but for sockets
char server_msg[10000],
client_msg[10000]; ///< character arrays to read and store string data
/// for communication
struct sockaddr_in server_addr,
client_addr; ///< asic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
/**
* The TCP socket is created using the socket function
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error(); ///< Error if the socket descriptor has a value lower than 0 -
/// socket wasnt created
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET; /// Domain/Family to be used
server_addr.sin_port = htons(PORT); /// Port to be used
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Server is running...\n");
/**
* This binds the socket descriptor to the server thus enabling the server
* to listen for connections and communicate with other clients
*/
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error(); /// If binding is unsuccessful
}
/**
* This is to listen for clients or connections made to the server
*
* The limit is currently at 5 but can be increased to listen for
* more connections
*
* It listens to connections through the socket descriptor
*/
listen(sockfd, 5);
printf("Server is listening...\n");
/**
* When a connection is found, a socket is created and connection is
* accepted and established through the socket descriptor
*/
conn = accept(sockfd, (struct sockaddr *)NULL, NULL);
printf("Server is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* First the SERVER is prompted to type a message which is read from
* stdin and then sent over the connection that was established - the socket
* - to be received by the client (send())
*
* The SERVER then waits for the client to reply. It then receives the reply
* in the string variable and displays it (recv())
*
* The server and client can communicate till one of them exits the
* connection
*
* Since the exchange of information between the server and client take
* place one at a time this represents HALF DUPLEX COMMUNICATION
*/
while (1)
{
bzero(&server_msg, sizeof(server_msg));
bzero(&client_msg, sizeof(client_msg));
/// Send message
printf("\nEnter message here: ");
fgets(server_msg, 10000, stdin);
send(conn, server_msg, strlen(server_msg) + 1, 0);
/// Receive Message
recv(conn, client_msg, sizeof(client_msg), 0);
printf("\nClient Message: %s\n", client_msg);
}
/// Close socket
close(sockfd);
printf("Server is offline...\n");
return 0;
}

View File

@@ -0,0 +1,82 @@
/**
* @file
* @author [TheShubham99](https://github.com/TheShubham99)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Client side implementation of UDP client-server model
* @see client_server/udp_server.c
*/
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#include <winsock2.h>
#define close closesocket /**< map BSD name to Winsock */
#else // if not windows platform
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8080 /**< port number to connect to */
#define MAXLINE 1024 /**< maximum characters per line */
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
perror("WSA Startup error: \n");
return 0;
}
atexit(cleanup); // register at-exit function
#endif
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n;
unsigned int len;
sendto(sockfd, (const char *)hello, strlen(hello), 0,
(const struct sockaddr *)&servaddr, sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL,
(struct sockaddr *)&servaddr, &len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}

View File

@@ -0,0 +1,89 @@
/**
* @file
* @author [TheShubham99](https://github.com/TheShubham99)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Server side implementation of UDP client-server model
* @see client_server/udp_client.c
*/
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#define close closesocket /**< map BSD name to Winsock */
#include <winsock2.h>
#else // if not windows platform
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8080 /**< port number to connect to */
#define MAXLINE 1024 /**< maximum characters per line */
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
perror("WSA Startup error: \n");
return 0;
}
atexit(cleanup); // register at-exit function
#endif
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
unsigned int len;
int n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL,
(struct sockaddr *)&cliaddr, &len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello), 0,
(const struct sockaddr *)&cliaddr, len);
printf("Hello message sent.\n");
close(sockfd);
return 0;
}

View File

@@ -1,100 +0,0 @@
#include<stdio.h>
#include<conio.h>
void display(float a[20][20],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<=n;j++)
{
printf("%.2f \t",a[i][j]);
}
printf("\n");
}
}
float interchange(float m[20][20],int i,int n)
{
float tmp[20][20];
float max=fabs(m[i][i]);
int j,k=i;
for(j=i;j<n;j++)
{
if(max<fabs(m[j][i]))
{
max=fabs(m[j][i]);
k=j;
}
}
for(j=0;j<=n;j++)
{
tmp[i][j]=m[i][j];
m[i][j]=m[k][j];
m[k][j]=tmp[i][j];
}
return m[20][20];
}
float eliminate(float m[20][20],int i,int n)
{
float tmp;
int k=1,l,j;
for(j=i;j<n-1;j++)
{
tmp=-((m[i+k][i])/(m[i][i]));
for(l=0;l<=n;l++)
{
m[i+k][l]=(m[i+k][l])+(m[i][l]*tmp);
}
k++;
}
return m[20][20];
}
void main()
{
int i,j,n,k=0,l;
float m[20][20],mul,tmp[20][20],val,ans[20];
clrscr();
printf("Total No.of Equations : ");
scanf("%d",&n);
printf("\n");
for(i=0;i<n;i++)
{
printf("Enter Co-efficient Of Equations %d & Total --->>>\n",i+1);
for(j=0;j<=n;j++)
{
printf("r%d%d : ",i,j);
scanf("%f",&m[i][j]);
}
printf("\n");
}
printf(":::::::::::: Current Matrix ::::::::::::\n\n");
display(m,n);
for(i=0;i<n-1;i++)
{
printf("\n------->>>>>>>>>>>>>>>>>>>>>>>>-------- %d\n",i+1);
m[20][20]=interchange(m,i,n);
display(m,n);
printf("\n_______________________________________\n");
m[20][20]=eliminate(m,i,n);
display(m,n);
}
printf("\n\n Values are : \n");
for(i=n-1;i>=0;i--)
{
l=n-1;
mul=0;
for(j=0;j<k;j++)
{
mul=mul+m[i][l]*ans[l];
l--;
}
k++;
ans[i]=(m[i][n]-mul)/m[i][i];
printf("X%d = %.2f\n",i+1,ans[i]);
}
getch();
}

View File

@@ -1,46 +0,0 @@
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int a[10],n,i,j,temp,sum=0;
float mean;
clrscr();
printf("Enter no. for Random Numbers :");
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i]=rand()%100;
}
printf("Random Numbers Generated are :\n");
for(i=0;i<n;i++)
{
printf("\n%d",a[i]);
}
printf("\n");
printf("\nSorted Data:");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
for(i=0;i<n;i++)
{
printf("\n%d",a[i]);
sum=sum+a[i];
}
mean=sum/(float)n;
printf("\nMean :");
printf("%f",mean);
getch();
}

View File

@@ -1,50 +0,0 @@
#include<stdio.h>
//#include<conio.h>
#include<math.h>
void main()
{
int a[10],n,i,j,temp;
float mean,median;
clrscr();
printf("Enter no. for Random Numbers :");
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i]=rand()%100;
}
printf("Random Numbers Generated are :\n");
for(i=0;i<n;i++)
{
printf("\n%d",a[i]);
}
printf("\n");
printf("\nSorted Data:");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
for(i=0;i<n;i++)
{
printf("\n%d",a[i]);
}
if(n%2==0)
{
median=(a[n/2]+a[(n/2)-1])/2;
}
else
{
median=a[n/2];
}
printf("\nMedian is : %f",median);
getch();
}

View File

@@ -1,26 +0,0 @@
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
float a,b,c,a1,a2,a3,b1,b2,b3,c1,c2,c3,d1,d2,d3,x1,x2,x3;
clrscr();
printf("Enter values of eq1:");
scanf("%f%f%f%f",&a1,&a2,&a3,&d1);
printf("Enter values of eq2:");
scanf("%f%f%f%f",&b1,&b2,&b3,&d2);
printf("Enter values of eq3:");
scanf("%f%f%f%f",&c1,&c2,&c3,&d3);
x1=x2=x3=0.0;
do
{
a=x1;
b=x2;
c=x3;
x1=(1/a1)*(d1-(a2*x2)-(a3*x3));
x2=(1/b2)*(d2-(b1*x1)-(b3*x3));
x3=(1/c3)*(d3-(c1*x1)-(c2*x2));
}while(fabs(x1-a)>0.0001&&fabs(x2-b)>0.0001&&fabs(x3-c)>0.0001);
printf("x1=%f\nx2=%f\nx3=%f",x1,x2,x3);
getch();
}

View File

@@ -1,45 +0,0 @@
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
void main()
{
float x[20],y[20],a,sum,p;
int n,i,j;
clrscr();
printf("Enter the no of entry to insert->");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter the value of x%d->",i);
scanf("%f",&x[i]);
printf("enter the value of y%d->",i);
scanf("%f",&y[i]);
}
printf("\n X \t\t Y \n");
printf("----------------------------\n");
for(i=0;i<n;i++)
{
printf("%f\t",x[i]);
printf("%f\n",y[i]);
}
printf("\nenter the value of x for interpolation:");
scanf("%f",&a)
sum=0;
for(i=0;i<n;i++)
{
p=1.0;
for(j=0;j<n;j++)
{
if(i !=j)
{
p=p*(a-x[j])/(x[i]-x[j]);
}
sum=sum+y[i]*p;
}
printf("ans is->%f",sum);
getch();
}}

View File

@@ -1,34 +0,0 @@
#include<conio.h>
#include<stdio.h>
#include<math.h>
float f(float x)
{
return 1.0+x*x*x;
}
void main()
{
int i,n;
float a,b,h,x,s2,s3,sum,integral;
printf("enter the lower limit of the integration");
sacnf("%f",&a);
printf("enter the upper limit of the integration");
sacnf("%f",&b);
printf("enter the number of intervals");
sacnf("%d",&n);
h=(b-a)/n;
sum=f(a)+f(b);
s2=s3=0.0;
for(i=1;i<n;i+=3)
{
x=a+i*h;
s3=s3+f(x)+f(x+h);
}
for(i=3;i<n;i+=3)
{
x=a+i*h;
s2=s2+f(x);
}
intgral=(h/3.0)*(sum+2*s2+4*s3);
printf("\nvalue of the integral =%9.4f\n",integral);
getch();
}

View File

@@ -1,54 +0,0 @@
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
int main() {
int *ARRAY=NULL,ARRAY_LENGTH,i,TEMPORARY_ELEMENT,isSorted=0;
float MEAN=0,VARIANCE=0,STAND;
printf("Enter no. for Random Numbers :");
scanf("%d",&ARRAY_LENGTH);
ARRAY=(int *)realloc(ARRAY,ARRAY_LENGTH*(sizeof(int))); //We allocate the dedicated memory
for(i=0;i<ARRAY_LENGTH;i++) //We generate the random numbers
ARRAY[i]=rand()%100;
printf("Random Numbers Generated are :\n"); //We display them
for(i=0;i<ARRAY_LENGTH;i++)
printf("%d ",ARRAY[i]);
printf("\nSorted Data: ");//Then we sort it using Bubble Sort..
while(!isSorted){ //While our array's not sorted
isSorted=1; //we suppose that it's sorted
for(i=0;i<ARRAY_LENGTH-1;i++){ //then for each element of the array
if(ARRAY[i]>ARRAY[i+1]){ // if the two elements aren't sorted
isSorted=0; //it means that the array is not sorted
TEMPORARY_ELEMENT=ARRAY[i]; //and we switch these elements using TEMPORARY_ELEMENT
ARRAY[i]=ARRAY[i+1];
ARRAY[i+1]=TEMPORARY_ELEMENT;
}
}
}
for(i=0;i<ARRAY_LENGTH;i++) {
printf("%d ",ARRAY[i]);
MEAN=MEAN+ARRAY[i];
}
MEAN=MEAN/(float)ARRAY_LENGTH;
for(i=0;i<ARRAY_LENGTH;i++)
VARIANCE=VARIANCE+(pow((ARRAY[i]-MEAN),2));
VARIANCE=VARIANCE/(float)ARRAY_LENGTH;
STAND=sqrt(VARIANCE);
printf("\n\n- Mean is: %f\n",MEAN);
printf("- Variance is: %f\n",VARIANCE);
printf("- Standard Deviation is: %f\n",STAND);
}

View File

@@ -0,0 +1,21 @@
# 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} *.c )
# 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 ".c" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
if(OpenMP_C_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_C)
endif()
if(MATH_LIBRARY)
target_link_libraries(${testname} ${MATH_LIBRARY})
endif()
install(TARGETS ${testname} DESTINATION "bin/conversions")
endforeach( testsourcefile ${APP_SOURCES} )

View File

@@ -1,25 +1,24 @@
/**
* Modified 07/12/2017, Kyler Smith
*
*
*/
#include <stdio.h>
int main() {
int main()
{
int remainder, number = 0, decimal_number = 0, temp = 1;
printf("\n Enter any binary number= ");
scanf("%d", &number);
int remainder, number = 0, decimal_number = 0, temp = 1;
printf("Enter any binary number= ");
scanf("%d", &number);
// Iterate over the number until the end.
while (number > 0)
{
remainder = number % 10;
number = number / 10;
decimal_number += remainder * temp;
temp = temp * 2; // used as power of 2
}
// Iterate over the number until the end.
while(number > 0) {
remainder = number % 10;
number = number / 10;
decimal_number += remainder * temp;
temp = temp*2; //used as power of 2
}
printf("%d\n", decimal_number);
printf("%d\n", decimal_number);
}

View File

@@ -1,12 +1,12 @@
/*
* C Program to Convert Binary to Hexadecimal
* C Program to Convert Binary to Hexadecimal
*/
#include <stdio.h>
int main()
{
long int binary, hexa = 0, i = 1, remainder;
printf("Enter the binary number: ");
scanf("%ld", &binary);
while (binary != 0)
@@ -16,6 +16,6 @@ int main()
i = i * 2;
binary = binary / 10;
}
printf("THe Equivalent hexadecimal value: %lX", hexa);
printf("The equivalent hexadecimal value: %lX", hexa);
return 0;
}

View File

@@ -1,14 +1,14 @@
// Binary number to octal number conversion
#include<stdio.h>
#include <stdio.h>
//Function that returns the last three digits
// Function that returns the last three digits
int three_digits(int n)
{
int r, d = 0, p=1;
int r, d = 0, p = 1;
for(int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
r = n%10;
r = n % 10;
d += r * p;
p *= 10;
n /= 10;
@@ -18,24 +18,26 @@ int three_digits(int n)
int main(void)
{
int binary_num, d=0, base=1, remainder, td, res=0, ord=1;
int binary_num, d = 0, base = 1, remainder, td, res = 0, ord = 1;
printf("Enter the binary no: ");
scanf("%d", &binary_num);
while(binary_num > 0)
while (binary_num > 0)
{
if(binary_num > 111) //Checking if binary number is greater than three digits
if (binary_num >
111) // Checking if binary number is greater than three digits
td = three_digits(binary_num);
else td = binary_num;
else
td = binary_num;
binary_num /= 1000;
d = 0, base =1;
d = 0, base = 1;
// Converting the last three digits to decimal
while(td > 0)
while (td > 0)
{
remainder = td % 10;
td /= 10;
@@ -43,7 +45,7 @@ int main(void)
base *= 2;
}
res += d * ord; // Calculating the octal value
res += d * ord; // Calculating the octal value
ord *= 10;
}

View File

@@ -0,0 +1,89 @@
/**
* \file
* \brief Recoding the original atoi function in stdlib.h
* \author [Mohammed YMIK](https://github.com/medymik)W
* The function convert a string passed to an integer
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* the function take a string and return an integer
* \param[out] str pointer to a char address
*/
int c_atoi(const char *str)
{
int i;
int sign;
long value;
long prev;
i = 0;
sign = 1;
value = 0;
/* skipping the spaces */
while (((str[i] <= 13 && str[i] >= 9) || str[i] == 32) && str[i] != '\0')
i++;
/* store the sign if it is negative sign */
if (str[i] == '-')
{
sign = -1;
i++;
}
else if (str[i] == '+')
{
sign = 1;
i++;
}
/* converting char by char to a numeric value */
while (str[i] >= 48 && str[i] <= 57 && str[i] != '\0')
{
prev = value;
value = value * 10 + sign * (str[i] - '0');
/* managing the overflow */
if (sign == 1 && prev > value)
return (-1);
else if (sign == -1 && prev < value)
return (0);
i++;
}
return (value);
}
/**
* test the function implementation
*/
void test_c_atoi()
{
printf("<<<< TEST FUNCTION >>>>\n");
assert(c_atoi("123") == atoi("123"));
assert(c_atoi("-123") == atoi("-123"));
assert(c_atoi("") == atoi(""));
assert(c_atoi("-h23") == atoi("-h23"));
assert(c_atoi(" 23") == atoi(" 23"));
assert(c_atoi("999999999") == atoi("999999999"));
printf("<<<< TEST DONE >>>>\n");
}
/**
* the main function take one argument of type char*
* example : ./program 123
*/
int main(int argc, char **argv)
{
test_c_atoi();
if (argc == 2)
{
printf("Your number + 5 is %d\n", c_atoi(argv[1]) + 5);
return (0);
}
printf("wrong number of parmeters\n");
return (1);
}

View File

@@ -0,0 +1,169 @@
/**
* @file
* @author [jucollet972](https://github.com/jucollet972)
* @brief [Decimal to any-base](http://codeofthedamned.com/index.php/number-base-conversion) is a C function wich convert positive decimal
* integer to any positive ascii base with the base's alphabet given in input and return it in a dynamically allocated string(recursive way)
*/
#include <stdio.h> /// for IO operations
#include <string.h> /// for strchr and strlen
#include <stdint.h> /// for CPU arch's optimized int types
#include <stdbool.h> /// for boolean types
#include <assert.h> /// for assert
#include <stdlib.h> /// for malloc and free
/**
* @brief Checking if alphabet is valid
* @param base alphabet inputed by user
* @return int64_t as success or not
*/
bool isbad_alphabet(const char* alphabet) {
uint64_t len = strlen(alphabet);
/* Checking th lenght */
if (len < 2) {
return true;
}
/* Browse the alphabet */
for (int i = 0; i < len ; i++) {
/* Searching for duplicates */
if (strchr(alphabet + i + 1, alphabet[i]))
return true;
}
return false;
}
/**
* @brief Calculate the final length of the converted number
* @param nb to convert
* @param base calculated from alphabet
* @return Converted nb string length
*/
uint64_t converted_len(uint64_t nb, short base) {
/* Counting the number of characters translated to the base*/
if (nb > base - 1) {
return (converted_len(nb/base, base) + 1);
}
return 1;
}
/**
* @brief Convert positive decimal integer into anybase recursively
* @param nb to convert
* @param alphabet inputed by user used for base convertion
* @param base calculated from alphabet
* @param converted string filled with the convertion's result
* @return void
*/
void convertion(uint64_t nb, const char* alphabet, short base, char* converted) {
/* Recursive convertion */
*(converted) = *(alphabet + nb%base);
if (nb > base - 1) {
convertion(nb/base, alphabet, base, --converted);
}
}
/**
* @brief decimal_to_anybase ensure the validity of the parameters and convert any unsigned integers into any ascii positive base
* @param nb to convert
* @param base's alphabet
* @returns nb converted on success
* @returns NULL on error
*/
char* decimal_to_anybase(uint64_t nb, const char* alphabet) {
char* converted;
/* Verify that alphabet is valid */
if (isbad_alphabet(alphabet)) {
return NULL;
}
/* Convertion */
uint64_t base = strlen(alphabet);
uint64_t final_len = converted_len(nb, base);
converted = malloc(sizeof(char) * (final_len + 1));
converted[final_len] = 0;
convertion(nb, alphabet, base, converted + final_len - 1);
return converted;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void test()
{
char* ret = NULL;
char* reference = NULL;
/* min dec*/
reference = "0";
ret = decimal_to_anybase(0, "0123456789");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
/* max dec*/
reference = "18446744073709551615";
ret = decimal_to_anybase(18446744073709551615, "0123456789");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
/* negative dec*/
reference = "18446744073709551615";
ret = decimal_to_anybase(-1, "0123456789");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
/* bin */
reference = "101010";
ret = decimal_to_anybase(42, "01");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
/* octal */
reference = "52";
ret = decimal_to_anybase(42, "01234567");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
/* hexa */
reference = "2A";
ret = decimal_to_anybase(42, "0123456789ABCDEF");
for (int i = 0; i < strlen(reference) && i < strlen(ret); i++) {
assert(ret[i] == reference[i]);
}
if (ret != NULL) {
free(ret);
}
printf("[+] All tests have successfully passed!\n");
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
test(); // run self-test implementations
return 0;
}

View File

@@ -5,7 +5,6 @@
int main()
{
// input of the user
int inputNumber;
@@ -17,13 +16,13 @@ int main()
// for the loops
int j;
int i=0;
int i = 0;
printf("\t\tConverter decimal --> binary\n\n");
// reads a decimal number from the user.
printf("\nenter a positive integer number: ");
scanf("%d",&inputNumber);
scanf("%d", &inputNumber);
// make sure the input number is a positive integer.
if (inputNumber < 0)
@@ -33,9 +32,8 @@ int main()
}
// actual processing
while(inputNumber>0)
while (inputNumber > 0)
{
// computes the remainder by modulo 2
re = inputNumber % 2;
@@ -44,15 +42,14 @@ int main()
bits[i] = re;
i++;
}
printf("\n the number in binary is: ");
// iterates backwards over all bits
for(j=i-1; j>=0; j--)
for (j = i - 1; j >= 0; j--)
{
printf("%d",bits[j]);
printf("%d", bits[j]);
}
// for the case the input number is 0
@@ -63,4 +60,3 @@ int main()
return 0;
}

View File

@@ -0,0 +1,38 @@
/**
* @file
* @brief Convert decimal to binary using recursion algorithm
*/
#include <assert.h>
/**
* Decimal to binary using recursion algorithm.
* For example, if number = 5, the function returns the decimal integer 101.
* @param number positive integer number to convert
* @returns integer with digits representing binary value representation of
* number.
*/
int decimal_to_binary(unsigned int number)
{
return number == 0 ? 0 : number % 2 + 10 * decimal_to_binary(number / 2);
}
/** Test function */
void test()
{
const int sets[][2] = {
{0, 0}, {1, 1}, {2, 10}, {3, 11}, {4, 100}, {6, 110}, {7, 111},
/* add more data sets to test */
};
for (int i = 0, size = sizeof(sets) / sizeof(sets[0]); i < size; ++i)
{
assert(decimal_to_binary(sets[i][0]) == sets[i][1]);
}
}
/** Driver Code */
int main()
{
test();
return 0;
}

View File

@@ -2,45 +2,47 @@
#include <stdio.h>
void decimal2Hexadecimal(long num);
int main(){
long decimalnum;
printf("Enter decimal number: ");
scanf("%ld", &decimalnum);
decimal2Hexadecimal(decimalnum);
int main()
{
long decimalnum;
return 0;
printf("Enter decimal number: ");
scanf("%ld", &decimalnum);
decimal2Hexadecimal(decimalnum);
return 0;
}
/********function for convert decimal number to hexadecimal number****************/
void decimal2Hexadecimal(long num){
long decimalnum=num;
long quotient, remainder;
int i, j = 0;
char hexadecimalnum[100];
/********function for convert decimal number to hexadecimal
* number****************/
void decimal2Hexadecimal(long num)
{
long decimalnum = num;
long quotient, remainder;
int i, j = 0;
char hexadecimalnum[100];
quotient = decimalnum;
while (quotient != 0){
while (quotient != 0)
{
remainder = quotient % 16;
if (remainder < 10)
if (remainder < 10)
hexadecimalnum[j++] = 48 + remainder;
else
hexadecimalnum[j++] = 55 + remainder;
else
hexadecimalnum[j++] = 55 + remainder;
quotient = quotient / 16;}
quotient = quotient / 16;
}
// print the hexadecimal number
for (i = j; i >= 0; i--){
printf("%c", hexadecimalnum[i]);}
for (i = j; i >= 0; i--)
{
printf("%c", hexadecimalnum[i]);
}
printf("\n");
printf("\n");
}

View File

@@ -1,35 +1,35 @@
/*****Decimal to octal conversion*******************/
#include <stdio.h>
void decimal2Octal(long decimalnum);
int main(){
int main()
{
long decimalnum;
printf("Enter the decimal number: ");
scanf("%ld", &decimalnum);
scanf("%ld", &decimalnum);
decimal2Octal(decimalnum);
return 0;
return 0;
}
/********function for convert decimal numbers to octal numbers************/
void decimal2Octal(long decimalnum){
long remainder, quotient;
/********function for convert decimal numbers to octal numbers************/
void decimal2Octal(long decimalnum)
{
long remainder, quotient;
int octalNumber[100], i = 1, j;
quotient = decimalnum;
while (quotient != 0){
octalNumber[i++] = quotient % 8;
while (quotient != 0)
{
octalNumber[i++] = quotient % 8;
quotient = quotient / 8;
}
}
for (j = i - 1; j > 0; j--)
for (j = i - 1; j > 0; j--) printf("%d", octalNumber[j]);
printf("%d", octalNumber[j]);
printf("\n");
printf("\n");
}

View File

@@ -0,0 +1,29 @@
// Program to convert decimal number to octal (Using Reccursion)
// This program only works for integer decimals
// Created by Aromal Anil
#include <stdio.h>
int decimal_to_octal(int decimal)
{
if ((decimal < 8) && (decimal > 0))
{
return decimal;
}
else if (decimal == 0)
{
return 0;
}
else
{
return ((decimal_to_octal(decimal / 8) * 10) + decimal % 8);
}
}
int main()
{
int octalNumber, decimalNumber;
printf("\nEnter your decimal number : ");
scanf("%d", &decimalNumber);
octalNumber = decimal_to_octal(decimalNumber);
printf("\nThe octal of %d is : %d", decimalNumber, octalNumber);
return 0;
}

View File

@@ -0,0 +1,133 @@
/* C program to convert Hexadecimal to Octal number system */
#include <stdio.h>
int main()
{
#define MAX_STR_LEN 17
char hex[MAX_STR_LEN];
long long octal, bin, place;
int i = 0, rem, val;
/* Input hexadecimal number from user */
printf("Enter any hexadecimal number: ");
fgets(hex, MAX_STR_LEN, stdin);
octal = 0ll;
bin = 0ll;
place = 0ll;
/* Hexadecimal to binary conversion */
for (i = 0; hex[i] != '\0'; i++)
{
bin = bin * place;
switch (hex[i])
{
case '0':
bin += 0;
break;
case '1':
bin += 1;
break;
case '2':
bin += 10;
break;
case '3':
bin += 11;
break;
case '4':
bin += 100;
break;
case '5':
bin += 101;
break;
case '6':
bin += 110;
break;
case '7':
bin += 111;
break;
case '8':
bin += 1000;
break;
case '9':
bin += 1001;
break;
case 'a':
case 'A':
bin += 1010;
break;
case 'b':
case 'B':
bin += 1011;
break;
case 'c':
case 'C':
bin += 1100;
break;
case 'd':
case 'D':
bin += 1101;
break;
case 'e':
case 'E':
bin += 1110;
break;
case 'f':
case 'F':
bin += 1111;
break;
default:
printf("Invalid hexadecimal input.");
}
place = 10000;
}
place = 1;
/* Binary to octal conversion */
while (bin > 0)
{
rem = bin % 1000;
switch (rem)
{
case 0:
val = 0;
break;
case 1:
val = 1;
break;
case 10:
val = 2;
break;
case 11:
val = 3;
break;
case 100:
val = 4;
break;
case 101:
val = 5;
break;
case 110:
val = 6;
break;
case 111:
val = 7;
break;
}
octal = (val * place) + octal;
bin /= 1000;
place *= 10;
}
printf("Hexadecimal number = %s\n", hex);
printf("Octal number = %lld", octal);
return 0;
}

View File

@@ -0,0 +1,119 @@
/**
* @file
* @brief Convert hexadecimal number to octal number (with decimal intermediary)
* @details
* The input is valid from 0 to 0xFFFF_FFFF_FFFF_FFFF.
*
* At first, this program converts a hex string to an unsigned long long
* decimal, and then to an octal string.
*
* When there is an invalid character in input string, this program stops
* parsing and converts the string until that character.
*
* @see hexadecimal_to_octal.c
*/
#include <stdio.h> /// for printf() and fgets()
#include <string.h> /// for memset()
/**
* @brief Convert a hexadecimal number to octal number.
* @param hex Hexadecimal number to convert.
* @returns A pointer to the converted octal string.
*/
const char *hex_to_oct(const char *hex)
{
#define MAX_OCT_STR_LEN 23 /* 17_7777_7777_7777_7777_7777 */
static char octal[MAX_OCT_STR_LEN];
memset(octal, '\0', MAX_OCT_STR_LEN); // Initialize as NULL string
unsigned long long decimal = 0;
int i = 0;
int len;
if (hex == NULL)
{
// Return an empty string
return octal;
}
/* Hexadecimal to decimal conversion */
while (*hex != '\n' && *hex != '\0')
{
char ch = *hex;
if (ch >= '0' && ch <= '9')
{
ch -= '0';
}
else if (ch >= 'a' && ch <= 'f')
{
ch = ch - 'a' + 10;
}
else if (ch >= 'A' && ch <= 'F')
{
ch = ch - 'A' + 10;
}
else
{
printf("Invalid hexadecimal input: %c\n", ch);
break;
}
decimal *= 16;
decimal += ch;
hex++;
}
/* Decimal to octal conversion */
if (decimal == 0)
{
octal[0] = '0';
len = 1;
}
else
{
i = 0;
while (decimal > 0)
{
octal[i] = '0' + decimal % 8;
i++;
decimal /= 8;
}
len = i;
}
octal[len] = '\0';
/* Reverse the octal string */
for (i = 0; i < len / 2; i++)
{
char tmp = octal[i];
octal[i] = octal[len - i - 1];
octal[len - i - 1] = tmp;
}
return octal;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
#define MAX_HEX_STR_LEN 17 /* FFFF_FFFF_FFFF_FFFF */
char hex[MAX_HEX_STR_LEN];
/* Input hexadecimal number from user */
printf("Enter any hexadecimal number: ");
fgets(hex, MAX_HEX_STR_LEN, stdin);
const char *octal = hex_to_oct(hex);
printf("Hexadecimal number = %s\n", hex);
printf("Octal number = %s\n", octal);
return 0;
}

View File

@@ -0,0 +1,227 @@
/**
* @file
* @brief [Infix to
* Postfix](https://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm)
* Expression Conversion
* @details Convert Infixed expressions to Postfix expression.
* @author [Harsh Karande](https://github.com/harshcut)
*/
// include header files
#include <stdio.h> /// for printf() and scanf()
/**
* @brief a globally declared structure with an array and an variable that
* points to the topmost index of the array
*/
struct Stack
{
char arr[10]; ///> static array of integers
int tos; ///> stores index on topmost element in stack
};
// function headers
void push(struct Stack *p, char ch); // pust element in stack
char pop(struct Stack *p); // pop topmost element from the stack
int isOprnd(char ch); // check if element is operand or not
int isEmpty(struct Stack s); // check if stack is empty
int getPrecedence (char op1, char op2); // check operator precedence
void convert(char infix[],
char postfix[]); // convert infix to postfix expression
/**
* @brief main function
* @returns 0 on exit
*/
int main()
{
char infix[20], postfix[20]; // initialize empty infix and postfix array
printf("Enter infix expression: "); // example : A+B-C*D/E$F
scanf("%s", infix); // get values for infix array
convert(infix, postfix);
printf("Postfix expression is %s", postfix); // output : AB+CD*EF$/-
return 0;
}
/**
* @brief push function
* @param *p : used as a pointer variable of stack
* @param x : char to be pushed in stack
* @returns void
*/
void push(struct Stack *p, char x)
{
if (p->tos == 9) // check if stack has reached its max limit
{
printf("Stack Overflow!");
return;
}
p->tos += 1; // increment tos
p->arr[p->tos] = x; // assign char x to index of stack pointed by tos
}
/**
* @brief pop function
* @param *p : used as a pointer variable of stack
* @returns x or \0 on exit
*/
char pop(struct Stack *p)
{
char x;
if (p->tos == -1)
{
printf("Stack Underflow!");
return '\0';
}
x = p->arr[p->tos]; // assign the value of stack at index tos to x
p->tos -= 1; // decrement tos
return x;
}
/**
* @brief isOprnd function
* @param ch : this is the element from the infix array
* @returns 1 or 0 on exit
*/
int isOprnd(char ch)
{
if ((ch >= 65 && ch <= 90) ||
(ch >= 97 && ch <= 122) || // check if ch is an operator or
(ch >= 48 && ch <= 57)) // operand using ASCII values
{
return 1; // return for true result
}
else
{
return 0; // return for false result
}
}
/**
* @brief isEmpty function
* @param s : it is the object reference of stack
* @returns 1 or 0 on exit
*/
int isEmpty(struct Stack s)
{
if (s.tos == -1) // check if stack is empty
{
return 1; // return for true result
}
else
{
return 0; // return for false result
}
}
/**
* @brief convert function
* @param infix[] : infix array provided by user
* @param postfix[] : empty array to be given to convert()
* @returns postfixed expresion or \0 on exit
*/
void convert(char infix[], char postfix[])
{
struct Stack s; // initialze object reference of stack
s.tos = -1; // initalize the tos
int i, j = 0, pr;
char ch, temp;
for (i = 0; infix[i] != '\0'; i++)
{
ch = infix[i];
if (isOprnd(ch) == 1) // check if char is operand or operator
{
postfix[j] = ch; // assign ch to postfix array with index j
j++; // incement j
}
else
{
if (ch == '(')
{
push(&s, ch);
}
else
{
if (ch == ')')
{
while ((temp = pop(&s)) != '(')
{
postfix[j] = temp;
j++;
}
}
else
{
while (isEmpty(s) == 0) // check if stack is empty
{
pr = getPrecedence (ch,
s.arr[s.tos]); // check operator precedence
if (pr == 1)
{
break; // if ch has a greater precedence than
// s.arr[s.top]
}
postfix[j] = pop(&s);
j++;
}
push(&s, ch); // push ch to stack
}
}
}
}
while (isEmpty(s) == 0) // check if stack is empty
{
postfix[j] = pop(&s);
j++;
}
postfix[j] = '\0';
}
/**
* @brief getPrecedence function returns the precedence after comparing two operators passed as parameter.
* @param op1 : first operator
* @param op2 : second operator
* @returns 1 or 0 on exit
*/
int getPrecedence (char op1, char op2)
{
if (op2 == '$')
{
return 0;
}
else if (op1 == '$')
{
return 1;
}
else if (op2 == '*' || op2 == '/' || op2 == '%')
{
return 0;
}
else if (op1 == '*' || op1 == '/' || op1 == '%')
{
return 1;
}
else if (op2 == '+' || op2 == '-')
{
return 0;
}
else
{
return 1;
}
}

View File

@@ -0,0 +1,164 @@
/**
* @file
* @brief [Infix to Postfix converter](https://www.includehelp.com/c/infix-to-postfix-conversion-using-stack-with-c-program.aspx) implementation
* @details
* The input infix expression is of type string upto 24 characters.
* Supported operations- '+', '-', '/', '*', '%'
* @author [Kumar Yash](https://github.com/kumaryash18)
* @see infix_to_postfix.c
*/
#include <stdio.h> /// for IO operations
#include <string.h> /// for strlen(), strcmp()
#include <ctype.h> /// for isalnum()
#include <stdlib.h> /// for exit()
#include <stdint.h> /// for uint16_t, int16_t
#include <assert.h> /// for assert
/**
* @brief array implementation of stack using structure
*/
struct Stack {
char stack[10]; ///< array stack
int top; ///< stores index of the top element
};
struct Stack st; ///< global declaration of stack st
/**
* @brief Function to push on the stack
* @param opd character to be pushed in the stack
* @returns void
*/
void push(char opd) {
if(st.top == 9) { // overflow condition
printf("Stack overflow...");
exit(1);
}
st.top++;
st.stack[st.top] = opd;
}
/**
* @brief Function to pop from the stack
* @returns popped character
*/
char pop() {
char item; ///< to store the popped value to be returned
if(st.top == -1) { // underflow condition
printf("Stack underflow...");
exit(1);
}
item = st.stack[st.top];
st.top--;
return item;
}
/**
* @brief Function to check whether the stack is empty or not
* @returns 1 if the stack IS empty
* @returns 0 if the stack is NOT empty
*/
uint16_t isEmpty() {
if(st.top == -1) {
return 1;
}
return 0;
}
/**
* @brief Function to get top of the stack
* @returns top of stack
*/
char Top() {
return st.stack[st.top];
}
/**
* @brief Function to check priority of operators
* @param opr operator whose priority is to be checked
* @returns 0 if operator is '+' or '-'
* @returns 1 if operator is '/' or '*' or '%'
* @returns -1 otherwise
*/
int16_t priority(char opr) {
if(opr == '+' || opr == '-') {
return 0;
}
else if(opr == '/' || opr == '*' || opr == '%') {
return 1;
}
else {
return -1;
}
}
/**
* @brief Function to convert infix expression to postfix expression
* @param inf the input infix expression
* @returns output postfix expression
*/
char *convert(char inf[]) {
static char post[25]; ///< to store the postfix expression
int i; ///< loop iterator
int j = 0; ///< keeps track of end of postfix string
for(i = 0; i < strlen(inf); i++) {
if(isalnum(inf[i])) { // if scanned element is an alphabet or number
post[j] = inf[i]; // append in postfix expression
j++;
}
else if(inf[i] == '(') { // if scanned element is opening parentheses
push(inf[i]); // push on stack.
}
else if(inf[i] == ')') { // if scanned element is closing parentheses,
while(Top() != '(') { // pop elements from stack and append in postfix expression
post[j] = pop(); // until opening parentheses becomes top.
j++;
}
pop(); // pop opening parentheses
}
else { // if scanned element is an operator
while( (!isEmpty()) && (priority(inf[i]) <= priority(Top())) ) { // pop and append until stack becomes
post[j] = pop(); // empty or priority of top operator
j++; // becomes smaller than scanned operator
} // '(' has priority -1
push(inf[i]); // push the scanned operator
}
}
while(!isEmpty()) { // pop and append residual operators from stack
post[j] = pop();
j++;
}
post[j] = '\0'; // end postfix string with null character
return post;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
/* check sample test case
input- "(A/(B-C)*D+E)"
expected output- "ABC-/D*E+"
*/
assert(strcmp(convert("(A/(B-C)*D+E)"), "ABC-/D*E+") == 0); /// this ensures that the algorithm works as expected
/* input- "7-(2*3+5)*(8-4/2)"
expected output- "723*5+842/-*-"
*/
assert(strcmp(convert("7-(2*3+5)*(8-4/2)"), "723*5+842/-*-") == 0); /// this ensures that the algorithm works as expected
printf("All tests have successfully passed!\n");
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
st.top = -1; /// initialize
test(); /// run self-test implementations
char inf[25]; ///< to store input infix expression
printf("Enter infix: ");
scanf("%s", inf);
printf("Postfix: %s", convert(inf));
return 0;
}

View File

@@ -0,0 +1,83 @@
/**
* @file
* @brief Convert a positive integer to string (non-standard function)
* representation.
*/
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/**
* Converts an integer value to a null-terminated string using the specified
* base and stores the result in the array given by str parameter.
* @param value Value to be converted to a string.
* @param dest pointer to array in memory to store the resulting null-terminated
* string.
* @param base Numerical base used to represent the value as a string, between 2
* and 16, where 10 means decimal base, 16 hexadecimal, 8 octal, and 2 binary.
* @returns A pointer to the resulting null-terminated string, same as parameter
* str.
* @note The destination array must be pre-allocated by the calling function.
*/
char *int_to_string(uint16_t value, char *dest, int base)
{
const char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
int len = 0;
do
{
dest[len++] = hex_table[value % base];
value /= base;
} while (value != 0);
/* reverse characters */
for (int i = 0, limit = len / 2; i < limit; ++i)
{
char t = dest[i];
dest[i] = dest[len - 1 - i];
dest[len - 1 - i] = t;
}
dest[len] = '\0';
return dest;
}
/** Test function
* @returns `void`
*/
static void test()
{
const int MAX_SIZE = 100;
char *str1 = (char *)calloc(sizeof(char), MAX_SIZE);
char *str2 = (char *)calloc(sizeof(char), MAX_SIZE);
for (int i = 1; i <= 100; ++i) /* test 100 random numbers */
{
/* Generate value from 0 to 100 */
int value = rand() % 100;
// assert(strcmp(itoa(value, str1, 2), int_to_string(value, str2, 2)) ==
// 0);
snprintf(str1, MAX_SIZE, "%o", value); //* standard C - to octal */
assert(strcmp(str1, int_to_string(value, str2, 8)) == 0);
snprintf(str1, MAX_SIZE, "%d", value); /* standard C - to decimal */
assert(strcmp(str1, int_to_string(value, str2, 10)) == 0);
snprintf(str1, MAX_SIZE, "%x", value); /* standard C - to hexadecimal */
assert(strcmp(str1, int_to_string(value, str2, 16)) == 0);
}
free(str1);
free(str2);
}
/** Driver Code */
int main()
{
/* Intializes random number generator */
srand(time(NULL));
test();
return 0;
}

View File

@@ -0,0 +1,62 @@
/**
* @brief Octal to binay conversion by scanning user input
* @details
* The octalTobinary function take the octal number as long
* return a long binary nuber after conversion
* @author [Vishnu P](https://github.com/vishnu0pothan)
*/
#include <math.h>
#include <stdio.h>
/**
* @brief Converet octal number to binary
* @param octalnum octal value that need to convert
* @returns A binary number after conversion
*/
long octalToBinary(int octalnum)
{
int decimalnum = 0, i = 0;
long binarynum = 0;
/* This loop converts octal number "octalnum" to the
* decimal number "decimalnum"
*/
while (octalnum != 0)
{
decimalnum = decimalnum + (octalnum % 10) * pow(8, i);
i++;
octalnum = octalnum / 10;
}
// i is re-initialized
i = 1;
/* This loop converts the decimal number "decimalnum" to the binary
* number "binarynum"
*/
while (decimalnum != 0)
{
binarynum = binarynum + (long)(decimalnum % 2) * i;
decimalnum = decimalnum / 2;
i = i * 10;
}
// Returning the binary number that we got from octal number
return binarynum;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
int octalnum;
printf("Enter an octal number: ");
scanf("%d", &octalnum);
// Calling the function octaltoBinary
printf("Equivalent binary number is: %ld", octalToBinary(octalnum));
return 0;
}

View File

@@ -0,0 +1,36 @@
#include <math.h>
#include <stdio.h>
// Converts octal number to decimal
int convertValue(int num, int i) { return num * pow(8, i); }
long long toDecimal(int octal_value)
{
int decimal_value = 0, i = 0;
while (octal_value)
{
// Extracts right-most digit and then multiplies by 8^i
decimal_value += convertValue(octal_value % 10, i++);
// Shift right in base 10
octal_value /= 10;
}
return decimal_value;
}
int main()
{
printf("Enter octal value: ");
int octal_value;
scanf("%d", &octal_value);
long long result = toDecimal(octal_value);
printf("%d in decimal is %lld\n", octal_value, result);
return 0;
}

View File

@@ -0,0 +1,79 @@
/**
* @file
* @brief Octal to hexadecimal conversion by scanning user input
* @details
* The octalToHexadecimal function take the octal number as long
* return a string hexadecimal value after conversion
* @author [Rachit Bhalla](https://github.com/rachitbhalla)
*/
#include <assert.h> // for assert
#include <math.h> // for pow function
#include <stdio.h> // for scanf and printf functions
#include <stdlib.h> // for malloc and free functions
#include <string.h> // for strcmp function
/**
* @brief Convert octal number to decimal number
* @param octalValue is the octal number that needs to be converted
* @returns a decimal number after conversion
*/
long octalToDecimal(long octalValue){
long decimalValue = 0;
int i = 0;
while (octalValue) {
// Extracts right-most digit, multiplies it with 8^i, and increment i by 1
decimalValue += (long)(octalValue % 10) * pow(8, i++);
// Shift right in base 10
octalValue /= 10;
}
return decimalValue;
}
/**
* @brief Convert octal number to hexadecimal number
* dynamically allocated memory needs to be freed by the calling the function free
* @param octalValue is the octal number that needs to be converted
* @returns a hexadecimal value as a string after conversion
*/
char *octalToHexadecimal(long octalValue){
char *hexadecimalValue = malloc(256 * sizeof(char));
sprintf(hexadecimalValue, "%lX", octalToDecimal(octalValue));
return hexadecimalValue;
}
/**
* @brief Test function
* @returns void
*/
static void test() {
/* test that hexadecimal value of octal number 213 is 8B */
assert(strcmp(octalToHexadecimal(213), "8B") == 0);
/* test that hexadecimal value of octal number 174 is 7C */
assert(strcmp(octalToHexadecimal(174), "7C") == 0);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
// execute the tests
test();
// get the value of octal number as input
int octalValue;
printf("Enter an octal number: ");
scanf("%d", &octalValue);
// call the function octalToHexadecimal and print the hexadecimal value
char *hexadecimalValue = octalToHexadecimal(octalValue);
printf("Equivalent hexadecimal number is: %s", hexadecimalValue);
// free the memory allocated dynamically in function octalToHexadecimal
free(hexadecimalValue);
// return 0 and exit
return 0;
}

View File

@@ -1,38 +0,0 @@
/*
* convert from any base to decimal
*/
#include <stdio.h>
#include <ctype.h>
int main(void) {
int base, i, j;
char number[100];
unsigned long decimal = 0;
printf("Enter the base: ");
scanf("%d", &base);
printf("Enter the number: ");
scanf("%s", &number[0]);
for (i = 0; number[i] != '\0'; i++) {
if (isdigit(number[i]))
number[i] -= '0';
else if (isupper(number[i]))
number[i] -= 'A' - 10;
else if (islower(number[i]))
number[i] -= 'a' - 10;
else
number[i] = base + 1;
if (number[i] > base)
printf("invalid number\n");
}
for (j = 0; j < i; j++) {
decimal *= base;
decimal += number[j];
}
printf("%lu\n", decimal);
}

44
conversions/to_decimal.c Normal file
View File

@@ -0,0 +1,44 @@
/*
* convert from any base to decimal
*/
#include <ctype.h>
#include <stdio.h>
int main(void)
{
int base, i, j;
char number[100];
unsigned long decimal = 0;
printf("Enter the base: ");
scanf("%d", &base);
printf("Enter the number: ");
scanf("%s", &number[0]);
for (i = 0; number[i] != '\0'; i++)
{
if (isdigit(number[i]))
number[i] -= '0';
else if (isupper(number[i]))
number[i] -= 'A' - 10;
else if (islower(number[i]))
number[i] -= 'a' - 10;
else
number[i] = base + 1;
if (number[i] >= base)
{
printf("invalid number\n");
return 0;
}
}
for (j = 0; j < i; j++)
{
decimal *= base;
decimal += number[j];
}
printf("%lu\n", decimal);
}

View File

@@ -1,255 +0,0 @@
/*
* CArray.c
*
* Author: Leonardo Vencovsky
* Created on 19/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Array Implementations in C
*
* Compiled in Visual Studio 2017
*
*/
/*
Return Codes
-1 - Array Erased
0 - Success
1 - Invalid Position
2 - Position already initialized (use update function)
3 - Position not initialized (use insert function)
4 - Position already empty
5 - Array is full
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "CArray.h"
void swap(CArray *array, int position1, int position2);
CArray * getCArray(int size)
{
CArray *array = (CArray *) malloc(sizeof(CArray));
array->array = (int *) malloc(sizeof(int) * size);
array->size = size;
int i;
for (i = 0; i < size; i++) {
array->array[i] = 0;
}
return array;
}
int insertValueCArray(CArray *array, int position, int value)
{
if (position >= 0 && position < array->size) {
if (array->array[position] == 0) {
array->array[position] = value;
return SUCCESS;
}
else return POSITION_INIT;
}
return INVALID_POSITION;
}
int removeValueCArray(CArray *array, int position)
{
if (position >= 0 && position < array->size) {
if (array->array[position] != 0) {
array->array[position] = 0;
}
else return POSITION_EMPTY;
}
return INVALID_POSITION;
}
int pushValueCArray(CArray *array, int value)
{
int i;
int ok = 0;
for (i = 0; i < array->size; i++) {
if (array->array[i] == 0) {
array->array[i] = value;
ok = 1;
break;
}
}
if (ok == 1) return SUCCESS;
else return ARRAY_FULL;
}
int updateValueCArray(CArray *array, int position, int value)
{
if (position >= 0 && position < array->size) {
if (array->array[position] != 0) {
}
else return POSITION_NOT_INIT;
}
return INVALID_POSITION;
}
int eraseCArray(CArray *array)
{
int i;
for (i = 0; i < array->size; i++) {
array->array[i] = 0;
}
return 0;
}
int switchValuesCArray(CArray *array, int position1, int position2)
{
if (position1 >= 0 && position1 < array->size
&& position2 >= 0 && position2 < array->size) {
int temp = array->array[position1];
array->array[position1] = array->array[position2];
array->array[position2] = temp;
}
return INVALID_POSITION;
}
int reverseCArray(CArray *array)
{
int i;
for (i = 0; i < array->size / 2; i++) {
swap(array, i, array->size - i - 1);
}
return SUCCESS;
}
int displayCArray(CArray *array)
{
int i;
printf("\nC ARRAY\n");
for (i = 0; i < array->size; i++) {
printf("%d ", array->array[i]);
}
printf("\n");
return 0;
}
int blenderCArray(CArray *array)
{
srand(time(NULL) * array->size);
int i;
int total = array->size * 100;
for (i = 0; i < total; i++) {
swap(array, rand() % array->size, rand() % array->size);
}
return 0;
}
CArray * getCopyCArray(CArray *arr)
{
CArray *array = (CArray *)malloc(sizeof(CArray));
array->array = (int *)malloc(sizeof(int) * arr->size);
array->size = arr->size;
int i;
for (i = 0; i < arr->size; i++) {
array->array[i] = arr->array[i];
}
return array;
}
void swap(CArray *array, int position1, int position2)
{
int temp = array->array[position1];
array->array[position1] = array->array[position2];
array->array[position2] = temp;
}
int bubbleSortCArray(CArray *array)
{
int i, j;
for (i = 0; i < array->size - 1; i++) {
for (j = 0; j < array->size - i - 1; j++) {
if (array->array[j] > array->array[j + 1]) {
swap(array, j, j + 1);
}
}
}
return 0;
}
int selectionSortCArray(CArray *array)
{
int i, j, min;
for (i = 0; i < array->size - 1; i++) {
min = i;
for (j = i + 1; j < array->size; j++)
if (array->array[j] < array->array[min]) min = j;
swap(array, min, i);
}
return 0;
}
int insertionSortCArray(CArray *array)
{
int i, j, num;
for (i = 1; i < array->size; i++) {
num = array->array[i];
j = i - 1;
while (j >= 0 && array->array[j] > num)
{
array->array[j + 1] = array->array[j];
j--;
}
array->array[j + 1] = num;
}
return 0;
}
int valueOcurranceCArray(CArray *array, int value)
{
int i, total = 0;
for (i = 0; i < array->size; i++) {
if (array->array[i] == value) total++;
}
return total;
}
CArray * valuePositionsCArray(CArray *array, int value)
{
int i, j = 0;
int total = valueOcurranceCArray(array, value);
CArray *resultArray = getCArray(total);
for (i = 0; i < array->size; i++) {
if (array->array[i] == value) {
// Hopefully this won't overflow
resultArray->array[j] = i;
j++;
}
}
return resultArray;
}
int findMinCArray(CArray *array)
{
int i;
int min = array->array[0];
for (i = 1; i < array->size; i++) {
if (array->array[i] < min) {
min = array->array[i];
}
}
return min;
}
int findMaxCArray(CArray *array)
{
int i;
int max = array->array[0];
for (i = 1; i < array->size; i++) {
if (array->array[i] > max) {
max = array->array[i];
}
}
return max;
}

View File

@@ -1,84 +0,0 @@
/*
* CArray.h
*
* Author: Leonardo Vencovsky
* Created on 18/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Header for Array in C
*
* Compiled in Visual Studio 2017
*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define ARRAY_ERASED -1
#define SUCCESS 0
#define INVALID_POSITION 1
#define POSITION_INIT 2
#define POSITION_NOT_INIT 3
#define POSITION_EMPTY 4
#define ARRAY_FULL 5
typedef struct CArray {
int *array;
int size;
} CArray;
// +-------------------------------------+
// | Returns array |
// +-------------------------------------+
CArray * getCArray(int size);
CArray * getCopyCArray(CArray *array);
// +-------------------------------------+
// | Input / Output |
// +-------------------------------------+
int insertValueCArray(CArray *array, int position, int value);
int removeValueCArray(CArray *array, int position);
int pushValueCArray(CArray *array, int value);
int updateValueCArray(CArray *array, int position, int value);
// +-------------------------------------+
// | Erase |
// +-------------------------------------+
int eraseCArray(CArray *array);
// +-------------------------------------+
// | Switching |
// +-------------------------------------+
int switchValuesCArray(CArray *array, int position1, int position2);
int reverseCArray(CArray *array);
// +-------------------------------------+
// | Sorting |
// +-------------------------------------+
int bubbleSortCArray(CArray *array);
int selectionSortCArray(CArray *array);
int insertionSortCArray(CArray *array);
int blenderCArray(CArray *array);
// +-------------------------------------+
// | Searching |
// +-------------------------------------+
int valueOcurranceCArray(CArray *array, int value);
CArray * valuePositionsCArray(CArray *array, int value);
int findMaxCArray(CArray *array);
int findMinCArray(CArray *array);
// +-------------------------------------+
// | Display |
// +-------------------------------------+
int displayCArray(CArray *array);
#ifdef __cplusplus
}
#endif

View File

@@ -1,152 +0,0 @@
/*
* CArrayTests.c
*
* Author: Leonardo Vencovsky
* Created on 19/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Test Cases for Array Implementations in C
*
* Compiled in Visual Studio 2017
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "CArray.h"
int CArrayTests()
{
printf("\n");
printf(" +-------------------------------------+\n");
printf(" | |\n");
printf(" | C Array |\n");
printf(" | |\n");
printf(" +-------------------------------------+\n");
printf("\n");
CArray *array = getCArray(10);
int i;
for (i = 0; i < array->size; i++) {
insertValueCArray(array, i, i+1);
}
displayCArray(array);
printf("\nCode: %d\n", pushValueCArray(array, 11)); // 5
for (i = 0; i < array->size; i++) {
removeValueCArray(array, i);
}
displayCArray(array);
printf("\nCode: %d", removeValueCArray(array, -1)); // 1
printf("\nCode: %d\n", insertValueCArray(array, -1, 1)); // 1
// Erase
for (i = 0; i < array->size; i++) {
insertValueCArray(array, i, i + 1);
}
eraseCArray(array);
displayCArray(array); // Should give all 0s
// Switching
CArray *arr = getCArray(13);
for (i = 0; i < arr->size; i++) {
insertValueCArray(arr, i, i + 1);
}
displayCArray(arr);
for (i = 0; i < arr->size / 2; i++) {
switchValuesCArray(arr, i, arr->size - i - 1);
}
displayCArray(arr);
// Or simply...
reverseCArray(arr);
displayCArray(arr);
// Sorting
srand(time(NULL));
CArray *barray = getCArray(20);
for (i = 0; i < barray->size; i++) {
insertValueCArray(barray, i, rand());
}
CArray *carray = getCopyCArray(barray);
CArray *darray = getCopyCArray(barray);
printf("\nNot sorted Array:");
displayCArray(barray);
printf("\nBubble Sort:");
clock_t begin1 = clock();
// Timing bubble sort
bubbleSortCArray(barray);
clock_t end1 = clock();
double time_spent1 = (double)(end1 - begin1) / CLOCKS_PER_SEC;
displayCArray(barray);
printf("\nSelection Sort:");
clock_t begin2 = clock();
// Timing selection sort
selectionSortCArray(carray);
clock_t end2 = clock();
double time_spent2 = (double)(end2 - begin2) / CLOCKS_PER_SEC;
displayCArray(carray);
printf("\nInsertion Sort:");
clock_t begin3 = clock();
// Timing insertion sort
insertionSortCArray(darray);
clock_t end3 = clock();
double time_spent3 = (double)(end3 - begin3) / CLOCKS_PER_SEC;
displayCArray(carray);
// Descending order
reverseCArray(barray);
// displayCArray(barray);
// printf("\nBlender:");
// blenderCArray(barray);
// displayCArray(barray);
printf("\nTotal time spent for bubble sort: %lf seconds", time_spent1);
printf("\nTotal time spent for selection sort: %lf seconds", time_spent2);
printf("\nTotal time spent for insertion sort: %lf seconds", time_spent3);
// Searching
CArray *aarray = getCArray(1000);
for (i = 0; i < aarray->size; i++) {
insertValueCArray(aarray, i, rand() % 100);
}
int j = 24;
printf("\nOccurrences of the number %d in the array: %d", j,
valueOcurranceCArray(aarray, j));
printf("\nAnd its positions:\n");
CArray *positions = valuePositionsCArray(aarray, j);
displayCArray(positions);
// This should all give value of j
printf("\nAll %d s", j);
for (i = 0; i < positions->size; i++) {
printf("\nPosition %d has a value of %d",
positions->array[i], aarray->array[positions->array[i]]);
}
printf("\nThe list has a minimum value of %d and a maximum value of %d",
findMinCArray(aarray), findMaxCArray(aarray));
insertionSortCArray(aarray);
// displayCArray(aarray);
free(arr);
free(array);
free(aarray);
free(barray);
free(carray);
free(darray);
printf("\n");
return 0;
}

View File

@@ -2,6 +2,10 @@
Simple array of integers. With I/O functions, Sort Functions and Search Functions.
## Sort Function
The Sort function sorts the elements in the range in a particular order. The different types of sorting methods are Bubble Sort, Selection Sort, Merge Sort and Quick Sort. Bubble Sort repeatedly sorts the adjacent elements if they are in wrong order.
## Structure
```C

View File

@@ -0,0 +1,288 @@
/*
* CArray.c
*
* Author: Leonardo Vencovsky
* Created on 19/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Array Implementations in C
*
* Compiled in Visual Studio 2017
*
*/
/*
Return Codes
-1 - Array Erased
0 - Success
1 - Invalid Position
2 - Position already initialized (use update function)
3 - Position not initialized (use insert function)
4 - Position already empty
5 - Array is full
*/
#include "carray.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(CArray *array, int position1, int position2);
CArray *getCArray(int size)
{
CArray *array = (CArray *)malloc(sizeof(CArray));
array->array = (int *)malloc(sizeof(int) * size);
array->size = size;
int i;
for (i = 0; i < size; i++)
{
array->array[i] = 0;
}
return array;
}
int insertValueCArray(CArray *array, int position, int value)
{
if (position >= 0 && position < array->size)
{
if (array->array[position] == 0)
{
array->array[position] = value;
return SUCCESS;
}
else
return POSITION_INIT;
}
return INVALID_POSITION;
}
int removeValueCArray(CArray *array, int position)
{
if (position >= 0 && position < array->size)
{
if (array->array[position] != 0)
{
array->array[position] = 0;
}
else
return POSITION_EMPTY;
}
return INVALID_POSITION;
}
int pushValueCArray(CArray *array, int value)
{
int i;
int ok = 0;
for (i = 0; i < array->size; i++)
{
if (array->array[i] == 0)
{
array->array[i] = value;
ok = 1;
break;
}
}
if (ok == 1)
return SUCCESS;
else
return ARRAY_FULL;
}
int updateValueCArray(CArray *array, int position, int value)
{
if (position >= 0 && position < array->size)
{
if (array->array[position] != 0)
{
}
else
return POSITION_NOT_INIT;
}
return INVALID_POSITION;
}
int eraseCArray(CArray *array)
{
int i;
for (i = 0; i < array->size; i++)
{
array->array[i] = 0;
}
return 0;
}
int switchValuesCArray(CArray *array, int position1, int position2)
{
if (position1 >= 0 && position1 < array->size && position2 >= 0 &&
position2 < array->size)
{
int temp = array->array[position1];
array->array[position1] = array->array[position2];
array->array[position2] = temp;
}
return INVALID_POSITION;
}
int reverseCArray(CArray *array)
{
int i;
for (i = 0; i < array->size / 2; i++)
{
swap(array, i, array->size - i - 1);
}
return SUCCESS;
}
int displayCArray(CArray *array)
{
int i;
printf("\nC ARRAY\n");
for (i = 0; i < array->size; i++)
{
printf("%d ", array->array[i]);
}
printf("\n");
return 0;
}
int blenderCArray(CArray *array)
{
srand(time(NULL) * array->size);
int i;
int total = array->size * 100;
for (i = 0; i < total; i++)
{
swap(array, rand() % array->size, rand() % array->size);
}
return 0;
}
CArray *getCopyCArray(CArray *arr)
{
CArray *array = (CArray *)malloc(sizeof(CArray));
array->array = (int *)malloc(sizeof(int) * arr->size);
array->size = arr->size;
int i;
for (i = 0; i < arr->size; i++)
{
array->array[i] = arr->array[i];
}
return array;
}
void swap(CArray *array, int position1, int position2)
{
int temp = array->array[position1];
array->array[position1] = array->array[position2];
array->array[position2] = temp;
}
int bubbleSortCArray(CArray *array)
{
int i, j;
for (i = 0; i < array->size - 1; i++)
{
for (j = 0; j < array->size - i - 1; j++)
{
if (array->array[j] > array->array[j + 1])
{
swap(array, j, j + 1);
}
}
}
return 0;
}
int selectionSortCArray(CArray *array)
{
int i, j, min;
for (i = 0; i < array->size - 1; i++)
{
min = i;
for (j = i + 1; j < array->size; j++)
if (array->array[j] < array->array[min])
min = j;
swap(array, min, i);
}
return 0;
}
int insertionSortCArray(CArray *array)
{
int i, j, num;
for (i = 1; i < array->size; i++)
{
num = array->array[i];
j = i - 1;
while (j >= 0 && array->array[j] > num)
{
array->array[j + 1] = array->array[j];
j--;
}
array->array[j + 1] = num;
}
return 0;
}
int valueOcurranceCArray(CArray *array, int value)
{
int i, total = 0;
for (i = 0; i < array->size; i++)
{
if (array->array[i] == value)
total++;
}
return total;
}
CArray *valuePositionsCArray(CArray *array, int value)
{
int i, j = 0;
int total = valueOcurranceCArray(array, value);
CArray *resultArray = getCArray(total);
for (i = 0; i < array->size; i++)
{
if (array->array[i] == value)
{
// Hopefully this won't overflow
resultArray->array[j] = i;
j++;
}
}
return resultArray;
}
int findMinCArray(CArray *array)
{
int i;
int min = array->array[0];
for (i = 1; i < array->size; i++)
{
if (array->array[i] < min)
{
min = array->array[i];
}
}
return min;
}
int findMaxCArray(CArray *array)
{
int i;
int max = array->array[0];
for (i = 1; i < array->size; i++)
{
if (array->array[i] > max)
{
max = array->array[i];
}
}
return max;
}

View File

@@ -0,0 +1,85 @@
/*
* CArray.h
*
* Author: Leonardo Vencovsky
* Created on 18/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Header for Array in C
*
* Compiled in Visual Studio 2017
*
*/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#define ARRAY_ERASED -1
#define SUCCESS 0
#define INVALID_POSITION 1
#define POSITION_INIT 2
#define POSITION_NOT_INIT 3
#define POSITION_EMPTY 4
#define ARRAY_FULL 5
typedef struct CArray
{
int *array;
int size;
} CArray;
// +-------------------------------------+
// | Returns array |
// +-------------------------------------+
CArray *getCArray(int size);
CArray *getCopyCArray(CArray *array);
// +-------------------------------------+
// | Input / Output |
// +-------------------------------------+
int insertValueCArray(CArray *array, int position, int value);
int removeValueCArray(CArray *array, int position);
int pushValueCArray(CArray *array, int value);
int updateValueCArray(CArray *array, int position, int value);
// +-------------------------------------+
// | Erase |
// +-------------------------------------+
int eraseCArray(CArray *array);
// +-------------------------------------+
// | Switching |
// +-------------------------------------+
int switchValuesCArray(CArray *array, int position1, int position2);
int reverseCArray(CArray *array);
// +-------------------------------------+
// | Sorting |
// +-------------------------------------+
int bubbleSortCArray(CArray *array);
int selectionSortCArray(CArray *array);
int insertionSortCArray(CArray *array);
int blenderCArray(CArray *array);
// +-------------------------------------+
// | Searching |
// +-------------------------------------+
int valueOcurranceCArray(CArray *array, int value);
CArray *valuePositionsCArray(CArray *array, int value);
int findMaxCArray(CArray *array);
int findMinCArray(CArray *array);
// +-------------------------------------+
// | Display |
// +-------------------------------------+
int displayCArray(CArray *array);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,160 @@
/*
* CArrayTests.c
*
* Author: Leonardo Vencovsky
* Created on 19/03/2018
*
* Modified by: Leonardo Vencovsky
* Last modified: 19/03/2018
*
* Test Cases for Array Implementations in C
*
* Compiled in Visual Studio 2017
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "carray.h"
int CArrayTests()
{
printf("\n");
printf(" +-------------------------------------+\n");
printf(" | |\n");
printf(" | C Array |\n");
printf(" | |\n");
printf(" +-------------------------------------+\n");
printf("\n");
CArray *array = getCArray(10);
int i;
for (i = 0; i < array->size; i++)
{
insertValueCArray(array, i, i + 1);
}
printf("Entered array is:\n");
displayCArray(array);
printf("\nCode: %d\n", pushValueCArray(array, 11)); // 5
for (i = 0; i < array->size; i++)
{
removeValueCArray(array, i);
}
displayCArray(array);
printf("\nCode: %d", removeValueCArray(array, -1)); // 1
printf("\nCode: %d\n", insertValueCArray(array, -1, 1)); // 1
// Erase
for (i = 0; i < array->size; i++)
{
insertValueCArray(array, i, i + 1);
}
eraseCArray(array);
displayCArray(array); // Should give all 0s
// Switching
CArray *arr = getCArray(13);
for (i = 0; i < arr->size; i++)
{
insertValueCArray(arr, i, i + 1);
}
displayCArray(arr);
for (i = 0; i < arr->size / 2; i++)
{
switchValuesCArray(arr, i, arr->size - i - 1);
}
displayCArray(arr);
// Or simply...
reverseCArray(arr);
displayCArray(arr);
// Sorting
srand(time(NULL));
CArray *barray = getCArray(20);
for (i = 0; i < barray->size; i++)
{
insertValueCArray(barray, i, rand());
}
CArray *carray = getCopyCArray(barray);
CArray *darray = getCopyCArray(barray);
printf("\nNot sorted Array:");
displayCArray(barray);
printf("\nBubble Sort:");
clock_t begin1 = clock();
// Timing bubble sort
bubbleSortCArray(barray);
clock_t end1 = clock();
double time_spent1 = (double)(end1 - begin1) / CLOCKS_PER_SEC;
displayCArray(barray);
printf("\nSelection Sort:");
clock_t begin2 = clock();
// Timing selection sort
selectionSortCArray(carray);
clock_t end2 = clock();
double time_spent2 = (double)(end2 - begin2) / CLOCKS_PER_SEC;
displayCArray(carray);
printf("\nInsertion Sort:");
clock_t begin3 = clock();
// Timing insertion sort
insertionSortCArray(darray);
clock_t end3 = clock();
double time_spent3 = (double)(end3 - begin3) / CLOCKS_PER_SEC;
displayCArray(carray);
// Descending order
reverseCArray(barray);
// displayCArray(barray);
// printf("\nBlender:");
// blenderCArray(barray);
// displayCArray(barray);
printf("\nTotal time spent for bubble sort: %lf seconds", time_spent1);
printf("\nTotal time spent for selection sort: %lf seconds", time_spent2);
printf("\nTotal time spent for insertion sort: %lf seconds", time_spent3);
// Searching
CArray *aarray = getCArray(1000);
for (i = 0; i < aarray->size; i++)
{
insertValueCArray(aarray, i, rand() % 100);
}
int j = 24;
printf("\nOccurrences of the number %d in the array: %d", j,
valueOcurranceCArray(aarray, j));
printf("\nAnd its positions:\n");
CArray *positions = valuePositionsCArray(aarray, j);
displayCArray(positions);
// This should all give value of j
printf("\nAll %d s", j);
for (i = 0; i < positions->size; i++)
{
printf("\nPosition %d has a value of %d", positions->array[i],
aarray->array[positions->array[i]]);
}
printf("\nThe list has a minimum value of %d and a maximum value of %d",
findMinCArray(aarray), findMaxCArray(aarray));
insertionSortCArray(aarray);
// displayCArray(aarray);
free(arr);
free(array);
free(aarray);
free(barray);
free(carray);
free(darray);
printf("\n");
return 0;
}

View File

@@ -0,0 +1,420 @@
#include <stdio.h>
#include <stdlib.h>
struct AVLnode
{
int key;
struct AVLnode *left;
struct AVLnode *right;
int height;
};
typedef struct AVLnode avlNode;
int max(int a, int b) { return (a > b) ? a : b; }
avlNode *newNode(int key)
{
avlNode *node = (avlNode *)malloc(sizeof(avlNode));
if (node == NULL)
printf("!! Out of Space !!\n");
else
{
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 0;
}
return node;
}
int nodeHeight(avlNode *node)
{
if (node == NULL)
return -1;
else
return (node->height);
}
int heightDiff(avlNode *node)
{
if (node == NULL)
return 0;
else
return (nodeHeight(node->left) - nodeHeight(node->right));
}
/* Returns the node with min key in the left subtree*/
avlNode *minNode(avlNode *node)
{
avlNode *temp = node;
while (temp->left != NULL) temp = temp->left;
return temp;
}
void printAVL(avlNode *node, int level)
{
int i;
if (node != NULL)
{
printAVL(node->right, level + 1);
printf("\n\n");
for (i = 0; i < level; i++) printf("\t");
printf("%d", node->key);
printAVL(node->left, level + 1);
}
}
avlNode *rightRotate(avlNode *z)
{
avlNode *y = z->left;
avlNode *T3 = y->right;
y->right = z;
z->left = T3;
z->height = (max(nodeHeight(z->left), nodeHeight(z->right)) + 1);
y->height = (max(nodeHeight(y->left), nodeHeight(y->right)) + 1);
return y;
}
avlNode *leftRotate(avlNode *z)
{
avlNode *y = z->right;
avlNode *T3 = y->left;
y->left = z;
z->right = T3;
z->height = (max(nodeHeight(z->left), nodeHeight(z->right)) + 1);
y->height = (max(nodeHeight(y->left), nodeHeight(y->right)) + 1);
return y;
}
avlNode *LeftRightRotate(avlNode *z)
{
z->left = leftRotate(z->left);
return (rightRotate(z));
}
avlNode *RightLeftRotate(avlNode *z)
{
z->right = rightRotate(z->right);
return (leftRotate(z));
}
avlNode *insert(avlNode *node, int key)
{
if (node == NULL)
return (newNode(key));
/*Binary Search Tree insertion*/
if (key < node->key)
node->left =
insert(node->left, key); /*Recursive insertion in L subtree*/
else if (key > node->key)
node->right =
insert(node->right, key); /*Recursive insertion in R subtree*/
/* Node Height as per the AVL formula*/
node->height = (max(nodeHeight(node->left), nodeHeight(node->right)) + 1);
/*Checking for the balance condition*/
int balance = heightDiff(node);
/*Left Left */
if (balance > 1 && key < (node->left->key))
return rightRotate(node);
/*Right Right */
if (balance < -1 && key > (node->right->key))
return leftRotate(node);
/*Left Right */
if (balance > 1 && key > (node->left->key))
{
node = LeftRightRotate(node);
}
/*Right Left */
if (balance < -1 && key < (node->right->key))
{
node = RightLeftRotate(node);
}
return node;
}
avlNode *delete (avlNode *node, int queryNum)
{
if (node == NULL)
return node;
if (queryNum < node->key)
node->left =
delete (node->left, queryNum); /*Recursive deletion in L subtree*/
else if (queryNum > node->key)
node->right =
delete (node->right, queryNum); /*Recursive deletion in R subtree*/
else
{
/*Single or No Child*/
if ((node->left == NULL) || (node->right == NULL))
{
avlNode *temp = node->left ? node->left : node->right;
/* No Child*/
if (temp == NULL)
{
temp = node;
node = NULL;
}
else /*Single Child : copy data to the parent*/
*node = *temp;
free(temp);
}
else
{
/*Two Child*/
/*Get the smallest key in the R subtree*/
avlNode *temp = minNode(node->right);
node->key = temp->key; /*Copy that to the root*/
node->right =
delete (node->right,
temp->key); /*Delete the smallest in the R subtree.*/
}
}
/*single node in tree*/
if (node == NULL)
return node;
/*Update height*/
node->height = (max(nodeHeight(node->left), nodeHeight(node->right)) + 1);
int balance = heightDiff(node);
/*Left Left */
if ((balance > 1) && (heightDiff(node->left) >= 0))
return rightRotate(node);
/*Left Right */
if ((balance > 1) && (heightDiff(node->left) < 0))
{
node = LeftRightRotate(node);
}
/*Right Right */
if ((balance < -1) && (heightDiff(node->right) >= 0))
return leftRotate(node);
/*Right Left */
if ((balance < -1) && (heightDiff(node->right) < 0))
{
node = RightLeftRotate(node);
}
return node;
}
avlNode *findNode(avlNode *node, int queryNum)
{
if (node != NULL)
{
if (queryNum < node->key)
node = findNode(node->left, queryNum);
else if (queryNum > node->key)
node = findNode(node->right, queryNum);
}
return node;
}
void printPreOrder(avlNode *node)
{
if (node == NULL)
return;
printf(" %d ", (node->key));
printPreOrder(node->left);
printPreOrder(node->right);
}
void printInOrder(avlNode *node)
{
if (node == NULL)
return;
printInOrder(node->left);
printf(" %d ", (node->key));
printInOrder(node->right);
}
void printPostOrder(avlNode *node)
{
if (node == NULL)
return;
printPostOrder(node->left);
printPostOrder(node->right);
printf(" %d ", (node->key));
}
int main()
{
int choice;
int flag = 1;
int insertNum;
int queryNum;
avlNode *root = NULL;
avlNode *tempNode;
while (flag == 1)
{
printf("\n\nEnter the Step to Run : \n");
printf("\t1: Insert a node into AVL tree\n");
printf("\t2: Delete a node in AVL tree\n");
printf("\t3: Search a node into AVL tree\n");
printf("\t4: printPreOrder (Ro L R) Tree\n");
printf("\t5: printInOrder (L Ro R) Tree\n");
printf("\t6: printPostOrder (L R Ro) Tree\n");
printf("\t7: printAVL Tree\n");
printf("\t0: EXIT\n");
scanf("%d", &choice);
switch (choice)
{
case 0:
{
flag = 0;
printf("\n\t\tExiting, Thank You !!\n");
break;
}
case 1:
{
printf("\n\tEnter the Number to insert: ");
scanf("%d", &insertNum);
tempNode = findNode(root, insertNum);
if (tempNode != NULL)
printf("\n\t %d Already exists in the tree\n", insertNum);
else
{
printf("\n\tPrinting AVL Tree\n");
printAVL(root, 1);
printf("\n");
root = insert(root, insertNum);
printf("\n\tPrinting AVL Tree\n");
printAVL(root, 1);
printf("\n");
}
break;
}
case 2:
{
printf("\n\tEnter the Number to Delete: ");
scanf("%d", &queryNum);
tempNode = findNode(root, queryNum);
if (tempNode == NULL)
printf("\n\t %d Does not exist in the tree\n", queryNum);
else
{
printf("\n\tPrinting AVL Tree\n");
printAVL(root, 1);
printf("\n");
root = delete (root, queryNum);
printf("\n\tPrinting AVL Tree\n");
printAVL(root, 1);
printf("\n");
}
break;
}
case 3:
{
printf("\n\tEnter the Number to Search: ");
scanf("%d", &queryNum);
tempNode = findNode(root, queryNum);
if (tempNode == NULL)
printf("\n\t %d : Not Found\n", queryNum);
else
{
printf("\n\t %d : Found at height %d \n", queryNum,
tempNode->height);
printf("\n\tPrinting AVL Tree\n");
printAVL(root, 1);
printf("\n");
}
break;
}
case 4:
{
printf("\nPrinting Tree preOrder\n");
printPreOrder(root);
break;
}
case 5:
{
printf("\nPrinting Tree inOrder\n");
printInOrder(root);
break;
}
case 6:
{
printf("\nPrinting Tree PostOrder\n");
printPostOrder(root);
break;
}
case 7:
{
printf("\nPrinting AVL Tree\n");
printAVL(root, 1);
break;
}
default:
{
flag = 0;
printf("\n\t\tExiting, Thank You !!\n");
break;
}
}
}
return 0;
}

View File

@@ -1,206 +1,308 @@
/**
* @file
* @brief A basic unbalanced binary search tree implementation in C.
* @details The implementation has the following functionalities implemented:
* - Insertion
* - Deletion
* - Search by key value
* - Listing of node keys in order of value (from left to right)
*/
#include <stdio.h>
#include <stdlib.h>
/* A basic unbalanced binary search tree implementation in C, with the following functionalities implemented:
- Insertion
- Deletion
- Search by key value
- Listing of node keys in order of value (from left to right)
*/
// Node, the basic data structure in the tree
typedef struct node{
// left child
struct node* left;
// right child
struct node* right;
// data of the node
int data;
/** Node, the basic data structure in the tree */
typedef struct node
{
struct node *left; /**< left child */
struct node *right; /**< right child */
int data; /**< data of the node */
} node;
// The node constructor, which receives the key value input and returns a node pointer
node* newNode(int data){
/** The node constructor, which receives the key value input and returns a node
* pointer
* @param data data to store in a new node
* @returns new node with the provided data
* @note the node must be deleted before program terminates to avoid memory
* leaks
*/
node *newNode(int data)
{
// creates a slug
node* tmp = (node*)malloc(sizeof(node));
node *tmp = (node *)malloc(sizeof(node));
// initializes the slug
tmp->data = data;
tmp->left = NULL;
tmp->right = NULL;
// initializes the slug
tmp->data = data;
tmp->left = NULL;
tmp->right = NULL;
return tmp;
return tmp;
}
// Insertion procedure, which inserts the input key in a new node in the tree
node* insert(node* root, int data){
// If the root of the subtree is null, insert key here
if (root == NULL)
root = newNode(data);
// If it isn't null and the input key is greater than the root key, insert in the right leaf
else if (data > root->data)
root->right = insert(root->right, data);
// If it isn't null and the input key is lower than the root key, insert in the left leaf
else if (data < root->data)
root->left = insert(root->left, data);
// Returns the modified tree
return root;
/** Insertion procedure, which inserts the input key in a new node in the tree
* @param root pointer to parent node
* @param data value to store int he new node
* @returns pointer to parent node
*/
node *insert(node *root, int data)
{
// If the root of the subtree is null, insert key here
if (root == NULL)
{
root = newNode(data);
}
else if (data > root->data)
{
// If it isn't null and the input key is greater than the root key,
// insert in the right leaf
root->right = insert(root->right, data);
}
else if (data < root->data)
{ // If it isn't null and the input key is lower than the root key, insert
// in the left leaf
root->left = insert(root->left, data);
}
// Returns the modified tree
return root;
}
// Utilitary procedure to find the greatest key in the left subtree
node* getMax(node* root){
// If there's no leaf to the right, then this is the maximum key value
if (root->right == NULL)
return root;
else
root->right = getMax(root->right);
/** Utilitary procedure to find the greatest key in the left subtree
* @param root pointer to parent node
* @returns pointer to parent node
*/
node *getMax(node *root)
{
// If there's no leaf to the right, then this is the maximum key value
if (root->right != NULL)
{
return getMax(root->right);
}
return root;
}
// Deletion procedure, which searches for the input key in the tree and removes it if present
node* delete(node* root, int data){
// If the root is null, nothing to be done
if (root == NULL)
return root;
// If the input key is greater than the root's, search in the right subtree
else if (data > root->data)
root->right = delete(root->right, data);
// If the input key is lower than the root's, search in the left subtree
else if (data < root->data)
root->left = delete(root->left, data);
// If the input key matches the root's, check the following cases
// termination condition
else if (data == root->data){
// Case 1: the root has no leaves, remove the node
if ((root->left == NULL) && (root->right == NULL)){
free(root);
return NULL;
}
// Case 2: the root has one leaf, make the leaf the new root and remove the old root
else if (root->left == NULL){
node* tmp = root;
root = root->right;
free(tmp);
return root;
}
else if (root->right == NULL){
node* tmp = root;
root = root->left;
free(tmp);
return root;
}
// Case 3: the root has 2 leaves, find the greatest key in the left subtree and switch with the root's
else {
/** Deletion procedure, which searches for the input key in the tree and removes
* it if present
* @param root pointer to parent node
* @param data value to search for int the node
* @returns pointer to parent node
*/
node *delete (node *root, int data)
{
// If the root is null, nothing to be done
if (root == NULL)
{
return root;
}
else if (data > root->data)
{ // If the input key is greater than the root's, search in the right
// subtree
root->right = delete (root->right, data);
}
else if (data < root->data)
{ // If the input key is lower than the root's, search in the left subtree
root->left = delete (root->left, data);
}
else if (data == root->data)
{
// If the input key matches the root's, check the following cases
// termination condition
if ((root->left == NULL) && (root->right == NULL))
{ // Case 1: the root has no leaves, remove the node
free(root);
return NULL;
}
else if (root->left == NULL)
{ // Case 2: the root has one leaf, make the leaf the new root and
// remove
// the old root
node *tmp = root;
root = root->right;
free(tmp);
return root;
}
else if (root->right == NULL)
{
node *tmp = root;
root = root->left;
free(tmp);
return root;
}
else
{ // Case 3: the root has 2 leaves, find the greatest key in the left
// subtree and switch with the root's
// finds the biggest node in the left branch.
node* tmp = getMax(root->left);
node *tmp = getMax(root->left);
// sets the data of this node equal to the data of the biggest node (lefts)
root->data = tmp->data;
root->left = delete(root->left, tmp->data);
}
}
return root;
// sets the data of this node equal to the data of the biggest node
// (lefts)
root->data = tmp->data;
root->left = delete (root->left, tmp->data);
}
}
return root;
}
// Search procedure, which looks for the input key in the tree and returns 1 if it's present or 0 if it's not in the tree
int find(node* root, int data){
// If the root is null, the key's not present
if (root == NULL)
return 0;
// If the input key is greater than the root's, search in the right subtree
else if (data > root->data)
return find(root->right, data);
// If the input key is lower than the root's, search in the left subtree
else if (data < root->data)
return find(root->left, data);
// If the input and the root key match, return 1
else if (data == root->data)
return 1;
/** Search procedure, which looks for the input key in the tree and returns 1 if
* it's present or 0 if it's not in the tree
* @param root pointer to parent node
* @param data value to store int he new node
* @returns 0 if value not found in the nodes
* @returns 1 if value was found
*/
int find(node *root, int data)
{
// If the root is null, the key's not present
if (root == NULL)
{
return 0;
}
else if (data > root->data)
{
// If the input key is greater than the root's, search in the right
// subtree
return find(root->right, data);
}
else if (data < root->data)
{
// If the input key is lower than the root's, search in the left subtree
return find(root->left, data);
}
else if (data == root->data)
{
// If the input and the root key match, return 1
return 1;
}
else
{ // unknown result!!
return 0;
}
}
// Utilitary procedure to measure the height of the binary tree
int height(node* root){
// If the root is null, this is the bottom of the tree (height 0)
if (root == NULL)
return 0;
else{
// Get the height from both left and right subtrees to check which is the greatest
int right_h = height(root->right);
int left_h = height(root->left);
/** Utilitary procedure to measure the height of the binary tree
* @param root pointer to parent node
* @param data value to store int he new node
* @returns 0 if value not found in the nodes
* @returns height of nodes to get to data from parent node
*/
int height(node *root)
{
// If the root is null, this is the bottom of the tree (height 0)
if (root == NULL)
{
return 0;
}
else
{
// Get the height from both left and right subtrees to check which is
// the greatest
int right_h = height(root->right);
int left_h = height(root->left);
// The final height is the height of the greatest subtree(left or right) plus 1(which is the root's level)
if (right_h > left_h)
return (right_h + 1);
else
return (left_h + 1);
}
// The final height is the height of the greatest subtree(left or right)
// plus 1(which is the root's level)
if (right_h > left_h)
{
return (right_h + 1);
}
else
{
return (left_h + 1);
}
}
}
// Utilitary procedure to free all nodes in a tree
void purge(node* root){
if (root != NULL){
if (root->left != NULL)
purge(root->left);
if (root->right != NULL)
purge(root->right);
free(root);
}
/** Utilitary procedure to free all nodes in a tree
* @param root pointer to parent node
*/
void purge(node *root)
{
if (root != NULL)
{
if (root->left != NULL)
{
purge(root->left);
}
if (root->right != NULL)
{
purge(root->right);
}
free(root);
root = NULL; // reset pointer
}
}
// Traversal procedure to list the current keys in the tree in order of value (from the left to the right)
void inOrder(node* root){
if(root != NULL){
inOrder(root->left);
printf("\t[ %d ]\t", root->data);
inOrder(root->right);
}
/** Traversal procedure to list the current keys in the tree in order of value
* (from the left to the right)
* @param root pointer to parent node
*/
void inOrder(node *root)
{
if (root != NULL)
{
inOrder(root->left);
printf("\t[ %d ]\t", root->data);
inOrder(root->right);
}
}
void main(){
/** Main funcion */
int main()
{
// this reference don't change.
// only the tree changes.
node* root = NULL;
int opt = -1;
int data = 0;
node *root = NULL;
int opt = -1;
int data = 0;
// event-loop.
while (opt != 0){
printf("\n\n[1] Insert Node\n[2] Delete Node\n[3] Find a Node\n[4] Get current Height\n[5] Print Tree in Crescent Order\n[0] Quit\n");
scanf("%d",&opt); // reads the choice of the user
while (opt != 0)
{
printf(
"\n\n[1] Insert Node\n[2] Delete Node\n[3] Find a Node\n[4] Get "
"current Height\n[5] Print Tree in Crescent Order\n[0] Quit\n");
scanf("%d", &opt); // reads the choice of the user
// processes the choice
switch(opt){
case 1: printf("Enter the new node's value:\n");
scanf("%d",&data);
root = insert(root,data);
break;
switch (opt)
{
case 1:
printf("Enter the new node's value:\n");
scanf("%d", &data);
root = insert(root, data);
break;
case 2: printf("Enter the value to be removed:\n");
if (root != NULL){
scanf("%d",&data);
root = delete(root,data);
}
else
printf("Tree is already empty!\n");
break;
case 2:
printf("Enter the value to be removed:\n");
if (root != NULL)
{
scanf("%d", &data);
root = delete (root, data);
}
else
{
printf("Tree is already empty!\n");
}
break;
case 3: printf("Enter the searched value:\n");
scanf("%d",&data);
find(root,data) ? printf("The value is in the tree.\n") : printf("The value is not in the tree.\n");
break;
case 3:
printf("Enter the searched value:\n");
scanf("%d", &data);
find(root, data) ? printf("The value is in the tree.\n")
: printf("The value is not in the tree.\n");
break;
case 4: printf("Current height of the tree is: %d\n", height(root));
break;
case 4:
printf("Current height of the tree is: %d\n", height(root));
break;
case 5: inOrder(root);
break;
}
}
case 5:
inOrder(root);
break;
}
}
// deletes the tree from the heap.
purge(root);
purge(root);
return 0;
}

View File

@@ -1,5 +1,5 @@
/* Includes structure for a node and a newNode() function which
can be used to create a new node in the tree.
can be used to create a new node in the tree.
It is assumed that the data in nodes will be an integer, though
function can be modified according to the data type, easily.
*/
@@ -35,5 +35,5 @@ int main(void)
nameOfNode->leftNode and so on.
*/
return 0;
return 0;
}

View File

@@ -7,7 +7,7 @@
void inOrderTraversal(struct node *node)
{
if(node == NULL) //if tree is empty
if (node == NULL) // if tree is empty
return;
inOrderTraversal(node->leftNode);
@@ -17,7 +17,7 @@ void inOrderTraversal(struct node *node)
void preOrderTraversal(struct node *node)
{
if(node == NULL) //if tree is empty
if (node == NULL) // if tree is empty
return;
printf("\t%d\t", node->data);
@@ -27,12 +27,12 @@ void preOrderTraversal(struct node *node)
void postOrderTraversal(struct node *node)
{
if(node == NULL) //if tree is empty
if (node == NULL) // if tree is empty
return;
postOrderTraversal(node->leftNode);
postOrderTraversal(node->rightNode);
printf("\t%d\t",node->data);
printf("\t%d\t", node->data);
}
int main(void)
@@ -41,5 +41,5 @@ int main(void)
function with a pointer to the root node.
*/
return 0;
return 0;
}

View File

@@ -0,0 +1,797 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int val;
struct node *par;
struct node *left;
struct node *right;
int color;
} Node;
// Create a new node
Node *newNode(int val, Node *par)
{
Node *create = (Node *)(malloc(sizeof(Node)));
create->val = val;
create->par = par;
create->left = NULL;
create->right = NULL;
create->color = 1;
}
// Check if the node is the leaf
int isLeaf(Node *n)
{
if (n->left == NULL && n->right == NULL)
{
return 1;
}
return 0;
}
// Left Rotate
Node *leftRotate(Node *node)
{
Node *parent = node->par;
Node *grandParent = parent->par;
parent->right = node->left;
if (node->left != NULL)
{
node->left->par = parent;
}
node->par = grandParent;
parent->par = node;
node->left = parent;
if (grandParent != NULL)
{
if (grandParent->right == parent)
{
grandParent->right = node;
}
else
{
grandParent->left = node;
}
}
return node;
}
// Right Rotate
Node *rightRotate(Node *node)
{
Node *parent = node->par;
Node *grandParent = parent->par;
parent->left = node->right;
if (node->right != NULL)
{
node->right->par = parent;
}
node->par = grandParent;
parent->par = node;
node->right = parent;
if (grandParent != NULL)
{
if (grandParent->right == parent)
{
grandParent->right = node;
}
else
{
grandParent->left = node;
}
}
return node;
}
// Check the node after the insertion step
void checkNode(Node *node)
{
// If the node is the root
if (node == NULL || node->par == NULL)
{
return;
}
Node *child = node;
// If it is a black node or its parent is a black node
if (node->color == 0 || (node->par)->color == 0)
{
// Dont Do Anything
return;
}
// Both parent and child are red
// Check For Uncle
Node *parent = node->par;
Node *grandParent = parent->par;
// If grandParent is NULL, then parent is the root.
// Just make the root black.
if (grandParent == NULL)
{
parent->color = 0;
return;
}
// If both the children of the grandParent are red
if (grandParent->right != NULL && (grandParent->right)->color == 1 &&
grandParent->left != NULL && (grandParent->left)->color == 1)
{
// Make the grandParent red and both of its children black
(grandParent->right)->color = 0;
(grandParent->left)->color = 0;
grandParent->color = 1;
return;
}
else
{
// The only option left is rotation.
Node *greatGrandParent = grandParent->par;
// Right Case
if (grandParent->right == parent)
{
// Right Right Case
if (parent->right == node)
{
grandParent->right = parent->left;
if (parent->left != NULL)
{
(parent->left)->par = grandParent;
}
parent->left = grandParent;
grandParent->par = parent;
// Attach to existing Tree;
parent->par = greatGrandParent;
if (greatGrandParent != NULL)
{
if (greatGrandParent->left != NULL &&
greatGrandParent->left == grandParent)
{
greatGrandParent->left = parent;
}
else
{
greatGrandParent->right = parent;
}
}
// Change the colors
parent->color = 0;
grandParent->color = 1;
}
else
{ // Right Left Case
// First step -> Parent Child Rotation
parent->left = child->right;
if (child->right != NULL)
{
(child->right)->par = parent;
}
child->right = parent;
parent->par = child;
// Second step -> Child and GrandParent Rotation
grandParent->right = child->left;
if (child->left != NULL)
{
(child->left)->par = grandParent;
}
child->left = grandParent;
grandParent->par = child;
// Attach to the existing tree
child->par = greatGrandParent;
if (greatGrandParent != NULL)
{
if (greatGrandParent->left != NULL &&
greatGrandParent->left == grandParent)
{
greatGrandParent->left = child;
}
else
{
greatGrandParent->right = child;
}
}
// Change The Colors
child->color = 0;
grandParent->color = 1;
}
}
else
{ // Left Case
// Left Left Case
if (parent->left == node)
{
grandParent->left = parent->right;
if (parent->right != NULL)
{
(parent->right)->par = grandParent;
}
parent->right = grandParent;
grandParent->par = parent;
// Attach to existing Tree;
parent->par = greatGrandParent;
if (greatGrandParent != NULL)
{
if (greatGrandParent->left != NULL &&
greatGrandParent->left == grandParent)
{
greatGrandParent->left = parent;
}
else
{
greatGrandParent->right = parent;
}
}
// Change the colors
parent->color = 0;
grandParent->color = 1;
}
else
{ // Left Right Case
// First step -> Parent Child Rotation
parent->right = child->left;
if (child->left != NULL)
{
(child->left)->par = parent;
}
child->left = parent;
parent->par = child;
// Second step -> Child and GrandParent Rotation
grandParent->left = child->right;
if (child->right != NULL)
{
(child->right)->par = grandParent;
}
child->right = grandParent;
grandParent->par = child;
// Attach to the existing tree
child->par = greatGrandParent;
if (greatGrandParent != NULL)
{
if (greatGrandParent->left != NULL &&
greatGrandParent->left == grandParent)
{
greatGrandParent->left = child;
}
else
{
greatGrandParent->right = child;
}
}
// Change The Colors
child->color = 0;
grandParent->color = 1;
}
}
}
}
// To insert a node in the existing tree
void insertNode(int val, Node **root)
{
Node *buffRoot = *root;
while (buffRoot)
{
if (buffRoot->val > val)
{
// Go left
if (buffRoot->left != NULL)
{
buffRoot = buffRoot->left;
}
else
{
// Insert The Node
Node *toInsert = newNode(val, buffRoot);
buffRoot->left = toInsert;
buffRoot = toInsert;
// Check For Double Red Problems
break;
}
}
else
{
// Go right
if (buffRoot->right != NULL)
{
buffRoot = buffRoot->right;
}
else
{
// Insert The Node
Node *toInsert = newNode(val, buffRoot);
buffRoot->right = toInsert;
buffRoot = toInsert;
// Check For Double Red Problems
break;
}
}
}
while (buffRoot != *root)
{
checkNode(buffRoot);
if (buffRoot->par == NULL)
{
*root = buffRoot;
break;
}
buffRoot = buffRoot->par;
if (buffRoot == *root)
{
buffRoot->color = 0;
}
}
}
void checkForCase2(Node *toDelete, int delete, int fromDirection, Node **root)
{
if (toDelete == (*root))
{
(*root)->color = 0;
return;
}
if (!delete &&toDelete->color == 1)
{
if (!fromDirection)
{
if (toDelete->right != NULL)
{
toDelete->right->color = 1;
}
}
else
{
if (toDelete->left != NULL)
{
toDelete->left->color = 1;
}
}
toDelete->color = 0;
return;
}
// Get the sibling for further inspection
Node *sibling;
Node *parent = toDelete->par;
int locateChild = 0; // 0 if toDeleted is left of its parent else 1
if (parent->right == toDelete)
{
sibling = parent->left;
locateChild = 1;
}
else
{
sibling = parent->right;
}
// Case 2.1. i.e. if the any children of the sibling is red
if ((sibling->right != NULL && sibling->right->color == 1) ||
(sibling->left != NULL && sibling->left->color == 1))
{
if (sibling->right != NULL && sibling->right->color == 1)
{
// Sibling is left and child is right. i.e. LEFT RIGHT ROTATION
if (locateChild == 1)
{
int parColor = parent->color;
// Step 1: Left rotate sibling
sibling = leftRotate(sibling->right);
// Step 2: Right rotate updated sibling
parent = rightRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
// Step 3: Update the colors
parent->color = parColor;
parent->left->color = 0;
parent->right->color = 0;
// Delete the node (present at parent->right->right)
if (delete)
{
if (toDelete->left != NULL)
{
toDelete->left->par = parent->right;
}
parent->right->right = toDelete->left;
free(toDelete);
}
}
else
{ // Sibling is right and child is also right. i.e. LEFT LEFT
// ROTATION
int parColor = parent->color;
// Left Rotate the sibling
parent = leftRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
// Update Colors
parent->color = parColor;
parent->left->color = 0;
parent->right->color = 0;
// Delete the node (present at parent->left->left)
if (delete)
{
if (toDelete->right != NULL)
{
toDelete->right->par = parent->left;
}
parent->left->left = toDelete->left;
free(toDelete);
}
}
}
else
{
// Sibling is right and child is left. i.e. RIGHT LEFT ROTATION
if (locateChild == 0)
{
int parColor = parent->color;
// Step 1: Right rotate sibling
sibling = rightRotate(sibling->left);
// printf("%d - reached\n", sibling->val);
// return;
// Step 2: Left rotate updated sibling
parent = leftRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
// Step 3: Update the colors
parent->color = parColor;
parent->left->color = 0;
parent->right->color = 0;
// Delete the node (present at parent->left->left)
if (delete)
{
if (toDelete->right != NULL)
{
toDelete->right->par = parent->left;
}
parent->left->left = toDelete->right;
free(toDelete);
}
}
else
{ // Sibling is left and child is also left. i.e. RIGHT RIGHT
// ROTATION
int parColor = parent->color;
// Right Rotate the sibling
parent = rightRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
// Update Colors
parent->color = parColor;
parent->left->color = 0;
parent->right->color = 0;
// Delete the node (present at parent->right->right)
if (delete)
{
if (toDelete->left != NULL)
{
toDelete->left->par = parent->right;
}
parent->right->right = toDelete->left;
free(toDelete);
}
}
}
}
else if (sibling->color == 0)
{ // Make the sibling red and recur for its parent
// Recolor the sibling
sibling->color = 1;
// Delete if necessary
if (delete)
{
if (locateChild)
{
toDelete->par->right = toDelete->left;
if (toDelete->left != NULL)
{
toDelete->left->par = toDelete->par;
}
}
else
{
toDelete->par->left = toDelete->right;
if (toDelete->right != NULL)
{
toDelete->right->par = toDelete->par;
}
}
}
checkForCase2(parent, 0, locateChild, root);
}
else
{ // Bring the sibling on top and apply 2.1 or 2.2 accordingly
if (locateChild)
{ // Right Rotate
toDelete->par->right = toDelete->left;
if (toDelete->left != NULL)
{
toDelete->left->par = toDelete->par;
}
parent = rightRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
parent->color = 0;
parent->right->color = 1;
checkForCase2(parent->right, 0, 1, root);
}
else
{ // Left Rotate
toDelete->par->left = toDelete->right;
if (toDelete->right != NULL)
{
toDelete->right->par = toDelete->par;
}
parent = leftRotate(sibling);
// Check if the root is rotated
if (parent->par == NULL)
{
*root = parent;
}
printf("\nroot - %d - %d\n", parent->val, parent->left->val);
parent->color = 0;
parent->left->color = 1;
checkForCase2(parent->left, 0, 0, root);
}
}
}
// To delete a node from the tree
void deleteNode(int val, Node **root)
{
Node *buffRoot = *root;
// Search for the element in the tree
while (1)
{
if (val == buffRoot->val)
{
// Node Found
break;
}
if (val > buffRoot->val)
{
if (buffRoot->right != NULL)
{
buffRoot = buffRoot->right;
}
else
{
printf("Node Not Found!!!");
return;
}
}
else
{
if (buffRoot->left != NULL)
{
buffRoot = buffRoot->left;
}
else
{
printf("Node Not Found!!!");
return;
}
}
}
Node *toDelete = buffRoot;
// Look for the leftmost of right node or right most of left node
if (toDelete->left != NULL)
{
toDelete = toDelete->left;
while (toDelete->right != NULL)
{
toDelete = toDelete->right;
}
}
else if (toDelete->right != NULL)
{
toDelete = toDelete->right;
while (toDelete->left != NULL)
{
toDelete = toDelete->left;
}
}
if (toDelete == *root)
{
*root = NULL;
return;
}
// Swap the values
buffRoot->val = toDelete->val;
toDelete->val = val;
// Checking for case 1
if (toDelete->color == 1 ||
(toDelete->left != NULL && toDelete->left->color == 1) ||
(toDelete->right != NULL && toDelete->right->color == 1))
{
// if it is a leaf
if (toDelete->left == NULL && toDelete->right == NULL)
{
// Delete instantly
if (toDelete->par->left == toDelete)
{
toDelete->par->left = NULL;
}
else
{
toDelete->par->right = NULL;
}
}
else
{ // else its child should be red
// Check for the exitstence of left node
if (toDelete->left != NULL)
{
// The node should be right to its parent
toDelete->par->right = toDelete->left;
toDelete->left->par = toDelete->par;
toDelete->left->color = 1;
}
else
{ // else the right node should be red
toDelete->par->left = toDelete->right;
toDelete->right->par = toDelete->par;
toDelete->right->color = 1;
}
}
// Remove the node from memory
free(toDelete);
}
else
{ // Case 2
checkForCase2(toDelete, 1, ((toDelete->par->right == toDelete)), root);
}
}
void printInorder(Node *root)
{
if (root != NULL)
{
printInorder(root->left);
printf("%d c-%d ", root->val, root->color);
printInorder(root->right);
}
}
void checkBlack(Node *temp, int c)
{
if (temp == NULL)
{
printf("%d ", c);
return;
}
if (temp->color == 0)
{
c++;
}
checkBlack(temp->left, c);
checkBlack(temp->right, c);
}
int main()
{
Node *root = NULL;
int scanValue, choice = 1;
printf(
"1 - Input\n2 - Delete\n3 - Inorder Traversel\n0 - Quit\n\nPlease "
"Enter the Choice - ");
scanf("%d", &choice);
while (choice)
{
switch (choice)
{
case 1:
printf("\n\nPlease Enter A Value to insert - ");
scanf("%d", &scanValue);
if (root == NULL)
{
root = newNode(scanValue, NULL);
root->color = 0;
}
else
{
insertNode(scanValue, &root);
}
printf("\nSuccessfully Inserted %d in the tree\n\n", scanValue);
break;
case 2:
printf("\n\nPlease Enter A Value to Delete - ");
scanf("%d", &scanValue);
deleteNode(scanValue, &root);
printf("\nSuccessfully Inserted %d in the tree\n\n", scanValue);
break;
case 3:
printf("\nInorder Traversel - ");
printInorder(root);
printf("\n\n");
// checkBlack(root,0);
// printf("\n");
break;
default:
if (root != NULL)
{
printf("Root - %d\n", root->val);
}
}
printf(
"1 - Input\n2 - Delete\n3 - Inorder Traversel\n0 - "
"Quit\n\nPlease Enter the Choice - ");
scanf("%d", &choice);
}
}
// 32 12 50 53 1 2 3 4 5 6 7 8 9

View File

@@ -0,0 +1,235 @@
/**
* @file segment_tree.c
* @brief segment trees with only point updates
* @details
* This code implements segment trees. Segment trees are general structures
* which allow range based queries in a given array in logN time.
* Segment tree with point updates allow update of single element in the array
* in logN time.
* [Learn more about segment trees
* here](https://codeforces.com/blog/entry/18051)
* @author [Lakhan Nad](https://github.com/Lakhan-Nad)
*/
#include <assert.h> /* for assert */
#include <inttypes.h> /* for int32 */
#include <stdio.h> /* for scanf printf */
#include <stdlib.h> /* for malloc, free */
#include <string.h> /* for memcpy, memset */
/**
* Function that combines two data to generate a new one
* The name of function might be misleading actually combine here signifies the
* fact that in segment trees we take partial result from two ranges and using
* partial results we derive the result for joint range of those two ranges
* For Example: array(1,2,3,4,5,6) sum of range [0,2] = 6
* and sum of range [3,5] = 15 the combined sum of two range is 6+15=21
* @note The function is same to binary function in Discrete Mathematics
* @param a pointer to first data
* @param b pointer to second data
* @param result pointer to memory location where result of combining a and b is
* to be stored
*/
typedef void (*combine_function)(const void *a, const void *b, void *result);
/**
* This structures holds all the data that is required by a segment tree
*/
typedef struct segment_tree
{
void *root; /**< the root of formed segment tree */
void *identity; /**< identity element for combine function */
size_t elem_size; /**< size in bytes of each data element */
size_t length; /**< total size of array which segment tree represents*/
/** the function to be used to combine two node's
* data to form parent's data
*/
combine_function combine;
} segment_tree;
/**
* Builds a Segment tree
* It is assumed that leaves of tree already contains data.
* @param tree pointer to segment tree to be build
*/
void segment_tree_build(segment_tree *tree)
{
size_t elem_size = tree->elem_size;
int index = (tree->length - 2);
size_t b, l, r;
char *ptr = (char *)tree->root;
for (; index >= 0; index--)
{
b = index * elem_size;
l = (2 * index + 1) * elem_size;
r = (2 * index + 2) * elem_size;
tree->combine(ptr + l, ptr + r, ptr + b);
}
}
/**
* For point updates
* This function updates the element at given index and also updates segment
* tree accordingly
*
* @param tree pointer to segment tree
* @param index the index whose element is to be updated (0 based indexing used)
* @param val pointer to value that is to be replaced at given index
*/
void segment_tree_update(segment_tree *tree, size_t index, void *val)
{
size_t elem_size = tree->elem_size;
index = index + tree->length - 1;
char *base = (char *)tree->root;
char *t = base + index * elem_size;
memcpy(t, val, elem_size);
while (index > 0)
{
index = ((index - 1) >> 1);
tree->combine(base + (2 * index + 1) * elem_size,
base + (2 * index + 2) * elem_size,
base + index * elem_size);
}
}
/**
* Query the segment tree
* This function helps in range query of segment tree
* This function assumes that the given range is valid
* Performs the query in range [l,r]
* @param tree pointer to segment tree
* @param l the start of range
* @param r the end of range
* @param res the pointer to memory where result of query is stored
*/
void segment_tree_query(segment_tree *tree, long long l, long long r, void *res)
{
size_t elem_size = tree->elem_size;
memcpy(res, tree->identity, elem_size);
elem_size = tree->elem_size;
char *root = (char *)tree->root;
l += tree->length - 1;
r += tree->length - 1;
while (l <= r)
{
if (!(l & 1))
{
tree->combine(res, root + l * elem_size, res);
}
if (r & 1)
{
tree->combine(res, root + r * elem_size, res);
}
r = (r >> 1) - 1;
l = (l >> 1);
}
}
/**
* Initializes Segment Tree
* Accquires memory for segment tree
* and fill the leaves of segment tree with data from array
* @param arr the array data upon which segment tree is build
* @param elem_size size of each element in segment tree
* @param len total no of elements in array
* @param identity the identity element for combine_function
* @param func the combine_function used to build segment tree
*
* @returns pointer to sgement tree build
*/
segment_tree *segment_tree_init(void *arr, size_t elem_size, size_t len,
void *identity, combine_function func)
{
segment_tree *tree = malloc(sizeof(segment_tree));
tree->elem_size = elem_size;
tree->length = len;
tree->combine = func;
tree->root = malloc(sizeof(char) * elem_size * (2 * len - 1));
tree->identity = malloc(sizeof(char) * elem_size);
char *ptr = (char *)tree->root;
memset(ptr, 0, (len - 1) * elem_size); // Initializing memory
ptr = ptr + (len - 1) * elem_size;
memcpy(ptr, arr, elem_size * len); // copy the leaf nodes i.e. array data
memcpy(tree->identity, identity, elem_size); // copy identity element
return tree;
}
/**
* Dispose Segment Tree
* Frees all heap memory accquired by segment tree
* @param tree pointer to segment tree
*/
void segment_tree_dispose(segment_tree *tree)
{
free(tree->root);
free(tree->identity);
}
/**
* Prints the data in segment tree
* The data should be of int type
* A utility to print segment tree
* with data type of int
* @param tree pointer to segment tree
*/
void segment_tree_print_int(segment_tree *tree)
{
char *base = (char *)tree->root;
size_t i = 0;
for (; i < 2 * tree->length - 1; i++)
{
printf("%d ", *(int *)(base + i * tree->elem_size));
}
printf("\n");
}
/**
* Utility for test
* A function compare for minimum between two integers
* This function is used as combine_function for RMQ
* @param a pointer to integer a
* @param b pointer to integer b
* @param c pointer where minimum of a and b is tored as result
*/
void minimum(const void *a, const void *b, void *c)
{
*(int *)c = *(int *)a < *(int *)b ? *(int *)a : *(int *)b;
}
/**
* Test RMQ
* Testing Segment tree using
* Range Minimum Queries
* @returns void
*/
static void test()
{
int32_t arr[10] = {1, 0, 3, 5, 7, 2, 11, 6, -2, 8};
int32_t identity = __INT32_MAX__;
segment_tree *tree =
segment_tree_init(arr, sizeof(*arr), 10, &identity, minimum);
segment_tree_build(tree);
int32_t result;
segment_tree_query(tree, 3, 6, &result);
assert(result == 2);
segment_tree_query(tree, 8, 9, &result);
assert(result == -2);
result = 12;
segment_tree_update(tree, 5, &result);
segment_tree_update(tree, 8, &result);
segment_tree_query(tree, 0, 3, &result);
assert(result == 0);
segment_tree_query(tree, 8, 9, &result);
assert(result == 8);
segment_tree_dispose(tree);
}
/**
* @brief Main Function
* @returns 0 on exit
*/
int main()
{
test();
return 0;
}

View File

@@ -0,0 +1,303 @@
/**
* @file
* \brief This file is a simple implementation of a Threaded Binary Tree
*
* Threaded Binary Tree is a binary tree variant in which all left child
* pointers that are NULL (in Linked list representation) point to its
* in-order predecessor, and all right child pointers that are NULL
* (in Linked list representation) point to its in-order successor.
* It has the following functionalities:
* - Insertion
* - Search
* - Deletion
* - Listing of node keys inorder,preorder,postorder
*
* -see binary_search_tree.c
*
* \author [Amitha Nayak](https://github.com/amitnayakblr)
*/
#include <stdio.h>
#include <stdlib.h>
/**
* Node, the basic data structure of the tree
*/
typedef struct Node
{
int data; /**< stores the number */
struct Node *llink; /**< link to left child */
struct Node *rlink; /**< link to right child */
} node;
/**
* creates a new node
* param[in] data value to be inserted
* \returns a pointer to the new node
*/
node *create_node(int data)
{
node *ptr = (node *)malloc(sizeof(node));
ptr->rlink = ptr->llink = NULL;
ptr->data = data;
return ptr;
}
/**
* inserts a node into the tree
* param[in,out] root pointer to node pointer to the topmost node of the tree
* param[in] data value to be inserted into the tree
*/
void insert_bt(node **root, int data)
{
node *new_node = create_node(data);
node *temp; // to be deleted
node *prev; // keeps track of the parent of the element deleted
if (*root == NULL)
{
*root = new_node;
}
else
{
temp = *root;
prev = NULL;
while (temp != NULL)
{
if (new_node->data > temp->data)
{
prev = temp;
temp = temp->rlink;
}
else if (new_node->data < temp->data)
{
prev = temp;
temp = temp->llink;
}
else
{
return;
}
}
if (new_node->data > prev->data)
{
prev->rlink = new_node;
}
else
{
prev->llink = new_node;
}
}
}
/**
* searches for the element
* \param[in] root node pointer to the topmost node of the tree
* \param[in] ele value searched for
*/
void search(node *root, int ele)
{
node *temp = root;
while (temp != NULL)
{
if (temp->data == ele)
{
break;
}
else if (ele > temp->data)
{
temp = temp->rlink;
}
else
{
temp = temp->llink;
}
}
if (temp == NULL)
{
printf("%s\n", "Element not found.");
}
else
printf("%s\n", "Element found.");
}
/**
* performs inorder traversal
* param[in] curr node pointer to the topmost node of the tree
*/
void inorder_display(node *curr)
{
if (curr != NULL)
{
inorder_display(curr->llink);
printf("%d\t", curr->data);
inorder_display(curr->rlink);
}
}
/**
* performs postorder traversal
* param[in] curr node pointer to the topmost node of the tree
*/
void postorder_display(node *curr)
{
if (curr != NULL)
{
postorder_display(curr->llink);
postorder_display(curr->rlink);
printf("%d\t", curr->data);
}
}
/**
* performs preorder traversal
* param[in] curr node pointer to the topmost node of the tree
*/
void preorder_display(node *curr)
{
if (curr != NULL)
{
printf("%d\t", curr->data);
preorder_display(curr->llink);
preorder_display(curr->rlink);
}
}
/**
* deletion of a node from the tree
* if the node isn't present in the tree, it takes no action.
* param[in,out] root pointer to node pointer to the topmost node of the tree
* param[in] ele value to be deleted from the tree
*/
void delete_bt(node **root, int ele)
{
node *temp;
node *prev;
if (*root == NULL)
return;
else
{
temp = *root;
prev = NULL;
// search
while (temp != NULL)
{
if (temp->data == ele)
{
break;
}
else if (ele > temp->data)
{
prev = temp;
temp = temp->rlink;
}
else
{
prev = temp;
temp = temp->llink;
}
}
}
if (temp == NULL)
return;
else
{
node *replacement; // deleted node's replacement
node *t;
if (temp->llink == NULL && temp->rlink == NULL)
{
replacement = NULL;
}
else if (temp->llink == NULL && temp->rlink != NULL)
{
replacement = temp->rlink;
}
else if (temp->llink != NULL && temp->rlink == NULL)
{
replacement = temp->llink;
}
else
{
replacement = temp->rlink; // replaced with inorder successor
t = replacement;
while (t->llink != NULL)
{
t = t->llink;
}
t->llink =
temp->llink; // leftmost node of the replacement is linked to
// the left child of the deleted node
}
if (temp == *root)
{
free(*root);
*root = replacement;
}
else if (prev->llink == temp)
{
free(prev->llink);
prev->llink = replacement;
}
else if (prev->rlink == temp)
{
free(prev->rlink);
prev->rlink = replacement;
}
}
}
/**
* main function
*/
int main()
{
printf("BINARY THREADED TREE: \n");
node *root = NULL;
int choice, n;
do
{
printf("%s\n", "1. Insert into BT");
printf("%s\n", "2. Print BT - inorder");
printf("%s\n", "3. Print BT - preorder");
printf("%s\n", "4. print BT - postorder");
printf("%s\n", "5. delete from BT");
printf("%s\n", "6. search in BT");
printf("%s\n", "Type 0 to exit");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("%s\n", "Enter a no:");
scanf("%d", &n);
insert_bt(&root, n);
break;
case 2:
inorder_display(root);
printf("\n");
break;
case 3:
preorder_display(root);
printf("\n");
break;
case 4:
postorder_display(root);
printf("\n");
break;
case 5:
printf("%s\n", "Enter a no:");
scanf("%d", &n);
delete_bt(&root, n);
break;
case 6:
printf("%s\n", "Enter a no:");
scanf("%d", &n);
search(root, n);
break;
}
} while (choice != 0);
return 0;
}

View File

@@ -0,0 +1,316 @@
/**
* @file
* @brief Printing the [words contained in a
* file](http://www.dailyfreecode.com/Code/word-list-reads-text-file-makes-2050.aspx)
* named `file.txt` in alphabetical order and also their frequencies in to
* another file "wordcount.txt"
* @details
* Given a file (`file.txt`) containing words (like a publication or a novel),
* where words are separated by a space, newline, or underscore.
* This program prints (writes or outputs) to another file (`wordcount.txt`),
* the individual words contained in 'file.txt' with their frequencies (number
* of occurences) each on a newline and in alphabetical order. This program uses
* the binary tree data structure to accomplish this task.
* @author [Randy Kwalar](https://github.com/RandyKdev)
*/
#include <assert.h> /// for assert
#include <ctype.h> /// for type checks
#include <inttypes.h> /// for uint64_t based types, int64_t based types
#include <stdbool.h> /// for boolean data type
#include <stdio.h> /// for IO operations
#include <stdlib.h> /// for memory allocation
#include <string.h> /// for string operations
/**
* @brief structure defining a node in the binary tree
*/
struct Node
{
char *word; ///< the word (value) of the node
uint64_t frequency; ///< number of occurences of the word
struct Node *left; ///< pointer to the left child node
struct Node *right; ///< pointer to the right child node
};
/**
* @brief Ends program due to an error
* @param errorMessage the error message to be printed
* @returns void
*/
void endProgramAbruptly(char *errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(EXIT_FAILURE);
}
/**
* @brief Frees memory when program is terminating
* @param node pointer to current node
* @returns void
*/
void freeTreeMemory(struct Node *node)
{
if (node != NULL)
{
freeTreeMemory(node->left);
freeTreeMemory(node->right);
free(node->word); // freeing node->word because memory was allocated
// using malloc
free(node); // freeing node because memory was allocated using malloc
}
}
/**
* @brief Stores word in memory
* @param word word to be stored in memory
* @returns a pointer to the newly allocated word if the word IS stored successfully
* @returns `NULL` if the word is NOT stored
*/
char *getPointerToWord(char *word)
{
char *string =
(char *)malloc((strlen(word) + 1) * sizeof(char)); ///< pointer to string
// + 1 is for the '\0' character
if (string != NULL)
{
strcpy(string, word);
return string;
}
endProgramAbruptly(
"\nA problem occurred while reserving memory for the word\n");
return NULL;
}
/**
* @brief Closes the file after reading or writing
* @param file pointer to the file to be closed
* @returns void
*/
void closeFile(FILE *file)
{
if (fclose(file)) {
endProgramAbruptly("\nA Problem Occurred while closing a file\n");
}
}
/**
* @brief Reserves memory for new node
* @returns a pointer to the newly allocated node if memory IS successfully reserved
* @returns `NULL` if memory is NOT reserved
*/
struct Node *allocateMemoryForNode()
{
struct Node *node =
(struct Node *)malloc(sizeof(struct Node)); ///< pointer to the node
if (node != NULL)
{
return node;
}
endProgramAbruptly(
"\nA problem occurred while reserving memory for the structure\n");
return NULL;
}
/**
* @brief Writes contents of tree to another file alphabetically
* @param node pointer to current node
* @param file pointer to file
* @returns void
*/
void writeContentOfTreeToFile(struct Node *node, FILE *file)
{
static uint64_t i = 1; ///< for word numbering in the write file
if (node != NULL) // checks if the node is valid
{
writeContentOfTreeToFile(
node->left,
file); // calls `writeContentOfTreeToFile` for left sub tree
fprintf(file, "%-5lu \t %-9lu \t %s \n", i++, node->frequency,
node->word); // prints the word number, word frequency and word
// in tabular format to the file
writeContentOfTreeToFile(
node->right,
file); // calls `writeContentOfTreeToFile` for right sub tree
}
}
/**
* @brief Adds word (node) to the correct position in tree
* @param word word to be inserted in to the tree
* @param currentNode node which is being compared
* @returns a pointer to the root node
*/
struct Node *addWordToTree(char *word, struct Node *currentNode)
{
if (currentNode == NULL) // checks if `currentNode` is `NULL`
{
struct Node *currentNode =
allocateMemoryForNode(); // allocates memory for new node
currentNode->word = getPointerToWord(word); // stores `word` in memory
currentNode->frequency = 1; // initializes the word frequency to 1
currentNode->left = NULL; // sets left node to `NULL`
currentNode->right = NULL; // sets right node to `NULL`
return currentNode; // returns pointer to newly created node
}
int64_t compared = strcmp(word, currentNode->word); ///< holds compare state
if (compared > 0) {
currentNode->right = addWordToTree(word,
currentNode->right); // adds `word` to right sub tree if `word` is
// alphabetically greater than `currentNode->word`
}
else if (compared < 0) {
currentNode->left = addWordToTree(word,
currentNode->left); // adds `word` to left sub tree if `word` is
// alphabetically less than `currentNode->word`
}
else {
currentNode->frequency++; // increments `currentNode` frequency if `word` is the same as `currentNode->word`
}
return currentNode; // returns pointer to current node
}
/**
* @brief Reads words from file to tree
* @param file file to be read from
* @param root root node of tree
* @returns a pointer to the root node
*/
struct Node *readWordsInFileToTree(FILE *file, struct Node *root)
{
// longest english word = 45 chars
// +1 for '\0' = 46 chars
char *inputString =
(char *)malloc(46 * sizeof(char)); ///< pointer to the input string
char inputChar; ///< temp storage of characters
bool isPrevCharAlpha = false; ///< bool to mark the end of a word
uint8_t pos = 0; ///< position in inputString to place the inputChar
while ((inputChar = fgetc(file)) != EOF)
{
if (pos > 0)
isPrevCharAlpha = isalpha(inputString[pos - 1]);
// checks if character is letter
if (isalpha(inputChar))
{
inputString[pos++] = tolower(inputChar);
continue;
}
// checks if character is ' or - and if it is preceded by a letter eg
// yours-not, persons' (valid)
if ((inputChar == '\'' || inputChar == '-') && isPrevCharAlpha)
{
inputString[pos++] = inputChar;
continue;
}
// makes sure that there is something valid in inputString
if (pos == 0)
continue;
// if last character is not letter and is not ' then replace by \0
if (!isPrevCharAlpha && inputString[pos - 1] != '\'')
pos--;
inputString[pos] = '\0';
pos = 0;
isPrevCharAlpha = false;
root = addWordToTree(inputString, root);
}
// this is to catch the case for the EOF being immediately after the last
// letter or '
if (pos > 0)
{
if (!isPrevCharAlpha && inputString[pos - 1] != '\'')
pos--;
inputString[pos] = '\0';
root = addWordToTree(inputString, root);
}
free(inputString);
return root;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void test()
{
struct Node *root = NULL; ///< pointer to the root node
FILE *file = NULL; ///< pointer to the file
file = fopen("file.txt", "w"); // creates test file in write mode
fprintf(file,
"hey_this, is a. test input \n to a_file"); // writes test data to
// test file
closeFile(file); // closes test file
file = fopen("file.txt", "r"); // reopens test file in read mode
root = readWordsInFileToTree(file,
root); // reads words from test file to tree
// Tests to check if words were added to correct position in tree and also
// if their frequencies were added correctly
assert(strcmp(root->word, "hey") == 0);
assert(root->frequency == 1);
assert(strcmp(root->left->word, "a") == 0);
assert(root->left->frequency == 2);
assert(strcmp(root->right->word, "this") == 0);
assert(strcmp(root->left->right->word, "file") == 0);
assert(strcmp(root->right->left->word, "is") == 0);
closeFile(file); // closes test file
remove("file.txt"); // deletes test file from storage
file = fopen("wordcount.txt", "a"); // creates write file
fprintf(file, "%-5s \t %9s \t %s \n", "S/N", "FREQUENCY",
"WORD"); // prints the heading to `wordcount.txt`
writeContentOfTreeToFile(
root, file); // writes content of tree to file (`wordcount.txt`)
// Here is how the output to `wordcount.txt` should look like
char *correctString =
"S/N FREQUENCY WORD \n"
"1 2 a \n"
"2 1 file \n"
"3 1 hey \n"
"4 1 input \n"
"5 1 is \n"
"6 1 n \n"
"7 1 test \n"
"8 1 this \n"
"9 1 to \n";
int16_t inputChar; // holds the current character in `wordcount.txt`
uint64_t i = 0; // holds the current index in `correctString`
// Checks if the content in `wordcount.txt` is as expected (the same as in
// `correctString`)
while ((inputChar = fgetc(file)) != EOF) {
assert(inputChar == correctString[i++]);
}
closeFile(file); // closes `wordcount.txt`
remove("wordcount.txt"); // deletes `wordcount.txt`
freeTreeMemory(root); // frees memory taken up by the tree
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
test(); // run self-test implementations
return 0;
}

View File

@@ -1,32 +1,30 @@
#include "dict.h"
#include <stdio.h>
#include <stdlib.h>
#include "dict.h"
/* simple constructor */
Dictionary * create_dict(void)
Dictionary *create_dict(void)
{
Dictionary * p_dic = malloc(sizeof (Dictionary));
Dictionary *p_dic = malloc(sizeof(Dictionary));
if (p_dic)
{
p_dic->number_of_elements = 0;
/* initializes the elemens of the array with NULL-pointer */
for (int i = 0; i < MAXELEMENTS; i++)
for (int i = 0; i < MAXELEMENTS; i++)
{
p_dic->elements[i] = NULL;
}
return p_dic;
}
else
else
{
printf("unable to create a dictionary\n");
return NULL;
}
}
/*
utility function
sdbm hash algorithm
@@ -37,18 +35,18 @@ int get_hash(char s[])
unsigned int hash_code = 0;
/* iterates over string at each character */
for (int counter = 0; s[counter]!='\0'; counter++)
for (int counter = 0; s[counter] != '\0'; counter++)
{
/* actual computing of the hash code */
hash_code = s[counter] + (hash_code << 6) + (hash_code << 16) - hash_code;
hash_code =
s[counter] + (hash_code << 6) + (hash_code << 16) - hash_code;
}
/* % modulo is for fitting the index in array. */
return hash_code % MAXELEMENTS;
}
int add_item_label(Dictionary * dic,char label[],void * item)
int add_item_label(Dictionary *dic, char label[], void *item)
{
unsigned int index = get_hash(label);
@@ -57,28 +55,26 @@ int add_item_label(Dictionary * dic,char label[],void * item)
{
dic->elements[index] = item;
return 0;
}
}
/* error case */
return -1;
return -1;
}
int add_item_index(Dictionary * dic , int index, void * item)
int add_item_index(Dictionary *dic, int index, void *item)
{
/* make sure whether this place is already given */
if (!dic->elements[index])
{
dic->elements[index] = item;
return 0;
}
}
/* error case */
return -1;
}
void * get_element_label(Dictionary * dict, char s[])
void *get_element_label(Dictionary *dict, char s[])
{
int index = get_hash(s);
if (dict->elements[index])
@@ -90,20 +86,15 @@ void * get_element_label(Dictionary * dict, char s[])
return NULL;
}
void * get_element_index(Dictionary * dict, int index)
void *get_element_index(Dictionary *dict, int index)
{
if (index >= 0 && index < MAXELEMENTS)
{
return dict->elements[index];
}
printf("index out of bounds!\n");
return NULL;
}
void destroy(Dictionary * dict)
{
free(dict);
}
void destroy(Dictionary *dict) { free(dict); }

View File

@@ -1,6 +1,6 @@
/*
author: Christian Bender
public interface for the dictionary.
public interface for the dictionary.
The dictionary prepares space for 1000 elements.
*/
@@ -14,13 +14,13 @@
special data type called 'Dictionary'
for generic use
*/
typedef struct Dict
typedef struct Dict
{
/*
/*
void* array for generic use of the dictionary.
there actual saves the entries.
*/
void * elements[MAXELEMENTS];
void *elements[MAXELEMENTS];
/* contains the number of elements in this dictionary */
int number_of_elements;
@@ -28,41 +28,38 @@ typedef struct Dict
} Dictionary;
/*
create_dict: is a simple constructor for creating
a dictionary and setting up the
create_dict: is a simple constructor for creating
a dictionary and setting up the
member field 'number_of_elements'
and prepares the inner array 'elements'
*/
Dictionary * create_dict(void);
Dictionary *create_dict(void);
/*
add_item_label: adds item (void*) to the dictionary at given label
/*
add_item_label: adds item (void*) to the dictionary at given label
returns 0 if adding was sucessful otherwise -1
*/
int add_item_label(Dictionary *,char label[],void *);
int add_item_label(Dictionary *, char label[], void *);
/*
add_item_index: adds item (void*) to the dictionary at given index (int)
/*
add_item_index: adds item (void*) to the dictionary at given index (int)
returns 0 if adding was sucessful otherwise -1
*/
int add_item_index(Dictionary *, int index, void *);
/*
get_element: returns the element at given label
*/
void *get_element_label(Dictionary *, char[]);
/*
get_element: returns the element at given label
get_element: returns the element at given index
*/
void * get_element_label(Dictionary *, char []);
void *get_element_index(Dictionary *, int);
/*
get_element: returns the element at given index
*/
void * get_element_index(Dictionary *, int );
/*
simple destrcutor function
*/
void destroy(Dictionary *);
#endif

View File

@@ -10,32 +10,32 @@
int main(void)
{
Dictionary * testObj1;
Dictionary * testObj2;
Dictionary *testObj1;
Dictionary *testObj2;
int value = 28;
int value = 28;
testObj1 = create_dict();
testObj2 = create_dict();
add_item_label(testObj1,"age",&value);
add_item_label(testObj2,"name","Christian");
add_item_label(testObj1, "age", &value);
add_item_label(testObj2, "name", "Christian");
/*
test for function add_item_label
attention:
The void* pointer must be convert into an int* pointer.
attention:
The void* pointer must be convert into an int* pointer.
After that you can dereference it.
*/
printf("My age is %d\n",*((int *)get_element_label(testObj1,"age")));
printf("My name is %s\n",get_element_label(testObj2,"name"));
printf("My age is %d\n", *((int *)get_element_label(testObj1, "age")));
printf("My name is %s\n", get_element_label(testObj2, "name"));
/* test for function add_item_index */
if (!add_item_index(testObj1,0,&value))
if (!add_item_index(testObj1, 0, &value))
{
printf("My age at index %d is %d\n",0,*((int *)get_element_index(testObj1,0)));
printf("My age at index %d is %d\n", 0,
*((int *)get_element_index(testObj1, 0)));
}
/* error scenario */

View File

@@ -0,0 +1,13 @@
CC = gcc
CFLAGS = -g -Wall
all: main
main: main.o dynamic_array.o
$(CC) $(CFLAGS) $^ -o $@
dynamic_array.o: dynamic_array.c
$(CC) $(CFLAGS) -c $^
clean:
rm *.o main

View File

@@ -0,0 +1,82 @@
#include "dynamic_array.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
dynamic_array_t *init_dynamic_array()
{
dynamic_array_t *da = malloc(sizeof(dynamic_array_t));
da->items = calloc(DEFAULT_CAPACITY, sizeof(void *));
da->capacity = DEFAULT_CAPACITY;
return da;
}
void *add(dynamic_array_t *da, const void *value)
{
if (da->size >= da->capacity)
{
void **newItems =
realloc(da->items, (da->capacity <<= 1) * sizeof(void **));
free(da->items);
da->items = newItems;
}
void *copy_value = retrive_copy_of_value(value);
da->items[da->size++] = copy_value;
return copy_value;
}
void *put(dynamic_array_t *da, const void *value, const unsigned index)
{
if (!contains(da->size, index))
return INDEX_OUT_OF_BOUNDS;
free(da->items[index]);
void *copy_value = retrive_copy_of_value(value);
da->items[index] = copy_value;
return copy_value;
}
void *get(dynamic_array_t *da, const unsigned index)
{
if (!contains(da->size, index))
return INDEX_OUT_OF_BOUNDS;
return da->items[index];
}
void delete (dynamic_array_t *da, const unsigned index)
{
if (!contains(da->size, index))
return;
for (unsigned i = index; i < da->size; i++)
{
da->items[i] = da->items[i + 1];
}
da->size--;
free(da->items[da->size]);
}
unsigned contains(const unsigned size, const unsigned index)
{
if (size >= 0 && index < size)
return 1;
printf("index [%d] out of bounds!\n", index);
return 0;
}
void *retrive_copy_of_value(const void *value)
{
void *value_copy = malloc(sizeof(void *));
memcpy(value_copy, value, sizeof(void *));
return value_copy;
}

View File

@@ -0,0 +1,27 @@
#ifndef __DYNAMIC_ARRAY__
#define __DYNAMIC_ARRAY__
#define DEFAULT_CAPACITY 1 << 4
#define INDEX_OUT_OF_BOUNDS NULL
typedef struct dynamic_array
{
void **items;
unsigned size;
unsigned capacity;
} dynamic_array_t;
extern dynamic_array_t *init_dynamic_array();
extern void *add(dynamic_array_t *da, const void *value);
extern void *put(dynamic_array_t *da, const void *value, unsigned index);
extern void *get(dynamic_array_t *da, const unsigned index);
extern void delete (dynamic_array_t *da, const unsigned index);
unsigned contains(const unsigned size, const unsigned index);
extern void *retrive_copy_of_value(const void *value);
#endif

View File

@@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include "dynamic_array.h"
int main()
{
dynamic_array_t *da = init_dynamic_array();
for (int i = 1; i <= 50; i++)
{
add(da, &i);
}
delete (da, 10);
int value = 1000;
put(da, &value, 0);
value = 5000;
int another_value = 7000;
add(da, &another_value);
for (int i = 0; i < da->size; i++)
{
printf("value %d\n", *(int *)get(da, i));
}
int value_for_invalid_index = 10000;
put(da, &value_for_invalid_index, 150);
return 0;
}

View File

@@ -1,130 +0,0 @@
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<string.h>
//Structure for storing edge
struct Edge{
int src,dst,weight;
};
//Structure for storing a graph
struct Graph{
int vertexNum;
int edgeNum;
struct Edge* edges;
};
//Constructs a graph with V vertices and E edges
void createGraph(struct Graph* G,int V,int E){
G->vertexNum = V;
G->edgeNum = E;
G->edges = (struct Edge*) malloc(E * sizeof(struct Edge));
}
//Adds the given edge to the graph
void addEdge(struct Graph* G, int src, int dst, int weight){
static int ind;
struct Edge newEdge;
newEdge.src = src;
newEdge.dst = dst;
newEdge.weight = weight;
G->edges[ind++]= newEdge;
}
//Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], int vset[], int V){
int minVal = INT_MAX, minInd ;
for(int i=0; i<V;i++)
if(vset[i] == 0 && mdist[i] < minVal){
minVal = mdist[i];
minInd = i;
}
return minInd;
}
//Utility function to print distances
void print(int dist[], int V){
printf("\nVertex Distance\n");
for(int i = 0; i < V; i++){
if(dist[i] != INT_MAX)
printf("%d\t%d\n",i,dist[i]);
else
printf("%d\tINF",i);
}
}
//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(struct 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]){
printf("Graph contains negative weight cycle. Hence, shortest distance not guaranteed.");
return;
}
}
print(dist, V);
return;
}
//Driver Function
int main(){
int V,E,gsrc;
int src,dst,weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d",&V);
printf("Enter number of edges: ");
scanf("%d",&E);
createGraph(&G,V,E);
for(int i=0; i<E; i++){
printf("\nEdge %d \nEnter source: ",i+1);
scanf("%d",&src);
printf("Enter destination: ");
scanf("%d",&dst);
printf("Enter weight: ");
scanf("%d",&weight);
addEdge(&G, src, dst, weight);
}
printf("\nEnter source:");
scanf("%d",&gsrc);
BellmanFord(&G,gsrc);
return 0;
}

View File

@@ -1,114 +0,0 @@
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<string.h>
//Structure for storing a graph
struct Graph{
int vertexNum;
int** edges;
};
//Constructs a graph with V vertices and E edges
void createGraph(struct Graph* G,int V){
G->vertexNum = V;
G->edges =(int**) malloc(V * sizeof(int*));
for(int i=0; i<V; i++){
G->edges[i] = (int*) malloc(V * sizeof(int));
for(int j=0; j<V; j++)
G->edges[i][j] = INT_MAX;
G->edges[i][i] = 0;
}
}
//Adds the given edge to the graph
void addEdge(struct Graph* G, int src, int dst, int weight){
G->edges[src][dst] = weight;
}
//Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], int vset[], int V){
int minVal = INT_MAX, minInd ;
for(int i=0; i<V;i++)
if(vset[i] == 0 && mdist[i] < minVal){
minVal = mdist[i];
minInd = i;
}
return minInd;
}
//Utility function to print distances
void print(int dist[], int V){
printf("\nVertex Distance\n");
for(int i = 0; i < V; i++){
if(dist[i] != INT_MAX)
printf("%d\t%d\n",i,dist[i]);
else
printf("%d\tINF",i);
}
}
//The main function that finds the shortest path from given source
//to all other vertices using Dijkstra's Algorithm.It doesn't work on negative
//weights
void Dijkstra(struct Graph* graph, int src){
int V = graph->vertexNum;
int mdist[V]; //Stores updated distances to vertex
int vset[V]; // vset[i] is true if the vertex i included
// in the shortest path tree
//Initialise mdist and vset. Set distance of source as zero
for(int i=0; i<V; i++)
mdist[i] = INT_MAX, vset[i] = 0;
mdist[src] = 0;
//iterate to find shortest path
for(int count = 0; count<V-1; count++){
int u = minDistance(mdist,vset,V);
vset[u] = 1;
for(int v=0; v<V; v++){
if(!vset[v] && graph->edges[u][v]!=INT_MAX && mdist[u] + graph->edges[u][v] < mdist[v])
mdist[v] = mdist[u] + graph->edges[u][v];
}
}
print(mdist, V);
return;
}
//Driver Function
int main(){
int V,E,gsrc;
int src,dst,weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d",&V);
printf("Enter number of edges: ");
scanf("%d",&E);
createGraph(&G,V);
for(int i=0; i<E; i++){
printf("\nEdge %d \nEnter source: ",i+1);
scanf("%d",&src);
printf("Enter destination: ");
scanf("%d",&dst);
printf("Enter weight: ");
scanf("%d",&weight);
addEdge(&G, src, dst, weight);
}
printf("\nEnter source:");
scanf("%d",&gsrc);
Dijkstra(&G,gsrc);
return 0;
}

View File

@@ -1,104 +0,0 @@
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<string.h>
//Structure for storing a graph
struct Graph{
int vertexNum;
int** edges;
};
//Constructs a graph with V vertices and E edges
void createGraph(struct Graph* G,int V){
G->vertexNum = V;
G->edges =(int**) malloc(V * sizeof(int*));
for(int i=0; i<V; i++){
G->edges[i] = (int*) malloc(V * sizeof(int));
for(int j=0; j<V; j++)
G->edges[i][j] = INT_MAX;
G->edges[i][i] = 0;
}
}
//Adds the given edge to the graph
void addEdge(struct Graph* G, int src, int dst, int weight){
G->edges[src][dst] = weight;
}
//Utility function to print distances
void print(int dist[], int V){
printf("\nThe Distance matrix for Floyd - Warshall\n");
for(int i = 0; i < V; i++){
for(int j=0; j<V; j++){
if(dist[i*V+j] != INT_MAX)
printf("%d\t",dist[i*V+j]);
else
printf("INF\t");
}
printf("\n");
}
}
//The main function that finds the shortest path from a vertex
//to all other vertices using Floyd-Warshall Algorithm.
void FloydWarshall(struct 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;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d",&V);
printf("Enter number of edges: ");
scanf("%d",&E);
createGraph(&G,V);
for(int i=0; i<E; i++){
printf("\nEdge %d \nEnter source: ",i+1);
scanf("%d",&src);
printf("Enter destination: ");
scanf("%d",&dst);
printf("Enter weight: ");
scanf("%d",&weight);
addEdge(&G, src, dst, weight);
}
FloydWarshall(&G);
return 0;
}

View File

@@ -0,0 +1,56 @@
CC=gcc
CFLAGS=-Wall -Werror -std=c99
all: BFS Bellman-Ford DFS Dijkstra Floyd-Warshall bfsQueue dfsRecursive euler hamiltonian strongly_connected_components topologicalSort transitiveClosure
BFS: BFS.c
$(CC) -o BFS BFS.c
Bellman-Ford: Bellman-Ford.c
$(CC) -o Bellman-Ford Bellman-Ford.c
DFS: DFS.c
$(CC) -o DFS DFS.c
Dijkstra: Dijkstra.c
$(CC) -o Dijkstra Dijkstra.c
Floyd-Warshall: Floyd-Warshall.c
$(CC) -o Floyd-Warshall Floyd-Warshall.c
Graph.o: Graph.c Graph.h
$(CC) $(CFLAGS) -c Graph.c
bfsQueue: Graph.o queue.o bfsQueue.o
$(CC) Graph.o queue.o bfsQueue.o -o bfsQueue
bfsQueue.o: bfsQueue.c
$(CC) $(CFLAGS) -c bfsQueue.c
dfsRecursive: Graph.o queue.o dfsRecursive.o
$(CC) Graph.o queue.o dfsRecursive.o -o dfsRecursive
dfsRecursive.o: dfsRecursive.c
$(CC) -c dfsRecursive.c
euler: Graph.o euler.o
$(CC) Graph.o euler.o -o euler
euler.o: euler.c
$(CC) $(CFLAGS) -c euler.c
hamiltonian: Graph.o hamiltonian.o
$(CC) Graph.o hamiltonian.o -o hamiltonian
hamiltonian.o: hamiltonian.c
$(CC) $(CFLAGS) -c hamiltonian.c
queue.o: queue.c queue.h
$(CC) $(CFLAGS) -c queue.c
strongly_connected_components: strongly_connected_components.c
$(CC) -o strongly_connected_components strongly_connected_components.c
topologicalSort: topologicalSort.c
$(CC) -o topologicalSort topologicalSort.c
transitiveClosure: transitiveClosure.c
$(CC) -o transitiveClosure transitiveClosure.c
# By
# .----------------. .----------------. .----------------. .-----------------. .----------------. .----------------.
# | .--------------. || .--------------. || .--------------. || .--------------. | | .--------------. || .--------------. |
# | | _________ | || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____ | || | ____ | |
# | | | _ _ | | || ||_ _||_ _|| || | / \ | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | |
# | | |_/ | | \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | | |__| | | || | / .--. \ | |
# | | | | | || | | ' ' | | || | / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
# | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_ | | | | _| | | |_ | || | \ `--' / | |
# | | |_____| | || | `.__.' | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.' | |
# | | | || | | || | | || | | | | | | || | | |
# | '--------------' || '--------------' || '--------------' || '--------------' | | '--------------' || '--------------' |
# '----------------' '----------------' '----------------' '----------------' '----------------' '----------------'
# Email : z5261243@unsw.edu.au
# hhoanhtuann@gmail.com

View File

@@ -0,0 +1,140 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Structure for storing edge
struct Edge
{
int src, dst, weight;
};
// Structure for storing a graph
struct Graph
{
int vertexNum;
int edgeNum;
struct Edge *edges;
};
// Constructs a graph with V vertices and E edges
void createGraph(struct Graph *G, int V, int E)
{
G->vertexNum = V;
G->edgeNum = E;
G->edges = (struct Edge *)malloc(E * sizeof(struct Edge));
}
// Adds the given edge to the graph
void addEdge(struct Graph *G, int src, int dst, int weight)
{
static int ind;
struct Edge newEdge;
newEdge.src = src;
newEdge.dst = dst;
newEdge.weight = weight;
G->edges[ind++] = newEdge;
}
// Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], int vset[], int V)
{
int minVal = INT_MAX, minInd;
for (int i = 0; i < V; i++)
if (vset[i] == 0 && mdist[i] < minVal)
{
minVal = mdist[i];
minInd = i;
}
return minInd;
}
// Utility function to print distances
void print(int dist[], int V)
{
printf("\nVertex Distance\n");
for (int i = 0; i < V; i++)
{
if (dist[i] != INT_MAX)
printf("%d\t%d\n", i, dist[i]);
else
printf("%d\tINF", i);
}
}
// 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(struct 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])
{
printf(
"Graph contains negative weight cycle. Hence, shortest "
"distance not guaranteed.");
return;
}
}
print(dist, V);
return;
}
// Driver Function
int main()
{
int V, E, gsrc;
int src, dst, weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
createGraph(&G, V, E);
for (int i = 0; i < E; i++)
{
printf("\nEdge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
printf("Enter weight: ");
scanf("%d", &weight);
addEdge(&G, src, dst, weight);
}
printf("\nEnter source:");
scanf("%d", &gsrc);
BellmanFord(&G, gsrc);
return 0;
}

View File

@@ -0,0 +1,195 @@
#include <stdio.h>
#include <stdlib.h>
#define SIZE 40
// Assume max size of graph is 40 nodes
struct queue
{
int items[SIZE];
int front;
int rear;
};
// Some declarations
struct queue *createQueue();
void enqueue(struct queue *q, int);
int dequeue(struct queue *q);
void display(struct queue *q);
int isEmpty(struct queue *q);
int pollQueue(struct queue *q);
// Structure to create a graph node
struct node
{
int vertex;
struct node *next;
};
struct node *createNode(int);
// Graph data structure
struct Graph
{
int numVertices;
struct node **adjLists;
int *visited;
};
struct Graph *createGraph(int vertices);
void addEdge(struct Graph *graph, int src, int dest);
void printGraph(struct Graph *graph);
void bfs(struct Graph *graph, int startVertex);
int main()
{
int vertices, edges, source, i, src, dst;
printf("Enter the number of vertices\n");
scanf("%d", &vertices);
struct Graph *graph = createGraph(vertices);
printf("Enter the number of edges\n");
scanf("%d", &edges);
for (i = 0; i < edges; i++)
{
printf("Edge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
addEdge(graph, src, dst);
}
printf("Enter source of bfs\n");
scanf("%d", &source);
bfs(graph, source);
// Uncomment below part to get a ready-made example
/*struct Graph* graph = createGraph(6);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 1, 4);
addEdge(graph, 1, 3);
addEdge(graph, 2, 4);
addEdge(graph, 3, 4);
bfs(graph,0);*/
return 0;
}
void bfs(struct Graph *graph, int startVertex)
{
struct queue *q = createQueue();
// Add to visited list and put in queue
graph->visited[startVertex] = 1;
enqueue(q, startVertex);
printf("Breadth first traversal from vertex %d is:\n", startVertex);
// Iterate while queue not empty
while (!isEmpty(q))
{
printf("%d ", pollQueue(q));
int currentVertex = dequeue(q);
struct node *temp = graph->adjLists[currentVertex];
// Add all unvisited neighbours of current vertex to queue to be printed
// next
while (temp)
{
int adjVertex = temp->vertex;
// Only add if neighbour is unvisited
if (graph->visited[adjVertex] == 0)
{
graph->visited[adjVertex] = 1;
enqueue(q, adjVertex);
}
temp = temp->next;
}
}
}
// Memory for a graph node
struct node *createNode(int v)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Allocates memory for graph data structure, in adjacency list format
struct Graph *createGraph(int vertices)
{
struct Graph *graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;
graph->adjLists = malloc(vertices * sizeof(struct node *));
graph->visited = malloc(vertices * sizeof(int));
int i;
for (i = 0; i < vertices; i++)
{
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
// Adds bidirectional edge to graph
void addEdge(struct Graph *graph, int src, int dest)
{
// Add edge from src to dest
struct node *newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
// Add edge from dest to src; comment it out for directed graph
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Allocates memory for our queue data structure
struct queue *createQueue()
{
struct queue *q = malloc(sizeof(struct queue));
q->front = -1;
q->rear = -1;
return q;
}
// Checks for empty queue
int isEmpty(struct queue *q)
{
if (q->rear == -1)
return 1;
else
return 0;
}
// Inserts item at start of queue
void enqueue(struct queue *q, int value)
{
if (q->rear == SIZE - 1)
printf("\nQueue is Full!!");
else
{
if (q->front == -1)
q->front = 0;
q->rear++;
q->items[q->rear] = value;
}
}
// Returns item at front of queue and removes it from queue
int dequeue(struct queue *q)
{
int item;
if (isEmpty(q))
{
printf("Queue is empty");
item = -1;
}
else
{
item = q->items[q->front];
q->front++;
if (q->front > q->rear)
{
q->front = q->rear = -1;
}
}
return item;
}
// Returns element at front of queue
int pollQueue(struct queue *q) { return q->items[q->front]; }

View File

@@ -0,0 +1,124 @@
#include <stdbool.h>
#include <stdio.h>
#include "Graph.h"
#include "queue.h"
#define MAX_NODES 1000
int visited[MAX_NODES]; // array to store visiting order
// indexed by vertex 0..nV-1
bool findPathBFS(Graph g, int nV, Vertex src, Vertex dest)
{
Vertex v;
for (v = 0; v < nV; v++) visited[v] = -1;
visited[src] = src;
queue Q = newQueue();
QueueEnqueue(Q, src);
while (!QueueIsEmpty(Q))
{
v = QueueDequeue(Q);
Vertex w;
for (w = 0; w < nV; w++)
if (adjacent(g, v, w) && visited[w] == -1)
{
visited[w] = v;
if (w == dest)
return true;
else
QueueEnqueue(Q, w);
}
}
return false;
}
int main(void)
{
int V = 10;
Graph g = newGraph(V);
Edge e;
e.v = 0;
e.w = 1;
insertEdge(g, e);
e.v = 0;
e.w = 2;
insertEdge(g, e);
e.v = 0;
e.w = 5;
insertEdge(g, e);
e.v = 1;
e.w = 5;
insertEdge(g, e);
e.v = 2;
e.w = 3;
insertEdge(g, e);
e.v = 3;
e.w = 4;
insertEdge(g, e);
e.v = 3;
e.w = 5;
insertEdge(g, e);
e.v = 3;
e.w = 8;
insertEdge(g, e);
e.v = 4;
e.w = 5;
insertEdge(g, e);
e.v = 4;
e.w = 7;
insertEdge(g, e);
e.v = 4;
e.w = 8;
insertEdge(g, e);
e.v = 5;
e.w = 6;
insertEdge(g, e);
e.v = 7;
e.w = 8;
insertEdge(g, e);
e.v = 7;
e.w = 9;
insertEdge(g, e);
e.v = 8;
e.w = 9;
insertEdge(g, e);
int src = 0, dest = 6;
if (findPathBFS(g, V, src, dest))
{
Vertex v = dest;
while (v != src)
{
printf("%d - ", v);
v = visited[v];
}
printf("%d\n", src);
}
return 0;
}
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

View File

@@ -0,0 +1,134 @@
#include <stdio.h>
#include <stdlib.h>
// A vertex of the graph
struct node
{
int vertex;
struct node *next;
};
// Some declarations
struct node *createNode(int v);
struct Graph
{
int numVertices;
int *visited;
struct node *
*adjLists; // we need int** to store a two dimensional array. Similary,
// we need struct node** to store an array of Linked lists
};
struct Graph *createGraph(int);
void addEdge(struct Graph *, int, int);
void printGraph(struct Graph *);
void dfs(struct Graph *, int);
int main()
{
int vertices, edges, source, i, src, dst;
printf("Enter the number of vertices\n");
scanf("%d", &vertices);
struct Graph *graph = createGraph(vertices);
printf("Enter the number of edges\n");
scanf("%d", &edges);
for (i = 0; i < edges; i++)
{
printf("Edge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
addEdge(graph, src, dst);
}
printf("Enter source of DFS\n");
scanf("%d", &source);
printf("DFS from %d is:\n", source);
dfs(graph, source);
printf("\n");
// Uncomment below part to get a ready-made example
/*struct Graph* graph = createGraph(4);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 2, 3);
printf("DFS from 0 is:\n");
dfs(graph,0);
printf("\n");*/
return 0;
}
// Recursive dfs approach
void dfs(struct Graph *graph, int vertex)
{
struct node *adjList = graph->adjLists[vertex];
struct node *temp = adjList;
// Add vertex to visited list and print it
graph->visited[vertex] = 1;
printf("%d ", vertex);
// Recursively call the dfs function on all unvisited neighbours
while (temp != NULL)
{
int connectedVertex = temp->vertex;
if (graph->visited[connectedVertex] == 0)
{
dfs(graph, connectedVertex);
}
temp = temp->next;
}
}
// Allocate memory for a node
struct node *createNode(int v)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Allocate memory for the entire graph structure
struct Graph *createGraph(int vertices)
{
struct Graph *graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;
graph->adjLists = malloc(vertices * sizeof(struct node *));
graph->visited = malloc(vertices * sizeof(int));
int i;
for (i = 0; i < vertices; i++)
{
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
// Creates a bidirectional graph
void addEdge(struct Graph *graph, int src, int dest)
{
// Add edge from src to dest
struct node *newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
// Add edge from dest to src
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Utility function to see state of graph at a given time
void printGraph(struct Graph *graph)
{
int v;
for (v = 0; v < graph->numVertices; v++)
{
struct node *temp = graph->adjLists[v];
printf("\n Adjacency list of vertex %d\n ", v);
while (temp)
{
printf("%d -> ", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}

View File

@@ -0,0 +1,103 @@
#include <stdbool.h>
#include <stdio.h>
#include "Graph.h"
#define MAX_NODES 1000
int visited[MAX_NODES]; // array to store visiting order
// indexed by vertex 0..nV-1
bool dfsPathCheck(Graph g, int nV, Vertex v, Vertex dest)
{
Vertex w;
for (w = 0; w < nV; w++)
if (adjacent(g, v, w) && visited[w] == -1)
{
visited[w] = v;
if (w == dest)
return true;
else if (dfsPathCheck(g, nV, w, dest))
return true;
}
return false;
}
bool findPathDFS(Graph g, int nV, Vertex src, Vertex dest)
{
Vertex v;
for (v = 0; v < nV; v++) visited[v] = -1;
visited[src] = src;
return dfsPathCheck(g, nV, src, dest);
}
int main(void)
{
int V = 6;
Graph g = newGraph(V);
Edge e;
e.v = 0;
e.w = 1;
insertEdge(g, e);
e.v = 0;
e.w = 4;
insertEdge(g, e);
e.v = 0;
e.w = 5;
insertEdge(g, e);
e.v = 5;
e.w = 4;
insertEdge(g, e);
e.v = 4;
e.w = 2;
insertEdge(g, e);
e.v = 4;
e.w = 3;
insertEdge(g, e);
e.v = 5;
e.w = 3;
insertEdge(g, e);
e.v = 1;
e.w = 2;
insertEdge(g, e);
e.v = 3;
e.w = 2;
insertEdge(g, e);
int src = 0, dest = 5;
if (findPathDFS(g, V, src, dest))
{
Vertex v = dest;
while (v != src)
{
printf("%d - ", v);
v = visited[v];
}
printf("%d\n", src);
}
return 0;
}
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

View File

@@ -0,0 +1,119 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Structure for storing a graph
struct Graph
{
int vertexNum;
int **edges;
};
// Constructs a graph with V vertices and E edges
void createGraph(struct Graph *G, int V)
{
G->vertexNum = V;
G->edges = (int **)malloc(V * sizeof(int *));
for (int i = 0; i < V; i++)
{
G->edges[i] = (int *)malloc(V * sizeof(int));
for (int j = 0; j < V; j++) G->edges[i][j] = INT_MAX;
G->edges[i][i] = 0;
}
}
// Adds the given edge to the graph
void addEdge(struct Graph *G, int src, int dst, int weight)
{
G->edges[src][dst] = weight;
}
// Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], int vset[], int V)
{
int minVal = INT_MAX, minInd;
for (int i = 0; i < V; i++)
if (vset[i] == 0 && mdist[i] < minVal)
{
minVal = mdist[i];
minInd = i;
}
return minInd;
}
// Utility function to print distances
void print(int dist[], int V)
{
printf("\nVertex Distance\n");
for (int i = 0; i < V; i++)
{
if (dist[i] != INT_MAX)
printf("%d\t%d\n", i, dist[i]);
else
printf("%d\tINF", i);
}
}
// The main function that finds the shortest path from given source
// to all other vertices using Dijkstra's Algorithm.It doesn't work on negative
// weights
void Dijkstra(struct Graph *graph, int src)
{
int V = graph->vertexNum;
int mdist[V]; // Stores updated distances to vertex
int vset[V]; // vset[i] is true if the vertex i included
// in the shortest path tree
// Initialise mdist and vset. Set distance of source as zero
for (int i = 0; i < V; i++) mdist[i] = INT_MAX, vset[i] = 0;
mdist[src] = 0;
// iterate to find shortest path
for (int count = 0; count < V - 1; count++)
{
int u = minDistance(mdist, vset, V);
vset[u] = 1;
for (int v = 0; v < V; v++)
{
if (!vset[v] && graph->edges[u][v] != INT_MAX &&
mdist[u] + graph->edges[u][v] < mdist[v])
mdist[v] = mdist[u] + graph->edges[u][v];
}
}
print(mdist, V);
return;
}
// Driver Function
int main()
{
int V, E, gsrc;
int src, dst, weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
createGraph(&G, V);
for (int i = 0; i < E; i++)
{
printf("\nEdge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
printf("Enter weight: ");
scanf("%d", &weight);
addEdge(&G, src, dst, weight);
}
printf("\nEnter source:");
scanf("%d", &gsrc);
Dijkstra(&G, gsrc);
return 0;
}

View File

@@ -0,0 +1,95 @@
#include <stdbool.h>
#include <stdio.h>
#include "Graph.h"
// Return the number of vertices that v is
// connected to
int degree(Graph g, int nV, Vertex v)
{
int deg = 0;
Vertex w;
for (w = 0; w < nV; w++)
if (adjacent(g, v, w))
deg++;
return deg;
}
// If start from vertex v, decide if the
// graph has euler path
bool hasEulerPath(Graph g, int nV, Vertex v, Vertex w)
{
if (v != w)
{
if (degree(g, nV, v) % 2 == 0 || degree(g, nV, w) % 2 == 0)
return false;
}
else if (degree(g, nV, v) % 2 != 0)
{
return false;
}
Vertex x;
for (x = 0; x < nV; x++)
if (x != v && x != w && degree(g, nV, x) % 2 != 0)
return false;
return true;
}
int main(void)
{
Edge e;
int n;
printf("Enter the number of vertices: ");
scanf("%d", &n);
Graph g = newGraph(n);
Vertex src, dest;
printf("Enter source node: ");
scanf("%d", &src);
printf("Enter destination node: ");
scanf("%d", &dest);
printf("Enter an edge (from): ");
while (scanf("%d", &e.v) == 1)
{
printf("Enter an edge (to): ");
scanf("%d", &e.w);
insertEdge(g, e);
printf("Enter an edge (from): ");
}
printf("Finished.\n");
printf("The graph has ");
if (hasEulerPath(g, n, src, dest))
printf("an");
else
printf("no");
printf(" Euler path from %d to %d.\n", src, dest);
freeGraph(g);
return 0;
}
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

View File

@@ -0,0 +1,108 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Structure for storing a graph
struct Graph
{
int vertexNum;
int **edges;
};
// Constructs a graph with V vertices and E edges
void createGraph(struct Graph *G, int V)
{
G->vertexNum = V;
G->edges = (int **)malloc(V * sizeof(int *));
for (int i = 0; i < V; i++)
{
G->edges[i] = (int *)malloc(V * sizeof(int));
for (int j = 0; j < V; j++) G->edges[i][j] = INT_MAX;
G->edges[i][i] = 0;
}
}
// Adds the given edge to the graph
void addEdge(struct Graph *G, int src, int dst, int weight)
{
G->edges[src][dst] = weight;
}
// Utility function to print distances
void print(int dist[], int V)
{
printf("\nThe Distance matrix for Floyd - Warshall\n");
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i * V + j] != INT_MAX)
printf("%d\t", dist[i * V + j]);
else
printf("INF\t");
}
printf("\n");
}
}
// The main function that finds the shortest path from a vertex
// to all other vertices using Floyd-Warshall Algorithm.
void FloydWarshall(struct 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;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
createGraph(&G, V);
for (int i = 0; i < E; i++)
{
printf("\nEdge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
printf("Enter weight: ");
scanf("%d", &weight);
addEdge(&G, src, dst, weight);
}
FloydWarshall(&G);
return 0;
}

View File

@@ -0,0 +1,117 @@
// Graph ADT
// Adjacency Matrix Representation
#include "Graph.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct GraphRep
{
int **edges; // adjacency matrix
int nV; // #vertices
int nE; // #edges
} GraphRep;
Graph newGraph(int V)
{
assert(V >= 0);
int i;
Graph g = malloc(sizeof(GraphRep));
assert(g != NULL);
g->nV = V;
g->nE = 0;
// allocate memory for each row
g->edges = malloc(V * sizeof(int *));
assert(g->edges != NULL);
// allocate memory for each column and initialise with 0
for (i = 0; i < V; i++)
{
g->edges[i] = calloc(V, sizeof(int));
assert(g->edges[i] != NULL);
}
return g;
}
// check if vertex is valid in a graph
bool validV(Graph g, Vertex v) { return (g != NULL && v >= 0 && v < g->nV); }
void insertEdge(Graph g, Edge e)
{
assert(g != NULL && validV(g, e.v) && validV(g, e.w));
if (!g->edges[e.v][e.w])
{ // edge e not in graph
g->edges[e.v][e.w] = 1;
g->edges[e.w][e.v] = 1;
g->nE++;
}
}
void removeEdge(Graph g, Edge e)
{
assert(g != NULL && validV(g, e.v) && validV(g, e.w));
if (g->edges[e.v][e.w])
{ // edge e in graph
g->edges[e.v][e.w] = 0;
g->edges[e.w][e.v] = 0;
g->nE--;
}
}
bool adjacent(Graph g, Vertex v, Vertex w)
{
assert(g != NULL && validV(g, v) && validV(g, w));
return (g->edges[v][w] != 0);
}
void showGraph(Graph g)
{
assert(g != NULL);
int i, j;
printf("Number of vertices: %d\n", g->nV);
printf("Number of edges: %d\n", g->nE);
for (i = 0; i < g->nV; i++)
for (j = i + 1; j < g->nV; j++)
if (g->edges[i][j])
printf("Edge %d - %d\n", i, j);
}
void freeGraph(Graph g)
{
assert(g != NULL);
int i;
for (i = 0; i < g->nV; i++) free(g->edges[i]);
free(g->edges);
free(g);
}
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

View File

@@ -0,0 +1,45 @@
// Graph ADT interface ... COMP2521
#include <stdbool.h>
typedef struct GraphRep *Graph;
// vertices are ints
typedef int Vertex;
// edges are pairs of vertices (end-points)
typedef struct Edge
{
Vertex v;
Vertex w;
} Edge;
Graph newGraph(int);
void insertEdge(Graph, Edge);
void removeEdge(Graph, Edge);
bool adjacent(Graph, Vertex, Vertex);
void showGraph(Graph);
void freeGraph(Graph);
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

View File

@@ -0,0 +1,103 @@
#include <stdbool.h>
#include <stdio.h>
#include "Graph.h"
#define MAX_NODES 1000
bool visited[MAX_NODES];
bool hamiltonR(Graph g, int nV, Vertex v, Vertex dest, int d)
{
// v = current vertex considered
// dest = destination vertex
// d = distance "remaining" until path found
Vertex w;
if (v == dest)
{
return (d == 0);
}
else
{
visited[v] = true;
for (w = 0; w < nV; w++)
{
if (adjacent(g, v, w) && !visited[w])
{
if (hamiltonR(g, nV, w, dest, d - 1))
{
return true;
}
}
}
}
visited[v] = false;
return false;
}
bool hasHamiltonianPath(Graph g, int nV, Vertex src, Vertex dest)
{
Vertex v;
for (v = 0; v < nV; v++) visited[v] = false;
return hamiltonR(g, nV, src, dest, nV - 1);
}
int main(void)
{
Edge e;
int n;
printf("Enter the number of vertices: ");
scanf("%d", &n);
Graph g = newGraph(n);
Vertex src, dest;
printf("Enter source node: ");
scanf("%d", &src);
printf("Enter destination node: ");
scanf("%d", &dest);
printf("Enter an edge (from): ");
while (scanf("%d", &e.v) == 1)
{
printf("Enter an edge (to): ");
scanf("%d", &e.w);
insertEdge(g, e);
printf("Enter an edge (from): ");
}
printf("Finished.\n");
printf("The graph has ");
if (hasHamiltonianPath(g, n, src, dest))
printf("a");
else
printf("no");
printf(" Hamiltonian path from %d to %d.\n", src, dest);
freeGraph(g);
return 0;
}
// By
// .----------------. .----------------. .----------------.
// .-----------------. .----------------. .----------------.
// | .--------------. || .--------------. || .--------------. ||
// .--------------. | | .--------------. || .--------------. | | | _________ |
// || | _____ _____ | || | __ | || | ____ _____ | | | | ____ ____
// | || | ____ | | | | | _ _ | | || ||_ _||_ _|| || | / \
// | || ||_ \|_ _| | | | | |_ || _| | || | .' `. | | | | |_/ | |
// \_| | || | | | | | | || | / /\ \ | || | | \ | | | | | | |
// |__| | | || | / .--. \ | | | | | | | || | | ' ' | | || |
// / ____ \ | || | | |\ \| | | | | | | __ | | || | | | | | | |
// | | _| |_ | || | \ `--' / | || | _/ / \ \_ | || | _| |_\ |_
// | | | | _| | | |_ | || | \ `--' / | | | | |_____| | || | `.__.'
// | || ||____| |____|| || ||_____|\____| | | | | |____||____| | || | `.____.'
// | | | | | || | | || | | || | | | | |
// | || | | | | '--------------' || '--------------' ||
// '--------------' || '--------------' | | '--------------' || '--------------'
// |
// '----------------' '----------------' '----------------'
// '----------------' '----------------' '----------------'
// Email : z5261243@unsw.edu.au
// hhoanhtuann@gmail.com

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