减治法原理
何为减治?减治法是通过减小问题规模,产生一个子问题,那么只要找到这个子问题的解,然后再找到子问题解与原问题解的关系,那么就成功解决了这个问题。当然,减治操作是可以递归的,问题规模当然越小越好,常见的减治法主要有:减常数规模、减常因子规模、减可变规模三种。

插入排序
插入排序是经典的排序算法,但其实从一个角度讲,它同样是一种的减治法的体现:假如现在有N个数,需要输出非递减序列。这当然很简单!
但让我们从分治法的角度来分析一下,我们要将N个数排序,如果第一个数本身就是有序的就好了!!!我们不妨假设,第一个数就是有序的,那我们当然希望第二个数也是有序的,对吧?那如果第二个数有序,我当然希望第三……咳咳!!!幻想当然是美好的,但我们还是要面对现实。但这个幻想却给我们提供了一个解决问题的角度,也就是排好第一个结点,然后不断减小待排序数的规模,直至问题解决。
那我们来实现以下,要排好第一个数,就先要找到最小的数,这一点毋庸置疑。同样这也很好解决,我们先默认第一个结点下标index是最小的,然后遍历一遍链表,碰见更小的结点就更新一下index。这样一遍下来,就可以得到最小的结点,那么我存好的这个结点后,问题的规模是不是就变小了!!!那么为了充分复用空间,我们直接在外层循环中将下标为index和下标为i的两个数调换顺序即可,此时我只关心第一个结点要放在首位,至于一开始的i节点被换到哪里去了,I don't care!!!
viod InsertionSort(a[N]){
int index=0;
for(int i=0;i<N;i++){
index=i;
for(int j=i+1;j<N-i;j++){
if(a[index]>a[j])
index=j;
}
int temp=a[index];
a[index]=a[i];
a[i]=temp;
}
}
拓扑排序
那么讲完了超级简单的插入排序,我们稍微进阶一下,来看一看比较简单的拓扑排序。
首先拓扑是数学中的一个概念,当然我们今天不讲数学(单纯因为我真的不不不……喜欢)。我们今天简单讲一讲在它在实际生活中的例子:
大家对课表肯定不陌生,但是一张课表是怎么排出来的呢?因为我们知道,课程的开设肯定是有顺序的,以计算机大类课程为例,C语言程序设计肯定要在数据结构之前开吧!!!所以说有些课程是有先后顺序的,而有些课程是可以并行开设的。那如果将这些课程抽象成结点,那么这些课程的关系应该是一个有向无环图。有人会问哦,为什么是一个有向无环图?其实很好理解,可以想象一下,如果你课表上有一门大四课程需要先学一门大一的课程,而你发现这门大一的课程又需要先学这门大四的课程……哇哦!!!(是先有鸡,还是先有蛋呢?)这样很好理解了吧。
那我现在将其抽象出来:

假如现在有四门课程,其开设的先后关系由箭头表示(优先开设指向后开设)。
这当然可以用深度优先遍历的出栈顺序解决,但我们试着从减治法的角度
减治法原理及相关算法应用

最低0.47元/天 解锁文章
2491

被折叠的 条评论
为什么被折叠?



