每日编程
Geek_Simon
simon的极客之路
展开
-
每日编程11之树的层次遍历
核心思想,是用队列作为辅助数据结构实现。队列的初始化,入队,出队的操作是关键初始时:将root指针入队(root != NULL,否则直接返回)每次从队列里取出队头元素,打印,并将其左右子树(若不为NULL)入队若队列为空,则遍历结束队列数据结构:队列空和队列满的判断这是在牺牲一个元素的存储空间下,队列空和队列满的原创 2013-03-05 22:16:37 · 484 阅读 · 0 评论 -
每日编程8之创建一个栈并使之min,push,pop复杂度均为O(1)
直观上push,pop的复杂度肯定是O(1)..当然,这里的min操作应该是找出栈中的最小元素,但并不要求将该元素出栈。。。核心思想是,栈顶元素同时记录着当前栈的最小元素指针这里涉及到需要证明的一个地方,这也是算法正确性的体现,即无论是出栈还是入栈,这样的栈结构设计都能够保证始终通过栈顶能直接找到最小元素结构体竟然可以直接assignment,太神奇了,s1原创 2013-03-01 18:19:57 · 297 阅读 · 0 评论 -
每日编程9之二叉树的先序遍历递归版本
本文研究先序遍历的方式建立二叉树,打印二叉树(递归方式)首先是,先序遍历建立二叉树。输入:014xx5xx2x6xx(1)接受输入元素element,建立一个新的节点,若该节点为第一个节点,则将树root指针指向它(这个也不需要,只要递归开始的时候,将root传进去,root会改变指向,root->left也会)(2)递归处理左右子树,结束递归的条件是输入为原创 2013-03-02 12:55:45 · 282 阅读 · 0 评论 -
每日编程10之二叉树的先序遍历的非递归版本
这是用栈模拟的一个过程,要注意的地方是:(1)入栈的顺序是先右子树,后左子树,这是才能保证出栈是先左后右初始化时:若根节点不为NULL,将根节点入栈,否则return;核心处理操作:打印数节点元素值循环结束条件:栈为空核心代码:int TreePrint_preorder_nonRecur(BTree root){ if(!root原创 2013-03-03 15:41:41 · 177 阅读 · 0 评论 -
每日编程20之用一个数组实现2个和3个栈
用一个数组实现2个栈很简单,只要一个栈栈底在数组左边,向右生长,另一个栈栈底在数组右边,向左生长。判断栈满的条件是二个栈元素之和超过数组大小。实现3个栈似乎有难度。。。直观的想法是,将数组静态的分为3个区域以实施3个栈,这样的话,存储空间的使用会非常的不灵活。对这个想法的一个优化是,3个栈的栈底分别是数组的start,mid,end 。。mid这个栈的push,pop操作交替左原创 2013-03-14 20:05:19 · 482 阅读 · 0 评论 -
每日编程20之树中二个节点的最近父节点
输入是一棵树中的二个节点指针(有可能是同一个指针)输出应该是指向这二个节点最近父节点的指针。考虑采用递归的思想去做,后序遍历二叉树遍历0号节点,遍历1号节点,遍历4号节点,发现其为first,继续遍历5号节点,遍历2号节点,发现其为second,此时二个节点都已经遍历到了,不需要对从根节点开始的每个节点后续遍历,若某一个节点的(左右)子树同时包含first,seco原创 2013-03-16 10:07:29 · 597 阅读 · 0 评论 -
每日编程21之单链表相交,环的相关问题研究
首先如何判断二个单链表是否相交,也就是所谓的Y型链表问题。算法很简单,只要分别遍历二个链表,对比二个链表的表尾元素是否相同即可那么再进一步,如何找到这二个链表的交汇点。只要在遍历的时候,记录2个链表的长度,M,N,假设M>N则长度为M的链表先走M-N步,然后二个指针同时走,当二个指针第一次相同的地方就是链表的交汇点。判断一个单链表是否有环,如果有环的话,如何找到起始原创 2013-03-16 12:40:30 · 526 阅读 · 0 评论 -
每日编程23之汉诺塔问题
问题的描述是,输入n个盘子,从从小到大排列在一起,设为A另有B,C二个托盘如何移动,将A中的n个托盘移动到C中,同时在任何时候保证大的盘子在小的盘子下面普遍的通用的递归算法如下int hanoi(int n,char A,char B,char C){ if(n==1) { printf("m原创 2013-03-17 13:05:39 · 419 阅读 · 0 评论 -
每日编程22之递归实现栈的反转
这个问题还是蛮复杂的,主要的解题思想是汉诺塔和九连环问题。。要求空间复杂度O(1)既然是反转栈,那么首先所有的栈元素都应该先出栈,那么如何存储这O(n)的元素?既然是递归的方法,很容易想到用递归函数栈来存储。。关键是如何实现反转?这样一次递归出栈是无法解决问题的,等等,这怎么看怎么像"汉诺塔问题",好吧,我们先去研究一下它吧。看到的实现代码,递归逻辑如上图所原创 2013-03-17 20:15:30 · 1060 阅读 · 0 评论 -
每日编程24之BST
BST,二叉查找树,又叫排序二叉树,指一种树,对于每一个树节点,其左子树的值关键的操作(1)根据元素序列,初始化,构建一颗二叉查找树,基于插入操作(2)对于一颗二叉查找树,插入一个元素,并保持二叉查找树的特征(3)查找操作,删除操作int insert_bst(BTree bst,int e){ struct node *pt = bst;原创 2013-03-18 10:03:02 · 679 阅读 · 1 评论 -
每日编程25之求二叉树镜像
思路很简单:对二叉树进行先序遍历,如果树根节点的左右子树同时为空,则返回;若不同时为空,则交换左右子树(即交换root->left,root->right)。。。。so easy。。。原创 2013-03-19 08:58:19 · 744 阅读 · 0 评论 -
每日编程27之linux系统调用——进程管理
进程ID的唯一性,多数UNIX系统采用的延迟重用(防止新进程的ID被认为是已经被删除进程的ID)策略。。。系统中存在一些专用进程:(1)ID为0的进程通常是调度进程(交换进程)swap,它不执行任何磁盘程序,因此被称为系统进程(2)ID为1的进程为init进程,在系统启动结束时由内核调用,程序文件为/etc/init 或/sbin/init...该进程负责启动一个unix系统,通常原创 2013-04-10 21:28:58 · 504 阅读 · 0 评论 -
每日编程28之求最大子数组(o(N)复杂度)
之前研究算法,还剩下三大难题——KMP,rb-tree和DP。。本来是想把DP这一遗留问题解决,就看到了这个问题,后面才发现这个问题其实很简单,完全用不到动态规划的思想,或者是最简单的一维DP。问题描述,一个数组,n个元素,有正有负求最大子数组,要求o(N)复杂度例如,输入数组为 1,-2,3,10,-4,7,2,-5 则和最大的子数组为3,10,-4,7,2原创 2013-04-11 13:29:15 · 854 阅读 · 0 评论 -
每日编程19之二个精妙小算法
(1)求单链表的倒数第四个元素第一种最直观的想法是,用二个指针first,second;初始时second比first多三步,当second走到结尾时,first的位置就是倒数第四个元素这个算法的优点是思想直观,容易实现。但需要考虑链表元素个数少于4个节点的没种情况。。第二种较为新颖的算法是,用一个数组arr[4]作为辅助存储,初始时arr中每个元素是一个特别的值,比如-1.01(最好原创 2013-03-13 09:06:09 · 736 阅读 · 0 评论 -
每日编程7之快速排序非递归版本
递归算法转化为非递归实现的核心思想是"用栈来模式递归函数栈"。实现主要考虑:入栈/出栈的逻辑对于快速排序来说。。栈元素包括,输入序列的左右下标,初始时将0,n-1每次循环 取出栈顶元素(p,q),若q 在该段元素序列中执行快速排序核心算法: 确定新的中间元素 i+1 将(p,原创 2013-02-28 17:51:06 · 271 阅读 · 0 评论 -
每日编程18之中位数/任意第K大的元素
中位数(中指)是指一串元素序列中值处于中间的那个元素。求中位数最直观的一种想法是,先将数据排个序,然后取中间元素,平均复杂度为O(nlogn)。另一种巧妙的想法是利用快速排序的划分步骤,每次将元素序列划分二份,中位数必然存在于其中的一个子序列,这样每次划分都可以抛去部分序列。这种算法的时间复杂度为O(n)递归函数,求解(p,q)序列中的第k个元素,,...int midVa原创 2013-03-12 13:26:31 · 428 阅读 · 0 评论 -
每日编程12之用二个栈实现队列操作
用二个栈实现一个队列现在的基本想法是:2个栈inS,outS一个栈用来取出队首元素,另一个栈用来加入队尾元素入队操作:即将元素压入栈inS,若inS栈满,则检查outS是否为空,若是则主动将inS中的元素pop并push到inS中去,否则则显示队列满出队操作:从栈outS取出元素,若栈空,将栈inS中的元素全部pop并push到outS中去,若二个栈都空,则说明队列为空算法原创 2013-03-06 13:39:39 · 422 阅读 · 0 评论 -
每日编程1之冒泡排序
冒泡排序的核心就是它的这个两层循环和其中的变量控制,第一层循环i表示每一次冒泡最后浮出水面的那个最大(最小)元素,这个元素的位置就确定下来了,第二层循环中的j每次从数组开始位置开始进行数据比较直到此次遍历只有一个元素(j==i)若初始数组为逆序或接近逆序,则比较会频繁发生,因此比较操作用宏定义来实现,以减少函数调用的开销.. for(i=Size-1;i>0;i--)原创 2013-02-22 11:02:13 · 209 阅读 · 0 评论 -
每日编程2之快速排序
6 4 3 7 5用变量i记录,(i+1)代表着下一个比pivot大的元素,j对元素序列进行遍历(p始终保持i,i+1为序列中小元素,大元素的分界线...遍历完成后交换A[q]与A[i+1],此时i+1即为A[q]元素的最终位置,以此为界,形成的二个子序列进行递归,递归结束的条件是p核心代码:int quickSort(float A[],int p,int q原创 2013-02-23 10:49:05 · 196 阅读 · 0 评论 -
每日编程13之希尔排序
核心思想是,分组插入排序,减小组间元素的距离,当距离为1时排序完成;写程序的要点还是循环控制首先,距离变量gap,初始为4依次减半2,1.对于gap=4的情况,就有四个分组(0,0+gap,...),(1,1+gap,...)(2,2+gap,...),(3,3+gap,...)即每个分组初始分别为0~gap-1对于gap=2的情况在每个分组的元素序列确原创 2013-03-07 15:42:47 · 363 阅读 · 0 评论 -
每日编程3之快速排序随机化版本
前文所述,快速排序的平均时间复杂度与输入元素序列的均衡化程度相关,在最坏情况下,每次选择的pivot元素都是最大元素/最小元素,时间复杂度为n*n 像1 2 3 4 5 6这种若输入元素较为均衡,平均时间复杂度将为logn*n所以对快速排序的输入序列做一个随机化预处理,可以有效降低排序的时间复杂度,在实际编程中,可以采用每次随机选择A[p-q]中的一个元素作为piv原创 2013-02-24 10:18:41 · 277 阅读 · 0 评论 -
每日编程14之取单链表中间元素
我的直观想法是遍历单链表,统计元素个数,然后确定中间元素的位置,在此进行遍历。。。看到的比较精妙的算法是,用二个指针first,second分别走一步,二步。。当second走到队尾/接近的时候,first应该就是中间/接近中间元素的位置这里的关键是,处理"接近"这个模糊的概念。。。来二个图,直观的展示一下..首先是元素个数分别为偶数/奇数个的情况所以每次都要判断sec原创 2013-03-08 10:44:18 · 625 阅读 · 0 评论 -
每日编程15之用二个队列实现栈数据结构
看到这个问题,我现在的想到的解决方案是:二个队列中,始终有一个队列(队列1)为空,另一个队列(队列2)为栈中的元素,入栈的操作就直接将元素放入队列2(所以栈满的条件就是队列2满),出栈时将队列2的元素依次出队并向队列1入队,直到队列2的最后一个元素,也就是栈顶的元素出栈。。。。此时队列1和队列2的次序和作用发生了一个翻转。。。。要处理的细节情况还是比较多比如push的时候,要处原创 2013-03-09 11:15:58 · 493 阅读 · 0 评论 -
每日编程4之单链表反转
这好像是marvell笔试的一道题!这里的链表是无头单链表,输入应该是单链表的表头元素指针head,输出是反转后的表头元素指针存三种情况:(1)若head == NULL ,即链表中没有元素,返回head(2)若p=head q=p->next为NULL 即只有一个元素,则返回p(3)若链表中有2个或2个以上的元素,初步想了一下,这几种情况应该可以统一起来...可以原创 2013-02-26 09:16:40 · 238 阅读 · 0 评论 -
每日编程5之逆序输出单链表
因为只要求逆序输出,考虑采用递归思想,以减少对链表结构的破坏。这里主要训练递归算法的编码技巧。首先,这里递归的单位应该是每个链表元素,对这个元素的核心处理操作是打印其数据项,因为是倒序输出,所以将递归处理操作放在核心处理操作之前。递归结束的条件是,当前节点为空节点,这个时候不做任何处理,前面的递归函数开始依次出栈,因为第一个出栈的是链表尾元素,所以后续的数据输出也是逆序的。核心代码原创 2013-02-26 09:44:20 · 275 阅读 · 0 评论 -
每日编程16之判断数是否为平衡二叉树
平衡二叉树的定义是,对于树中的任一节点,其左右子树高度差不超过1(即只可以为-1,0,1三种情况)这里的树的高度是指从叶子节点(高度为0)算起的左右子树最高的值+1。这里也有递归的逻辑。判断一颗树(树的唯一标志/入口是其root节点)是否平衡,就是比较其左右子树的高度差是否小于1.。现在的解决方案是,递归思想+树的后续遍历递归需要对每一个节点都进行处理,对于一般原创 2013-03-10 10:54:44 · 558 阅读 · 0 评论 -
每日编程6之单链表反转递归版本
既然链表逆序输出可以用递归方法实现,单链表反转也可以采用递归思想实现。不同的地方时,后者需要破坏原有的链表结构不晓得采用1个指针能不能实现先考虑用2个指针p,q分别记录原来的链表关系初始时:p = NULL,q = head; 特殊条件为q==NULL,表示链表中没有元素,这也可以作为递归结束条件(这可以成为一种找递归结束条件的思路)递归处理操作是:p=q;q=q->原创 2013-02-27 11:01:00 · 300 阅读 · 0 评论 -
每日编程17之字符串匹配朴素算法
字符串匹配朴素算法的核心思想是:从待匹配字符串的首字符开始依次和模式串匹配,若匹配成功则返回位置,若匹配不成功则接着匹配下一个字符开始的串。。直到,待匹配串余下的长度小于模式串。。。所以这里要频繁的调用了求字符串长度的函数,但如果每个字符都开始求长度,整体复杂度就不是O(mn)了,而是O(n2)。。。其实也不用这样,初始的时候求一下长度,就可以了。。。int str原创 2013-03-11 10:20:27 · 415 阅读 · 0 评论