《數據結構與算法分析》學習筆記-第一章-引論

自述

自從工做以後,就沒有再寫博客了,一方面是由於本身初入職場還不能很好的適應職場生活。另外一方面也是對前途有些不知所措。如今工做已經快三年了,我慢慢找到了本身的節奏,也許仍是有不少不成熟的地方,可是我已經想開啦。作本身真正喜歡的事就行了,遵循本身的心裏。在職場的這些年我寫了不少筆記,可是沒有時間整理出來,後面慢慢都會發表出來分享給你們。感受本身在技術上仍是有不少不足,有不少基礎的東西掌握的仍是很差呀。因此想踏踏實實的從新學習這些基本知識。包括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
相關文章
相關標籤/搜索