算法导论

算法导论——归并排序

北慕城南 提交于 2019-11-28 21:42:59
#include<stdio.h> #define MAXN 100 //A[p,q] A[q+1,r]是两个有序数组,想办法把他们结合成一个有序数组 void merge(int A[],int p,int q,int r){ int n=0; int i=p; int j=q+1; int tmp[MAXN]; while(i<=q&&j<=r){ if(A[i]<=A[j]) tmp[n++]=A[i++]; else tmp[n++]=A[j++]; } while(i<=q) tmp[n++]=A[i++]; while(j<=r) tmp[n++]=A[j++]; int k; for(k=p;k<p+n;k++) A[k]=tmp[k-p]; } //归并排序主体 void merge_sort(int A[],int p,int r){ if(p<r){ int q=(p+r)/2; merge_sort(A,p,q); merge_sort(A,q+1,r); merge(A,p,q,r); } } int main(){ int A[]={2,56,3,7,86,1,6,43,12}; merge_sort(A,0,8); int k; for(k=0;k<=8;k++) printf("%d ",A[k]); printf("\n"); return 0; }

《算法导论》第一章——算法在计算中的应用、第二章——算法基础

和自甴很熟 提交于 2019-11-28 16:06:26
第一章——算法在计算中的应用 算法 算法就是任何良定义的计算过程,该过程取某个值或值的集合作为输入并产生某个值或值的集合作为输出。 算法分析 算法分析是理论研究,是关于计算机性能和资源利用的研究(尤其关注性能)。 比性能更重要的因素 比如有正确性、简洁性、可维护性、编程成本、稳定性、功能性、模块化、安全性、可扩展性、用户友好度等。 算法的重要性 算法将不可行变为可行。 算法是一种描述程序行为的语言。 第二章——算法基础 插入排序 伪代码 INSERTION-SORT(A) 1 for j ← 2 to n 2 do key ← A[j] 3 // Insert A[j] into the sorted sequence A[1...j-1] 4 i ← j-1 5 while i > 0 and A[i] >key 6 do A[i+1] ← A[i] 7 i ← i-1 8 A[i+1] ← key A[1…j-1]称为循环不变式:在第1~8行的for循环的每次迭代开始时,子数组A[1…j-1]由原来在A[1…j-1]中的元素组成,但已按序排列。 关于循环不变式,必须证明三条性质: 初始化:循环的第一次迭代之前,它为真。 保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真。 终止:在循环终止时,不变式为我们提供了一个有用的性质,该性质有助于证明算法是正确的。 运行时间:

算法导论第六章 堆排序

不羁岁月 提交于 2019-11-26 14:58:27
主要内容: 堆、最大堆、最小堆的基本概念 堆的操作:调整、创建、排序 采用堆实现优先级队列 基本概念 堆 ( heap )亦被称为: 优先队列 ( priority queue ) 逻辑定义: n个元素序列{k 1 ,k 2 ...k i ...k n },当且仅当满足下列关系时称之为堆: (k i <= k 2i ,k i <= k 2i+1 )或者(k i >= k 2i ,k i >= k 2i+1 ), (i = 1,2,3,4...n/2) 堆的实现通过构造 二叉堆 (binary heap),实为二叉树的一种。 性质 : 1、任意节点小于或大于它的所有后裔,最小元或最大元在堆的根上( 堆序性 )。将根节点最大的堆叫做 最大堆或大根堆 ,根节点最小的堆叫做 最小堆或小根堆 。常见的堆有二叉堆、斐波那契堆等。 2、堆总是一棵完全树。堆只需要满足父节点大于两个子节点,而子节点之间没有要求。作为一颗完全树,一层中的节点是从左到右填满的。如果一个节点没有左儿子,那么它一定没有右儿子。并且在第h层中如果存在节点,那么第h-1层必须是填满的。 堆的操作 调整堆 void adjust_max_heap_recursive(int *datas, int length, int i)//递归调用,最大堆调整 { int left,right,largest; int temp;

算法导论基础(第一~五章)

