一日一文(1)

来源:互联网 发布:营销网络地图代码 编辑:程序博客网 时间:2024/04/30 10:57

听说了很多的大牛的成长历程都从写自己的博客开始

虽然很久之前就开了博客但是没有坚持下去,从今天开始让自己养成这样的习惯。学着写博客、学着分享。

每天尽量发一篇文章、其他学习文章随着学习进度慢慢写

第一天学习计划:学习算法递归与分支策略,写出二分搜索算法、合并排序算法、快速排序算法

0X00 递归思想:

1、相关概念

直接调用自己或者间接通过一些语句调用自己

一个使用函数自身给出定义的函数叫做递归函数

        优点:描述问题自然,证明算法容易

        缺点:时间、空间复杂度高

一个递归问题可以分为“回推”和“逆推”两个阶段

2、递归应满足的条件

定义中必须包含一个基本部分,其中对于n的一个或多个值,f(n)必须是直接定义的(也就是必须有递归的出口)

在递归部分中,右侧出现的所有f的参数必须有一个比n小(保证每次递归调用规模减小)

3、经典例题

~Fibonacci数列递归算法

int Fibonacci(int n){if(n <= 1)  return 1;return Fibonacci(n - 1) + Fibonacci(n - 2);}
~排列问题的递归算法

/**问题描述*设计一个递归算法生成n个元素{r1,r2,……,rn}的全排列。记为perm({r1,r2,……,rn}).*解决思路*设R={r1,r2,……,rn}是要进行排列的n个元素,Ri=R-{ri}。*/template<class T>void Perm(T list[], int k, int m) //生成所有[k:m]的排列方式{int i;if(k == m)   //递归出口{for(i=0; i <= m; i++)cout << list[i];cout << endl;}else  //递归产生各种排列{for(i = k; i <= m; i++){  //i=>riswap(list[i],list[k]);  Perm(list, k+1, m);//对n-1个元素进行全排列swap(list[i],list[k]);//排列后为保证无重复结果,将ri换回}}}
0X01 分治法思想

1、基本概念

分治法解决一个大的问题时可以分成多个更小的问题、分别解决每个小问题后将每个小问题的解答组合起来,得到原来大问题的解

分治思想解决问题的代码模型为:

Divide-and-Conquer(P)   //P为求解问题的规模{if(|P| <= n0) Adhoc(P);  //判断规模P是否足够小,即子问题的规模divide P into smaller subinstances P1,P2,…,Pk;for(i=1;i<=k;i++)yi=Divide-and-Conquer(Pi);  //分治解决问题return Merge(y1,…,yk);  //合并子问题结果得到最终结果}

2、经典问题

~二分搜索

/**问题描述*给定已排好序的n个元素,在n个元素中找出一特定元素x,找到则将其位置交给赋值给变量j,否则j=-1*解决思想*取中间元素作比较元素,相等则返回,不相等则在相应的位置继续寻找*/template<class T>int binarySearch(T list[], const T& x, int n)//list为排好顺序的数组、x为寻找的元素、n为数组规模{int left = 0, right = n-1;int middle = 0;while(left <= right){middle = (left + right) / 2;if(list[middle] == x) return middle;if(x > list[middle]) left = middle + 1;else right = middle - 1;}return -1;}

~合并排序——插入法

/**问题描述*已知n个元素的数组list[1:n],将list中元素按不降序排列*解决思路*从第二个元素开始取出与之前的第i个元素进行大小对比*当遇到不小于list[i]的元素时插入list数组*/template<class T>void insertionSort(T list[], int n)//数组list、数组规模n{T item;int i;for (int j = 1; j < n; j++){item = list[j];        //取出当前元素i = j - 1;while (item < list[i] && i>-1){list[i + 1] = list[i];i--;}list[i + 1] = item;}}
算法时间复杂度分析:插入算法的while循环中语句执行次数可能为0~j次,因此最坏的时间复杂度为O(n^2),当然,输入之前就是排好顺序的话时间复杂度为最好情况的O(n)

~2、归并排序

void merge(int *data, int start, int end, int *result){int left_length = (end - start + 1) / 2 + 1;//左部分区间的数据元素的个数int left_index = start;int right_index = start + left_length;int result_index = start;while (left_index < start + left_length && right_index < end + 1){//对分别已经排好序的左区间和右区间进行合并if (data[left_index] <= data[right_index])result[result_index++] = data[left_index++];elseresult[result_index++] = data[right_index++];}while (left_index < start + left_length)result[result_index++] = data[left_index++];while (right_index < end + 1)result[result_index++] = data[right_index++];}void merge_sort(int *data, int start, int end, int *result){if (1 == end - start)//如果区间中只有两个元素,则对这两个元素进行排序{if (data[start] > data[end]){int temp = data[start];data[start] = data[end];data[end] = temp;}return;}else if (0 == end - start)//如果只有一个元素,则不用排序return;else{//继续划分子区间,分别对左右子区间进行排序merge_sort(data, start, (end - start + 1) / 2 + start, result);merge_sort(data, (end - start + 1) / 2 + start + 1, end, result);//开始归并已经排好序的start到end之间的数据merge(data, start, end, result);//把排序后的区间数据复制到原始数据中去for (int i = start; i <= end; ++i)data[i] = result[i];}}
~快速排序

void sort(int array[], int left, int right) {int ltemp = left, rtemp = right;int f = array[(left + right) / 2];while (ltemp<rtemp){while (array[ltemp] < f){ltemp++;}while (array[rtemp] > f){rtemp--;}if (ltemp < rtemp) {int temp = array[ltemp];array[ltemp] = array[rtemp];array[rtemp] = temp;ltemp++;rtemp--;}}if (ltemp == rtemp) {ltemp++;}if (left < rtemp) {sort(array, left, ltemp - 1);}if (ltemp < right) {sort(array, rtemp + 1, right);}}
好的问题大概就这样,明天计划学一下python的正则表达式、多线程以及一些其他的算法。

希望自己能坚持下去。













原创粉丝点击