search1.c
#include <cs50.h>
#include <stdio.h>
int main()
{
int numbers[] = {20, 500, 10, 5, 100, 1, 50};
int n = get_int("Number: ");
int length = sizeof(numbers) / sizeof(numbers[0]);
for (int i = 0; i < length; i++)
{
if (numbers[i] == n)
{
printf("Found\n");
return 0;
}
}
printf("Not Found.\n");
return 1;
}
search2.c
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string strings[] = {"battleship", "boot", "cannon", "iron", "thimble", "top hat"};
string s = get_string("String: ");
for (int i = 0; i < 6; i++)
{
//strcmp 用于比较两个字符串是否相等
if (strcmp(strings[i], s) == 0)
{
printf("Found.\n");
return 0;
}
}
printf("Not Found.\n");
return 1;//比如自动化运行程序, echo $ 可以帮我们判断程序是否正常与运行
}
phonebook.c
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string names[] = {"aaa", "bbb"};//中文strcmp好像无法识别
string numbers[] = {"111", "222"};
string name = get_string("Name: ");
for (int i = 0; i < 2; i++)
{
if (strcmp(names[i], name) == 0)
{
printf("Found:%s\n", numbers[i]);
return 0;
}
}
printf("Not Found.");
return 1;
}
phonebook2.c
//结构体
#include <cs50.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
string name;
string number;
}person;
int main(void)
{
person people[2];
people[0].name = "Carter";
people[0].number = "111";
people[1].name = "David";
people[1].number = "222";
string name = get_string("Name: ");
for (int i = 0; i < 2; i++)
{
if (strcmp(people[i].name, name) == 0)
{
printf("Found:%s\n", people[i].number);
return 0;
}
}
printf("Not Found.");
return 1;
}
iteration.c
#include <cs50.h>
#include <stdio.h>
void draw(int n);
int main(void)
{
int height = get_int("Height: ");
draw(height);
return 0;
}
void draw(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i+1; j++)
{
printf("#");
}
printf("\n");
}
}
recursion.c
#include <cs50.h>
#include <stdio.h>
void draw(int n);
int main(void)
{
int height = get_int("Height: ");
draw(height);
return 0;
}
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
selection_sort.c
//选择排序
#include <stdio.h>
int main()
{
int nums[] = {9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int length = sizeof(nums) / sizeof(nums[0]);
int minIndex, temp;
for (int i = 0; i < length - 1; i++)
{
// 假设当前位置的元素是最小的
minIndex = i;
// 在未排序的部分中找到最小元素的下标
for (int j = i + 1; j < length; j++)
{
if (nums[j] < nums[minIndex])
{
minIndex = j;
}
}
// 交换找到的最小元素和当前位置的元素
temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
printf("排序后数组: ");
for (int i = 0; i < length; i++)
{
printf("%d ", nums[i]);
}
printf("\n");
return 0;
}
bubble_sort.c
//冒泡排序
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int nums[] = {9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int length = sizeof(nums) / sizeof(nums[0]);
int count = 0;
for (int i = 0; i < length - 1; i++)
{
int swapped = 0; // 标志,记录是否有元素交换
for (int j = 0; j < length - i - 1; j++)
{
if (nums[j] > nums[j + 1])
{
// 交换相邻元素
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
swapped = 1;
}
count++; // 统计次数
}
if (!swapped)
{
// 如果在这一轮没有发生交换,说明数组已经有序,提前结束排序
break;
}
}
printf("排序后数组: ");
for (int k = 0; k < length; k++)
{
printf("%i ", nums[k]);
}
printf("\n");
printf("统计次数:%i\n", count);
return 0;
}
merge_sort.c
//归并排序
#include <stdio.h>
void merge(int arr[], int left, int mid, int right);
void mergeSort(int arr[], int left, int right);
void printArray(int arr[], int size);
int main()
{
int arr[] = {9, 8, 6, 7, 5, 0, 1, 2, 3, 4};
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("原始数组: \n");
printArray(arr, arr_size);
// 调用归并排序函数
mergeSort(arr, 0, arr_size - 1);
printf("排序数组: \n");
printArray(arr, arr_size);
}
// 合并两个有序数组
void merge(int arr[], int left, int mid, int right)
{
// 计算左右两个数组的长度
int n_left = mid - left + 1;
int n_right = right - mid;
// 创建临时数组
int L[n_left], R[n_right];
// 拷贝数据到临时数组 L[] 和 R[]
for (int i = 0; i < n_left; i++)
{
L[i] = arr[left + i];
}
for (int j = 0; j < n_right; j++)
{
R[j] = arr[mid + 1 + j];
}
// 合并临时数到 arr[left..right]
int i = 0;
int j = 0;
int k = left;
while (i < n_left && j < n_right)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
// 拷贝 L[] 的剩余元素(如果有)
while (i < n_left)
{
arr[k] = L[i];
i++;
k++;
}
// 拷贝 R[] 的剩余元素(如果有)
while (j < n_right)
{
arr[k] = R[j];
j++;
k++;
}
}
// 归并排序的主函数
void mergeSort(int arr[], int left, int right)
{
if (left < right)
{
// 计算中间点
int mid = left + (right - left) / 2;
// 递归排序左半部分
mergeSort(arr, left, mid);
// 递归排序右半部分
mergeSort(arr, mid + 1, right);
// 合并已排序的两部分
merge(arr, left, mid, right);
}
}
// 打印数组元素
void printArray(int arr[], int size)
{
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
qiuck_sort.c
//快速排序
#include<stdio.h>
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
/*设置坑位x,作为标记值*/
int i = l, j = r, x = s[l];
/*让左边的比标记值小,右边的比标记值大*/
while (i < j)
{
/*找到右边比标记值小的*/
while (x <= s[j] && i < j)
{
j--;
}
s[i] = s[j];
/*找到左边比标记值大的*/
while (x >= s[i] && i < j)
{
i++;
}
s[j] = s[i];
}
/*填回坑位,s[i]左边的都是小的,右边都是大的*/
s[i] = x;
/*排序标记值间隔开的两个区间*/
quick_sort(s, l, i - 1);
quick_sort(s, i + 1, r);
}
}
int main()
{
int s[] = { 2,8,5,6,3,9,4,0,7,1 };
int length;
/*计算数组长度*/
length = sizeof(s) / sizeof(s[0]);
/*排序*/
quick_sort(s, 0, length - 1);
/*遍历*/
for (int i = 0; i < length; i++)
{
printf("%-2d", s[i]);
}
printf("\n");
return 0;
}
归并排序与快速排序区别
-
排序算法不同:
- 第一段代码实现了快速排序,使用了分治的思想,通过选取一个基准元素,将数组分成左右两部分,递归地对这两部分进行排序。
- 第二段代码实现了归并排序,也是一种分治算法,通过将数组划分为两个子数组,分别排序后再合并。
-
实现细节不同:
- 快速排序的核心思想是通过一趟排序将数组分成两部分,不需要额外的辅助数组。它通过挖坑填数的方式进行元素交换。
- 归并排序在合并两个有序数组时需要额外的空间,通常使用临时数组。
-
稳定性:
- 归并排序是一种稳定的排序算法,相同元素的相对顺序在排序前后不会改变。
- 快速排序在实现时可能会对相同元素的相对顺序进行改变,因此在某些实现中可能是不稳定的。
-
时间复杂度:
- 快速排序的平均时间复杂度为 O(n log n),最坏情况下为 O(n^2)。
- 归并排序的时间复杂度同样为 O(n log n),但由于需要额外的空间,空间复杂度相对较高。
recursive_atoi.c
//递归实现atoi功能
#include <stdio.h>
#include <cs50.h>
#include <string.h>
long atoi(const char S[]);
long atoi_recursive(const char S[], int i);
int main()
{
string nums = get_string("Enter a positive integer: ");
printf("%ld\n", atoi(nums));
return 0;
}
long atoi(const char S[])
{
int i = 0, sign = 1;
int length = strlen(S);
// skip white space characters
while (S[i] == ' ' || S[i] == '\n' || S[i] == '\t')
{
i++;
}
// note sign of the number
if (S[i] == '+' || S[i] == '-')
{
if (S[i] == '-')
{
sign = -1;
}
i++;
}
return atoi_recursive(S, length-1) * sign;
}
long atoi_recursive(const char S[], int i)
{
// 基本情况:如果当前字符是字符串的结束符,则返回0
if (i < 0 || S[i] == '\0')
{
return 0;
}
// 将字符转换为数字
if (S[i] >= '0' && S[i] <= '9')
{
return (S[i] - '0') + atoi_recursive(S, i - 1) * 10;
}
else
{
// 如果遇到非数字字符,可以选择在这里处理错误或采取其他措施
// 这里简单地返回 0
return 0;
}
}
temps.c
//排序练习
// 练习使用结构体
// 练习应用排序算法
#include <cs50.h>
#include <stdio.h>
#define NUM_CITIES 10
typedef struct
{
string city;
int temp;
} avg_temp;
avg_temp temps[NUM_CITIES];
void sort_cities(void);
int main(void)
{
temps[0].city = "Austin";
temps[0].temp = 97;
temps[1].city = "Boston";
temps[1].temp = 82;
temps[2].city = "Chicago";
temps[2].temp = 85;
temps[3].city = "Denver";
temps[3].temp = 90;
temps[4].city = "Las Vegas";
temps[4].temp = 105;
temps[5].city = "Los Angeles";
temps[5].temp = 82;
temps[6].city = "Miami";
temps[6].temp = 97;
temps[7].city = "New York";
temps[7].temp = 85;
temps[8].city = "Phoenix";
temps[8].temp = 107;
temps[9].city = "San Francisco";
temps[9].temp = 66;
sort_cities();
printf("\n七月份城市的平均温度\n\n");
for (int i = 0; i < NUM_CITIES; i++)
{
printf("%s: %i\n", temps[i].city, temps[i].temp);
}
}
// TODO: 按温度降序对城市进行排序
void sort_cities(void)
{
// Add your code here
avg_temp temp;
for (int i = 0; i < NUM_CITIES - 1; i++)
{
for (int k = i + 1; k < NUM_CITIES; k++)
{
if (temps[i].temp > temps[k].temp)
{
temp = temps[i];
temps[i] = temps[k];
temps[k] = temp;
}
}
}
}