zoukankan      html  css  js  c++  java
  • 《数据结构与算法分析》学习笔记-第一章-引论

    自述

    自从工作之后,就没有再写博客了,一方面是因为自己初入职场还不能很好的适应职场生活。另一方面也是对前途有些不知所措。现在工作已经快三年了,我慢慢找到了自己的节奏,也许还是有很多不成熟的地方,但是我已经想开啦。做自己真正喜欢的事就好了,遵循自己的内心。在职场的这些年我写了很多笔记,但是没有时间整理出来,后面慢慢都会发表出来分享给大家。感觉自己在技术上还是有很多不足,有很多基础的东西掌握的还是不好呀。所以想踏踏实实的重新学习这些基本知识。包括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("
    "); 
    #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
    ", 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("
    "); 
    #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
    ", K);	
    }
    

    1.2 数学知识复习

    因为数学格式很难打出来,所以干脆手写啦,这里委屈大家看我的丑字了-_-||
    好记性不如烂笔头,CCJ也建议大家亲自演算一下,自己演算出来的才算是自己的东西。





    1.2.5 证明方法

    1)归纳法

    1. 基准情形:确定某些小值得正确性
    2. 归纳假设:假设定理对于小于有限数k的所有情况成立,用这个定理证明k+1也是成立的

    2) 反证法

    通过假设定理不成立,然后证明该假设导致某个已知的性质而不成立,从而说明原假设是错误的




    1.3 递归简论

    1. 当一个函数用它自己来定义时,就称为是递归的。不是所有的数学递归函数都能有效的(或正确的)由C的递归模拟来实现。
    2. C中的递归函数若无基准情况,也是毫无意义的
    3. 跟踪挂起的函数调用(即这些调用已经开始但是正等待着递归调用来完成)以及它们中变量的记录工作都是由计算机自动完成的。递归调用将反复进行直到基准情形出现
    4. 递归组成
      • 基准情形:不用递归就能求解的情形
      • 不断推进:对于需要递归求解的情形,递归调用必须总能朝着产生基准情形的方向推进
      • 设计法则:假设所有的递归调用都能运行。不必追踪所有的递归调用,很困难且没必要。使用递归能简化算法设计并设计出简洁的代码
      • 合成效益法则: 在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。例如计算斐波那契数列用递归就不是很好的选择
    // 本书例程
    #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
    ", 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


    第一章到此结束,接下来会进行课后习题的讲解。希望能给正在学习数据结构与算法的朋友带来帮助。我们一起来构筑一个更好的世界!
    觉得好的话请帮忙点个推荐,谢谢大家的支持!嘿嘿~

    CrazyCatJack
  • 相关阅读:
    redis后台启动配置
    Go匿名函数
    Java中的ExceptionInInitializerError异常及解决方法
    数据库备份工具mysqldump重要参数详解
    Nginx初识
    找不到或无法加载主类
    类加载机制与反射(二)
    JavaScript 数据结构与算法之美
    JavaScript 数据结构与算法之美
    JavaScript 数据结构与算法之美
  • 原文地址:https://www.cnblogs.com/CrazyCatJack/p/12545591.html
Copyright © 2011-2022 走看看