《数据结构与算法分析》学习笔记-第一章-引论

自述

自从工做以后,就没有再写博客了,一方面是由于本身初入职场还不能很好的适应职场生活。另外一方面也是对前途有些不知所措。如今工做已经快三年了,我慢慢找到了本身的节奏,也许仍是有不少不成熟的地方,可是我已经想开啦。作本身真正喜欢的事就行了,遵循本身的心里。在职场的这些年我写了不少笔记,可是没有时间整理出来,后面慢慢都会发表出来分享给你们。感受本身在技术上仍是有不少不足,有不少基础的东西掌握的仍是很差呀。因此想踏踏实实的从新学习这些基本知识。包括C语言基础、数据结构与算法、操做系统。还但愿能更进一步,掌握python、java。学习并整理设计模式、网络、文件系统、内存管理、多线程开发等等。请你们敬请期待吧。好了,话很少说。
我,CrazyCatJack又回来啦!html

1.1 本书讨论的内容

  • 一个能够运行的程序并不够,若是在巨大的数据集运行,运行时间就变成了至关重要的问题。
  • 学习如何估计程序的运行时间,尤为是在未编码的状况下预估两个算法的运行时间。
  • 学习完全改进程序速度和肯定程序瓶颈的方法,这些方法使咱们可以找到须要大力优化的代码段

书上上来就提出了一个算法问题,并提出了两个解决方案,我实现了具体的代码,你们能够尝试将这两个文件编译后,查看打印了解具体的执行过程。还能够在linux命令行下使用time ./a.out 命令查看两个程序的执行时间,进行比较。我将代码上传到了github上。https://github.com/CrazyCatJack/structureAlgorithmjava

设有一组N个数而要肯定其中第K个最大的数。两种方法实现以下:python

  • 法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也建议你们亲自演算一下,本身演算出来的才算是本身的东西。





linux

1.2.5 证实方法

1)概括法

  1. 基准情形:肯定某些小值得正确性
  2. 概括假设:假设定理对于小于有限数k的全部状况成立,用这个定理证实k+1也是成立的

2) 反证法

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




git

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\n", F(1), F(2), F(3));
}

打印输出数github

// 本书例程
#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网络

原始博文连接地址:http://www.javashuo.com/article/p-wieesloe-ek.html


第一章到此结束,接下来会进行课后习题的讲解。但愿能给正在学习数据结构与算法的朋友带来帮助。咱们一块儿来构筑一个更好的世界,谢谢你们的支持!

CrazyCatJack
相关文章
相关标签/搜索