《数据结构与算法分析》学习笔记-第一章-引论
自述
自从工作之后,就没有再写博客了,一方面是因为自己初入职场还不能很好的适应职场生活。另一方面也是对前途有些不知所措。现在工作已经快三年了,我慢慢找到了自己的节奏,也许还是有很多不成熟的地方,但是我已经想开啦。做自己真正喜欢的事就好了,遵循自己的内心。在职场的这些年我写了很多笔记,但是没有时间整理出来,后面慢慢都会发表出来分享给大家。感觉自己在技术上还是有很多不足,有很多基础的东西掌握的还是不好呀。所以想踏踏实实的重新学习这些基本知识。包括C语言基础、数据结构与算法、操作系统。还希望能更进一步,掌握python、java。学习并整理设计模式、网络、文件系统、内存管理、多线程开发等等。请大家敬请期待吧。好了,话不多说。
我,CrazyCatJack又回来啦!
1.1 本书讨论的内容
- 一个可以运行的程序并不够,如果在巨大的数据集运行,运行时间就变成了相当重要的问题。
- 学习如何估计程序的运行时间,尤其是在未编码的情况下预估两个算法的运行时间。
- 学习彻底改进程序速度和确定程序瓶颈的方法,这些方法使我们能够找到需要大力优化的代码段
书上上来就提出了一个算法问题,并提出了两个解决方案,我实现了具体的代码,大家可以尝试将这两个文件编译后,查看打印了解具体的执行过程。还可以在linux命令行下使用time ./a.out 命令查看两个程序的执行时间,进行比较。我将代码上传到了github上。https://github.com/CrazyCatJack/structureAlgorithm
设有一组N个数而要确定其中第K个最大的数。两种方法实现如下:
- 法1:将N个数读进一个数组,再通过冒泡排序进行递减排序,最后返回k位置上的元素
// SPDX-License-Identifier: GPL-2.0-only
/*
* sort1.c
*
* Copyright (C) 2020 xuri.All rights reserved.
*/
#include <stdio.h>
#define ARRAY_SIZE 1000
#define MAXKNUM 500
int sortK(int *array, int arraySize, int MaxKnum)
{
if (array == NULL || arraySize <= 0 || MaxKnum <= 0) {
return -1;
}
int subscript, sortTimes;
for (sortTimes = 0; sortTimes < arraySize - 1; sortTimes++) {
for (subscript = 1; subscript < arraySize - sortTimes; subscript++) {
if (array[subscript] > array[subscript - 1]) {
int temp;
temp = array[subscript];
array[subscript] = array[subscript - 1];
array[subscript - 1] = temp;
}
}
#if 0
printf("NO %d sort:", sortTimes);
int prtCnt;
for (prtCnt = 0; prtCnt < arraySize; prtCnt++) {
printf("%d ", array[prtCnt]);
}
printf("\n");
#endif
}
return array[MaxKnum - 1];
}
void main()
{
int array[ARRAY_SIZE];
int assignCnt;
for (assignCnt = 0; assignCnt < ARRAY_SIZE; assignCnt++) {
array[assignCnt] = assignCnt;
}
int K = sortK(array, ARRAY_SIZE, MAXKNUM);
printf("K = %d\n", K);
}
- 法2:可以先把前K个元素读入数组并以递减的顺序进行排序。再将剩下的元素逐个读入,用新元素与当前数组中第K个元素进行比较,如果它小于则忽略,如果它大于,则将它放到数组中正确的位置上,同时挤出一个元素。当算法终止,第k个元素就是正确答案
// SPDX-License-Identifier: GPL-2.0-only
/*
* sort2.c
*
* Copyright (C) 2020 xuri.All rights reserved.
*/
#include <stdio.h>
#define ARRAY_SIZE 1000
#define MAXKNUM 500
void MaoPaoSort(int *localArray, int MaxKnum)
{
int subscript, sortTimes;
for (sortTimes = 0; sortTimes < MaxKnum - 1; sortTimes++) {
for (subscript = 1; subscript < MaxKnum - sortTimes; subscript++) {
if (localArray[subscript] > localArray[subscript - 1]) {
int temp;
temp = localArray[subscript];
localArray[subscript] = localArray[subscript - 1];
localArray[subscript - 1] = temp;
}
}
#if 0
printf("NO %d sort:", sortTimes);
int prtCnt;
for (prtCnt = 0; prtCnt < MaxKnum; prtCnt++) {
printf("%d ", localArray[prtCnt]);
}
printf("\n");
#endif
}
}
int sortK(int *array, int arraySize, int MaxKnum)
{
if (array == NULL || arraySize <= 0 || MaxKnum <= 0) {
return -1;
}
// assign MaxKnum number in localArray
int localArray[MaxKnum];
int assignCnt;
for (assignCnt = 0; assignCnt < MaxKnum; assignCnt++) {
localArray[assignCnt] = array[assignCnt];
}
// sort localArray
MaoPaoSort(localArray, MaxKnum);
// get remain number in array add to in localArray for sort
for (assignCnt = MaxKnum; assignCnt < arraySize; assignCnt++) {
if (array[assignCnt] > localArray[MaxKnum - 1]) {
int temp = 0;
temp = array[assignCnt];
array[assignCnt] = localArray[MaxKnum - 1];
localArray[MaxKnum - 1] = temp;
MaoPaoSort(localArray, MaxKnum);
}
}
return localArray[MaxKnum - 1];
}
void main()
{
int array[ARRAY_SIZE];
int assignCnt;
for (assignCnt = 0; assignCnt < ARRAY_SIZE; assignCnt++) {
array[assignCnt] = assignCnt;
}
int K = sortK(array, ARRAY_SIZE, MAXKNUM);
printf("K = %d\n", K);
}
1.2 数学知识复习
因为数学格式很难打出来,所以干脆手写啦,这里委屈大家看我的丑字了-_-||
好记性不如烂笔头,CCJ也建议大家亲自演算一下,自己演算出来的才算是自己的东西。
1.2.5 证明方法
1)归纳法
- 基准情形:确定某些小值得正确性
- 归纳假设:假设定理对于小于有限数k的所有情况成立,用这个定理证明k+1也是成立的
2) 反证法
通过假设定理不成立,然后证明该假设导致某个已知的性质而不成立,从而说明原假设是错误的
1.3 递归简论
- 当一个函数用它自己来定义时,就称为是递归的。不是所有的数学递归函数都能有效的(或正确的)由C的递归模拟来实现。
- C中的递归函数若无基准情况,也是毫无意义的
- 跟踪挂起的函数调用(即这些调用已经开始但是正等待着递归调用来完成)以及它们中变量的记录工作都是由计算机自动完成的。递归调用将反复进行直到基准情形出现
- 递归组成
- 基准情形:不用递归就能求解的情形
- 不断推进:对于需要递归求解的情形,递归调用必须总能朝着产生基准情形的方向推进
- 设计法则:假设所有的递归调用都能运行。不必追踪所有的递归调用,很困难且没必要。使用递归能简化算法设计并设计出简洁的代码
- 合成效益法则: 在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。例如计算斐波那契数列用递归就不是很好的选择
// 本书例程
#include <stdio.h>
int F(int x)
{
if (0 == x) {
return 0;
} else (0 > x) {
return (2 * F(x-1) + x * x);
}
}
void main()
{
printf("F(1)=%d, F(2)=%d, F(3)=%d\n", F(1), F(2), F(3));
}
打印输出数
// 本书例程
#include <stdio.h>
int printDigit(int x)
{
if (x >= 10) {
printDigit((x / 10));
}
printf("%d", (x % 10));
}
void main()
{
int a = 123456789;
printDigit(a);
}
敬告:
本文原创,欢迎大家学习转载_
转载请在显著位置注明:
博主ID:CrazyCatJack
原始博文链接地址:https://www.cnblogs.com/CrazyCatJack/p/12545591.html
第一章到此结束,接下来会进行课后习题的讲解。希望能给正在学习数据结构与算法的朋友带来帮助。我们一起来构筑一个更好的世界!
觉得好的话请帮忙点个推荐,谢谢大家的支持!嘿嘿~