心不动则不痛 提交于 2019-11-26 14:57:54
插入排序 最好情况输入数组开始时候就是满足要求的排好序的,时间代价为 θ(n); 最坏情况输入数组是按逆序排序的,时间代价为 θ(n^2)。 归并排序 归并排序采用了算法设计中的分治法,分治法的思想是将原问题分解成n个规模较小而结构与原问题相似的小问题,递归的解决这些子问题,然后再去合并其结果,得到原问题的解。 分治模式在每一层递归上有三个步骤: 分解(divide):将原问题分解成一系列子问题。 解决(conquer):递归地解答各子问题,若子问题足够小,则直接求解。 合并(combine):将子问题的结果合并成原问题的解。 归并排序(merge sort)算法按照分治模式,操作如下: 分解:将n个元素分解成各含n/2个元素的子序列 解决:用合并排序法对两个序列递归地排序 合并:合并两个已排序的子序列以得到排序结果 算法中含有对其自身的递归调用,其运行时间可以用一个递归方程(或递归式)来表示。归并排序算法分析采用递归树进行,递归树的层数为lgn+1,每一层的时间代价是cn,整棵树的代价是cn(lgn+1)=cnlgn+cn,忽略低阶和常量c,得到结果为 θ(nlg n)。 转载于:https://www.cnblogs.com/lucas-hsueh/p/3731403.html 来源: https://blog.csdn.net/weixin_30586257/article

【算法导论】雇佣问题

你。 提交于 2019-11-26 14:25:24
首先介绍一点数学知识。 事件 A 的指示器随机变量 I { A } I\{A\} I { A } 定义为: I { A } = { 1 如 果 A 发 生 0 如 果 A 不 发 生 I\{A\} = \begin{cases} 1 \quad 如果A发生\\ 0 \quad 如果A不发生 \end{cases} I { A } = { 1 如 果 A 发 生 0 如 果 A 不 发 生 ​ 指示器随机变量的期望为: E [ I { A } ] = P r { A } E[I\{A\}] = Pr\{A\} E [ I { A } ] = P r { A } ,其中 P r { A } Pr\{A\} P r { A } 为事件A发生的概率。 期望性质:期望的和等于和的期望,即若 X = ∑ X i X = \sum{X_i} X = ∑ X i ​ , 则 E [ ∑ X i ] = ∑ E [ X i ] E[\sum{X_i}] = \sum{E[X_i]} E [ ∑ X i ​ ] = ∑ E [ X i ​ ] 雇佣问题:输入长度为n的数组 A[0, …, n-1], 其元素数值代表每个人的能力。假定初始时助手的能力为0, 且每次遇到能力高于当前助手能力的人,便辞掉当前助手,并雇佣该人. 每次雇佣需要花费费用 c h c_h c h ​ ,求总费用。 图示:假设 A =

大学四年,分享看过的优质书籍

人走茶凉 提交于 2019-11-25 19:53:13
数据结构与算法是我在大学里第一次接触到的,当时学了很多其他安卓、网页之类的,一开始就感觉纳闷,数据结构和算法学这个有啥用,再加上上的是一所野鸡大学,老师讲的也是模模糊糊,平时做项目、练习也几乎不用数据结构,所以考试应付应付就过了,也没太在意。 到了大三的时候,面临考研和就业了,突然看到学长考研的数据结构题和面试网站的要求,突然意识到数据结构和算法的重要性,真的很重要,重要的话说三遍,真的很重要,真的很重要。直到暑假出去面试,领略到了算法被面试官虐的感觉。 明人不说暗话,虽然我的专业方向是野路子出身的前端工程师,但是我对算法可谓是比前端都重视。 总结出一个结论,无论你是为了考研还是就业,越是提前学习越是优势,这是一个来自大四狗的深刻教训呀。为了能够顾忌到初学者入门、考研看哪些书籍以及面试前的准备,刷题等等吧,利用空余的时间,好好把书单整理了一遍,由浅入深,每本书的介绍以及内容涉及到了哪些,我大体都进行概括一下。 而且不同的人以及不同基础的人以及不同语言看同样的书籍难度都是不一样的,这需要根据自己的基础以及不同编程语言来记性选择,废话不多少,从入门书籍开始推荐。 一、入门类 要想学好数据结构和算法,首先我们要对它产生兴趣,就像是对你女朋友一样,产生兴趣,产生浓厚的兴趣,直接去看那种稍微难的数据结构书,会更加降低你的自信息,所以要选择一本产生兴趣的书籍,gongzhonghao