forked from krahets/hello-algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add interation.c recursion.c simple_hash.c binary_search_edge.c binar…
…y_search_insertion.c in C codes. (krahets#731) * fix(codes/cpp): Memory leak fix: the space was not freed when pop removed the element. * fix(codes/cpp): Fix access error when printArray(arr, 0) * Update PrintUtil.hpp * fix(codes/c): Fix some errors of cmake build * feat(codes/c): Add hashing_search.c * styles(codes/c): Modify function description * styles(codes/c): Modify binary_search.c code style * fix(codes/c): Fix the problem in binary_tree_bfs.c and the problem that the memory is not released. * feat: Add preorder_traversal_i_compact.c * feat(codes/c): Add head_sort.c * feat(codes/c): Add bucket_sort.c * feat(codes/c): Add binary_search_edge.c * fix(codes/c): Add programs that are not managed by cmake (c code) * feat(codes/c): Add selection_sort.c * style(codes/c): Change swap in selection_sort.c to `selectionSort` * styles(codes/c): Change style. * fix(codes/c): Fix some formatting errors and temporarily remove backtracking chapters * fix(codes/c): Fix space_complexity.c build error. * feat(codes/c): Add array_binary_tree.c * feat(code/c): Update push_back and pop_back in vector.h * styles(codes/c): Adjust format. * feat(codes/c): Add `interation.c ` `recursion.c` `simple_hash.c` `binary_search_edge.c` `binary_search_insertion.c` in C codes. --------- Co-authored-by: Yudong Jin <[email protected]>
- Loading branch information
Showing
8 changed files
with
346 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
add_executable(time_complexity time_complexity.c) | ||
add_executable(worst_best_time_complexity worst_best_time_complexity.c) | ||
add_executable(space_complexity space_complexity.c) | ||
add_executable(space_complexity space_complexity.c) | ||
add_executable(iteration iteration.c) | ||
add_executable(recursion recursion.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* File: iteration.c | ||
* Created Time: 2023-09-09 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* for 循环 */ | ||
int forLoop(int n) { | ||
int res = 0; | ||
// 循环求和 1, 2, ..., n-1, n | ||
for (int i = 1; i <= n; ++i) { | ||
res += i; | ||
} | ||
return res; | ||
} | ||
|
||
/* while 循环 */ | ||
int whileLoop(int n) { | ||
int res = 0; | ||
int i = 1; // 初始化条件变量 | ||
// 循环求和 1, 2, ..., n-1, n | ||
while (i <= n) { | ||
res += i; | ||
i++; // 更新条件变量 | ||
} | ||
return res; | ||
} | ||
|
||
/* while 循环(两次更新) */ | ||
int whileLoopII(int n) { | ||
int res = 0; | ||
int i = 1; // 初始化条件变量 | ||
// 循环求和 1, 4, ... | ||
while (i <= n) { | ||
res += i; | ||
// 更新条件变量 | ||
i++; | ||
i *= 2; | ||
} | ||
return res; | ||
} | ||
|
||
/* 双层 for 循环 */ | ||
char *nestedForLoop(int n) { | ||
// n * n 为对应点数量,"(i, j), " 对应字符串长最大为 6+10*2,加上最后一个空字符 \0 的额外空间 | ||
int size = n * n * 26 + 1; | ||
char *res = malloc(size * sizeof(char)); | ||
|
||
// 循环 i = 1, 2, ..., n-1, n | ||
for (int i = 1; i <= n; ++i) { | ||
// 循环 j = 1, 2, ..., n-1, n | ||
for (int j = 1; j <= n; ++j) { | ||
char tmp[26]; | ||
snprintf(tmp, sizeof(tmp), "(%d, %d), ", i, j); | ||
strncat(res, tmp, size - strlen(res) - 1); | ||
} | ||
} | ||
return res; | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int n = 5; | ||
int res; | ||
|
||
res = forLoop(n); | ||
printf("\nfor 循环的求和结果 res = %d\n", res); | ||
|
||
res = whileLoop(n); | ||
printf("\nwhile 循环的求和结果 res = %d\n", res); | ||
|
||
res = whileLoopII(n); | ||
printf("\nwhile 循环(两次更新)求和结果 res = %d\n", res); | ||
|
||
char *resStr = nestedForLoop(n); | ||
printf("\n双层 for 循环的遍历结果 %s\r\n", resStr); | ||
free(resStr); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* File: recursion.c | ||
* Created Time: 2023-09-09 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 递归 */ | ||
int recur(int n) { | ||
// 终止条件 | ||
if (n == 1) | ||
return 1; | ||
// 递:递归调用 | ||
int res = recur(n - 1); | ||
// 归:返回结果 | ||
return n + res; | ||
} | ||
|
||
/* 尾递归 */ | ||
int tailRecur(int n, int res) { | ||
// 终止条件 | ||
if (n == 0) | ||
return res; | ||
// 尾递归调用 | ||
return tailRecur(n - 1, res + n); | ||
} | ||
|
||
/* 斐波那契数列:递归 */ | ||
int fib(int n) { | ||
// 终止条件 f(1) = 0, f(2) = 1 | ||
if (n == 1 || n == 2) | ||
return n - 1; | ||
// 递归调用 f(n) = f(n-1) + f(n-2) | ||
int res = fib(n - 1) + fib(n - 2); | ||
// 返回结果 f(n) | ||
return res; | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int n = 5; | ||
int res; | ||
|
||
res = recur(n); | ||
printf("\n递归函数的求和结果 res = %d\n", res); | ||
|
||
res = tailRecur(n, 0); | ||
printf("\n尾递归函数的求和结果 res = %d\n", res); | ||
|
||
res = fib(n); | ||
printf("\n斐波那契数列的第 %d 项为 %d\n", n, res); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
add_executable(array_hash_map array_hash_map.c) | ||
add_executable(simple_hash simple_hash.c) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* File: simple_hash.c | ||
* Created Time: 2023-09-09 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 加法哈希 */ | ||
int addHash(char *key) { | ||
long long hash = 0; | ||
const int MODULUS = 1000000007; | ||
for (int i = 0; i < strlen(key); i++) { | ||
hash = (hash + (unsigned char)key[i]) % MODULUS; | ||
} | ||
return (int)hash; | ||
} | ||
|
||
/* 乘法哈希 */ | ||
int mulHash(char *key) { | ||
long long hash = 0; | ||
const int MODULUS = 1000000007; | ||
for (int i = 0; i < strlen(key); i++) { | ||
hash = (31 * hash + (unsigned char)key[i]) % MODULUS; | ||
} | ||
return (int)hash; | ||
} | ||
|
||
/* 异或哈希 */ | ||
int xorHash(char *key) { | ||
int hash = 0; | ||
const int MODULUS = 1000000007; | ||
|
||
for (int i = 0; i < strlen(key); i++) { | ||
hash ^= (unsigned char)key[i]; | ||
} | ||
return hash & MODULUS; | ||
} | ||
|
||
/* 旋转哈希 */ | ||
int rotHash(char *key) { | ||
long long hash = 0; | ||
const int MODULUS = 1000000007; | ||
for (int i = 0; i < strlen(key); i++) { | ||
hash = ((hash << 4) ^ (hash >> 28) ^ (unsigned char)key[i]) % MODULUS; | ||
} | ||
|
||
return (int)hash; | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
char *key = "Hello dsad3241241dsa算123法"; | ||
|
||
int hash = addHash(key); | ||
printf("加法哈希值为 %d\n", hash); | ||
|
||
hash = mulHash(key); | ||
printf("乘法哈希值为 %d\n", hash); | ||
|
||
hash = xorHash(key); | ||
printf("异或哈希值为 %d\n", hash); | ||
|
||
hash = rotHash(key); | ||
printf("旋转哈希值为 %d\n", hash); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
add_executable(binary_search binary_search.c) | ||
add_executable(two_sum two_sum.c) | ||
add_executable(binary_search_edge binary_search_edge.c) | ||
add_executable(hashing_search hashing_search.c) | ||
add_executable(linear_search linear_search.c) | ||
add_executable(linear_search linear_search.c) | ||
add_executable(binary_search_edge binary_search_edge.c) | ||
add_executable(binary_search_insertion binary_search_insertion.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/** | ||
* File: binary_search_edge.c | ||
* Created Time: 2023-09-09 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 二分查找插入点(存在重复元素) */ | ||
int binarySearchInsertion(int *nums, int numSize, int target) { | ||
int i = 0, j = numSize - 1; // 初始化双闭区间 [0, n-1] | ||
while (i <= j) { | ||
int m = i + (j - i) / 2; // 计算中点索引 m | ||
if (nums[m] < target) { | ||
i = m + 1; // target 在区间 [m+1, j] 中 | ||
} else { | ||
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中 | ||
} | ||
} | ||
// 返回插入点 i | ||
return i; | ||
} | ||
|
||
/* 二分查找最左一个 target */ | ||
int binarySearchLeftEdge(int *nums, int numSize, int target) { | ||
// 等价于查找 target 的插入点 | ||
int i = binarySearchInsertion(nums, numSize, target); | ||
// 未找到 target ,返回 -1 | ||
if (i == numSize || nums[i] != target) { | ||
return -1; | ||
} | ||
// 找到 target ,返回索引 i | ||
return i; | ||
} | ||
|
||
/* 二分查找最右一个 target */ | ||
int binarySearchRightEdge(int *nums, int numSize, int target) { | ||
// 转化为查找最左一个 target + 1 | ||
int i = binarySearchInsertion(nums, numSize, target + 1); | ||
// j 指向最右一个 target ,i 指向首个大于 target 的元素 | ||
int j = i - 1; | ||
// 未找到 target ,返回 -1 | ||
if (j == -1 || nums[j] != target) { | ||
return -1; | ||
} | ||
// 找到 target ,返回索引 j | ||
return j; | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
// 包含重复元素的数组 | ||
int nums[] = {1, 3, 6, 6, 6, 6, 6, 10, 12, 15}; | ||
printf("\n数组 nums = "); | ||
printArray(nums, sizeof(nums) / sizeof(nums[0])); | ||
|
||
// 二分查找左边界和右边界 | ||
int targets[] = {6, 7}; | ||
for (int i = 0; i < sizeof(targets) / sizeof(targets[0]); i++) { | ||
int index = binarySearchLeftEdge(nums, sizeof(nums) / sizeof(nums[0]), targets[i]); | ||
printf("最左一个元素 %d 的索引为 %d\n", targets[i], index); | ||
index = binarySearchRightEdge(nums, sizeof(nums) / sizeof(nums[0]), targets[i]); | ||
printf("最右一个元素 %d 的索引为 %d\n", targets[i], index); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* File: binary_search_insertion.c | ||
* Created Time: 2023-09-09 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 二分查找插入点(无重复元素) */ | ||
int binarySearchInsertionSimple(int *nums, int numSize, int target) { | ||
int i = 0, j = numSize - 1; // 初始化双闭区间 [0, n-1] | ||
while (i <= j) { | ||
int m = i + (j - i) / 2; // 计算中点索引 m | ||
if (nums[m] < target) { | ||
i = m + 1; // target 在区间 [m+1, j] 中 | ||
} else if (nums[m] > target) { | ||
j = m - 1; // target 在区间 [i, m-1] 中 | ||
} else { | ||
return m; // 找到 target ,返回插入点 m | ||
} | ||
} | ||
// 未找到 target ,返回插入点 i | ||
return i; | ||
} | ||
|
||
/* 二分查找插入点(存在重复元素) */ | ||
int binarySearchInsertion(int *nums, int numSize, int target) { | ||
int i = 0, j = numSize - 1; // 初始化双闭区间 [0, n-1] | ||
while (i <= j) { | ||
int m = i + (j - i) / 2; // 计算中点索引 m | ||
if (nums[m] < target) { | ||
i = m + 1; // target 在区间 [m+1, j] 中 | ||
} else if (nums[m] > target) { | ||
j = m - 1; // target 在区间 [i, m-1] 中 | ||
} else { | ||
j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中 | ||
} | ||
} | ||
// 返回插入点 i | ||
return i; | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
// 无重复元素的数组 | ||
int nums1[] = {1, 3, 6, 8, 12, 15, 23, 26, 31, 35}; | ||
printf("\n数组 nums = "); | ||
printArray(nums1, sizeof(nums1) / sizeof(nums1[0])); | ||
// 二分查找插入点 | ||
int targets1[] = {6, 9}; | ||
for (int i = 0; i < sizeof(targets1) / sizeof(targets1[0]); i++) { | ||
int index = binarySearchInsertionSimple(nums1, sizeof(nums1) / sizeof(nums1[0]), targets1[i]); | ||
printf("元素 %d 的插入点的索引为 %d\n", targets1[i], index); | ||
} | ||
|
||
// 包含重复元素的数组 | ||
int nums2[] = {1, 3, 6, 6, 6, 6, 6, 10, 12, 15}; | ||
printf("\n数组 nums = "); | ||
printArray(nums2, sizeof(nums2) / sizeof(nums2[0])); | ||
// 二分查找插入点 | ||
int targets2[] = {2, 6, 20}; | ||
for (int i = 0; i < sizeof(targets2) / sizeof(int); i++) { | ||
int index = binarySearchInsertion(nums2, sizeof(nums2) / sizeof(nums2[0]), targets2[i]); | ||
printf("元素 %d 的插入点的索引为 %d\n", targets2[i], index); | ||
} | ||
|
||
return 0; | ||
} |