mirror of
https://github.com/TheAlgorithms/C.git
synced 2026-02-15 14:05:11 +00:00
Merge branch 'TheAlgorithms:master' into master
This commit is contained in:
167
.clang-format
Normal file
167
.clang-format
Normal 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
6
.clang-tidy
Normal 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
65
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal 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
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
38
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal 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
22
.github/ISSUE_TEMPLATE/other.yml
vendored
Normal 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
24
.github/pull_request_template.md
vendored
Normal 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
14
.github/workflows/approved-label.yml
vendored
Normal 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
166
.github/workflows/awesome_workflow.yml
vendored
Normal 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
48
.github/workflows/codeql_analysis.yml
vendored
Normal 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
36
.github/workflows/gh-pages.yml
vendored
Normal 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
18
.github/workflows/stale.yml
vendored
Normal 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
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
*.swp
|
||||
*.exe
|
||||
*.out
|
||||
.vscode/
|
||||
build/
|
||||
11
.gitpod.dockerfile
Normal file
11
.gitpod.dockerfile
Normal 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
17
.gitpod.yml
Normal 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
7
.vscode/settings.json
vendored
Normal 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
112
CMakeLists.txt
Normal 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
76
CODE_OF_CONDUCT.md
Normal 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
218
CONTRIBUTING.md
Normal 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 [](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.
|
||||
|
||||

|
||||
|
||||
- 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
417
DIRECTORY.md
Normal 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
277
Doxyfile
Normal 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
676
LICENSE
Normal 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
101
README.md
@@ -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)
|
||||
[](https://gitpod.io/#https://github.com/TheAlgorithms/C)
|
||||
[](https://lgtm.com/projects/g/TheAlgorithms/C/context:cpp)
|
||||
[](https://github.com/TheAlgorithms/C/actions/workflows/codeql_analysis.yml)
|
||||
[](https://gitter.im/TheAlgorithms)
|
||||
[](https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md)
|
||||

|
||||
[](https://TheAlgorithms.github.io/C)
|
||||
[](https://github.com/TheAlgorithms/C/actions?query=workflow%3A%22Awesome+CI+Workflow%22)
|
||||
[](https://liberapay.com/TheAlgorithms)
|
||||
[](https://discord.gg/c7MnfGFGa6)
|
||||
[](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
13
REVIEWER_CODE.md
Normal 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
14
audio/CMakeLists.txt
Normal 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
216
audio/alaw.c
Normal 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;
|
||||
}
|
||||
44
client_server/CMakeLists.txt
Normal file
44
client_server/CMakeLists.txt
Normal 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
122
client_server/client.c
Normal 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
158
client_server/server.c
Normal 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;
|
||||
}
|
||||
173
client_server/tcp_full_duplex_client.c
Normal file
173
client_server/tcp_full_duplex_client.c
Normal 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;
|
||||
}
|
||||
195
client_server/tcp_full_duplex_server.c
Normal file
195
client_server/tcp_full_duplex_server.c
Normal 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;
|
||||
}
|
||||
153
client_server/tcp_half_duplex_client.c
Normal file
153
client_server/tcp_half_duplex_client.c
Normal 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;
|
||||
}
|
||||
177
client_server/tcp_half_duplex_server.c
Normal file
177
client_server/tcp_half_duplex_server.c
Normal 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;
|
||||
}
|
||||
82
client_server/udp_client.c
Normal file
82
client_server/udp_client.c
Normal 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;
|
||||
}
|
||||
89
client_server/udp_server.c
Normal file
89
client_server/udp_server.c
Normal 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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
conversions/CMakeLists.txt
Normal file
21
conversions/CMakeLists.txt
Normal 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} )
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
89
conversions/c_atoi_str_to_integer.c
Normal file
89
conversions/c_atoi_str_to_integer.c
Normal 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);
|
||||
}
|
||||
169
conversions/decimal_to_any_base.c
Normal file
169
conversions/decimal_to_any_base.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
38
conversions/decimal_to_binary_recursion.c
Normal file
38
conversions/decimal_to_binary_recursion.c
Normal 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;
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
29
conversions/decimal_to_octal_recursion.c
Normal file
29
conversions/decimal_to_octal_recursion.c
Normal 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;
|
||||
}
|
||||
133
conversions/hexadecimal_to_octal.c
Normal file
133
conversions/hexadecimal_to_octal.c
Normal 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;
|
||||
}
|
||||
119
conversions/hexadecimal_to_octal2.c
Normal file
119
conversions/hexadecimal_to_octal2.c
Normal 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;
|
||||
}
|
||||
227
conversions/infix_to_postfix.c
Normal file
227
conversions/infix_to_postfix.c
Normal 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;
|
||||
}
|
||||
}
|
||||
164
conversions/infix_to_postfix2.c
Normal file
164
conversions/infix_to_postfix2.c
Normal 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;
|
||||
}
|
||||
83
conversions/int_to_string.c
Normal file
83
conversions/int_to_string.c
Normal 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;
|
||||
}
|
||||
62
conversions/octal_to_binary.c
Normal file
62
conversions/octal_to_binary.c
Normal 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;
|
||||
}
|
||||
36
conversions/octal_to_decimal.c
Normal file
36
conversions/octal_to_decimal.c
Normal 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;
|
||||
}
|
||||
79
conversions/octal_to_hexadecimal.c
Normal file
79
conversions/octal_to_hexadecimal.c
Normal 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;
|
||||
}
|
||||
@@ -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
44
conversions/to_decimal.c
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
288
data_structures/array/carray.c
Normal file
288
data_structures/array/carray.c
Normal 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;
|
||||
}
|
||||
85
data_structures/array/carray.h
Normal file
85
data_structures/array/carray.h
Normal 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
|
||||
160
data_structures/array/carray_tests.c
Normal file
160
data_structures/array/carray_tests.c
Normal 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;
|
||||
}
|
||||
420
data_structures/binary_trees/avl_tree.c
Normal file
420
data_structures/binary_trees/avl_tree.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
797
data_structures/binary_trees/red_black_tree.c
Normal file
797
data_structures/binary_trees/red_black_tree.c
Normal 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
|
||||
235
data_structures/binary_trees/segment_tree.c
Normal file
235
data_structures/binary_trees/segment_tree.c
Normal 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;
|
||||
}
|
||||
303
data_structures/binary_trees/threaded_binary_trees.c
Normal file
303
data_structures/binary_trees/threaded_binary_trees.c
Normal 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;
|
||||
}
|
||||
316
data_structures/binary_trees/words_alphabetical.c
Normal file
316
data_structures/binary_trees/words_alphabetical.c
Normal 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;
|
||||
}
|
||||
@@ -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); }
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
13
data_structures/dynamic_array/Makefile
Normal file
13
data_structures/dynamic_array/Makefile
Normal 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
|
||||
82
data_structures/dynamic_array/dynamic_array.c
Normal file
82
data_structures/dynamic_array/dynamic_array.c
Normal 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;
|
||||
}
|
||||
27
data_structures/dynamic_array/dynamic_array.h
Normal file
27
data_structures/dynamic_array/dynamic_array.h
Normal 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
|
||||
35
data_structures/dynamic_array/main.c
Normal file
35
data_structures/dynamic_array/main.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
56
data_structures/graphs/Makefile
Normal file
56
data_structures/graphs/Makefile
Normal 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
|
||||
140
data_structures/graphs/bellman_ford.c
Normal file
140
data_structures/graphs/bellman_ford.c
Normal 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;
|
||||
}
|
||||
195
data_structures/graphs/bfs.c
Normal file
195
data_structures/graphs/bfs.c
Normal 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]; }
|
||||
124
data_structures/graphs/bfs_queue.c
Normal file
124
data_structures/graphs/bfs_queue.c
Normal 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
|
||||
134
data_structures/graphs/dfs.c
Normal file
134
data_structures/graphs/dfs.c
Normal 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");
|
||||
}
|
||||
}
|
||||
103
data_structures/graphs/dfs_recursive.c
Normal file
103
data_structures/graphs/dfs_recursive.c
Normal 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
|
||||
119
data_structures/graphs/dijkstra.c
Normal file
119
data_structures/graphs/dijkstra.c
Normal 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;
|
||||
}
|
||||
95
data_structures/graphs/euler.c
Normal file
95
data_structures/graphs/euler.c
Normal 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
|
||||
108
data_structures/graphs/floyd_warshall.c
Normal file
108
data_structures/graphs/floyd_warshall.c
Normal 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;
|
||||
}
|
||||
117
data_structures/graphs/graph.c
Normal file
117
data_structures/graphs/graph.c
Normal 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
|
||||
45
data_structures/graphs/graph.h
Normal file
45
data_structures/graphs/graph.h
Normal 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
|
||||
103
data_structures/graphs/hamiltonian.c
Normal file
103
data_structures/graphs/hamiltonian.c
Normal 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
Reference in New Issue
Block a user