2011年4月28日

二叉查找树实现源码

摘要: 看了《算法导论》上的第12章二叉查找树,现把对二叉树的几种操作罗列如下,实现的描述见代码注释。#include <iostream>using namespace std;class Node{public: int key; Node* left; Node* right; Node* parent; Node(int k);};class BinarySearchTree{public: Node* root; BinarySearchTree(); //以node为根节点开始搜索 Node* search(Node* node, int k); //插入节点 void ins 阅读全文

posted @ 2011-04-28 22:41 NULL00 阅读(412) 评论(0) 推荐(0) 编辑

2011年4月21日

算法导论12.2节习题解答

摘要: CLRS 12.2-1C错,240及240之后的节点应该都为911左子树上的节点,那么所有节点必然小于或等于911,但点912明显违反了。CLRS12.2-2SEARCH-MINIMUM(x) if(left[x] != NIL) SEARCH-MINIMUM(left[x]) return xSEARCH-MAXIMUM(x) if(right[x] != NIL) SEARCH-MAXIMUM(right[x]) return xCLRS12.2-3TREE-PREDECESSOR(x) if(left[x] != NIL) return TREE-MAXIMUM(left[x]) y = 阅读全文

posted @ 2011-04-21 10:23 NULL00 阅读(1116) 评论(1) 推荐(0) 编辑

2011年4月20日

算法导论12.1-3习题解答(非递归中序遍历)

摘要: CLRS 12.1-3:给出一个非递归的中序树遍历算法。(提示:有两种方法,在较容易的方法中,可以采用栈作为辅助数据结构;在较为复杂的方法中,不采用栈结构,但假设可以测试两个指针是否相等。)算法思想:1.采用栈的话,先寻找最左边的节点,把经过的节点都存入栈中,第一个被弹出来的为最左节点,那么访问其右子树,对右子树也像前面一样遍历,整个流程跟递归一样。2.不采用栈的话,先是访问最左节点,然后访问其右子树,然后回溯到最左节点的父节点,不断重复这个过程,思路还是一样。这里参考了重剑无锋的http://blog.csdn.net/kofsky/archive/2008/09/05/2886453.as 阅读全文

posted @ 2011-04-20 20:43 NULL00 阅读(5967) 评论(3) 推荐(2) 编辑

2011年4月16日

算法导论10.2-7习题解答(单链表逆转)

摘要: CLRS 10.2-7 :在O(n)时间内对给定的单链表进行逆转。解法:这题没什么技巧,就是将指针的指向进行改变即可。#include <iostream>usingnamespace std;//很简单的Node 和 Listclass Node{public: Node* next; int data; Node(); Node(int d);};class List{public: Node* first; List(); void insert(int d);};int main(){ int K =5; List* list =new List(); ... 阅读全文

posted @ 2011-04-16 19:23 NULL00 阅读(846) 评论(1) 推荐(0) 编辑

算法导论10.1-7习题解答(用两个队列实现一个栈)

摘要: CLRS 10.1-7 :说明如何用两个队列来实现一个栈,并分析有关栈操作的运行时间。解法:1.有两个队列q1和q2,先往q1内插入a,b,c,这做的都是栈的push操作。2.现在要做pop操作,即要得到c,这时可以将q1中的a,b两个元素全部dequeue并存入q2中,这时q2中元素为a,b,对q1再做一次dequeue操作即可得到c。3.如果继续做push操作,比如插入d,f,则把d,f插入到q2中,4.此时若要做pop操作,则做步骤25.以此类推,就实现了用两个队列来实现一个栈的目的。注意在此过程中,新push进来的元素总是插入到非空队列中,空队列则用来保存pop操作之后的那些元素,那么 阅读全文

posted @ 2011-04-16 15:26 NULL00 阅读(1701) 评论(0) 推荐(0) 编辑

算法导论10.1-6习题解答(用两个栈实现一个队列)

摘要: CLRS10.1-6 :说明如何用两个栈来实现一个队列,并分析有关队列操作的运行时间。解法:1.有两个栈s1和s2,先往s1内插入a,b,c,这做的都是enqueue操作。2.现在要做dequeue操作,即要得到a,这时可以将s1中的元素全部弹出并存入s2中,这时s2中元素的顺序(从底部到顶部)为c,b,a,这时做s2.pop()操作即可得到a。3.如果继续做enqueue操作,比如插入d,f,则把d,f插入到s1中,4.此时若要做dequeue操作,则直接弹出s2中的b,它是目前为止,呆得时间最长的元素5.若继续做dequeue操作,则s2弹出c,6.若继续做dequeue操作,则s2为空, 阅读全文

posted @ 2011-04-16 15:12 NULL00 阅读(1613) 评论(0) 推荐(0) 编辑

算法导论10.1-5习题解答(deque实现源码)

摘要: CLRS 10.1-5栈的插入和删除操作都是在一端进行的,而队列的插入和删除却是在两头进行的。有一种双端队列(deque),其两端都可以做插入和删除的操作。对于一个用数组构造的双端队列,请写出四个在两端进行插入和删除操作的过程,要求运行时间为O(1)。#include <iostream>usingnamespace std;template <class T>class Deque{public: void push_front(T t); void push_back(T t); T pop_front(); T pop_back(); Deque(int m); 阅读全文

posted @ 2011-04-16 15:01 NULL00 阅读(1211) 评论(1) 推荐(0) 编辑

算法导论10.1-2习题解答(用一个数组实现两个栈)

摘要: CLRS 10.1-2 :说明如何用一个数组A[1...n]来实现两个栈,使得两个栈中的元素总数不到n时,两者都不会发生上溢。注意PUSH和POP操作的时间应为O(1)。解法:用top1指向数组第一个元素,用top2指向数组最后一个元素,然后PUSH的时候,它们向中间进发,POP的时候向相应的方向减一。 阅读全文

posted @ 2011-04-16 12:33 NULL00 阅读(1801) 评论(0) 推荐(0) 编辑

2011年4月15日

算法导论9.3-9习题解答(寻找中位数)

摘要: CLRS 9.3-9 :选择主输油管道的最优位置(使得各喷管长度总和最小的位置)。算法思想:1.当n为奇数时,其实就是求median;2.当n为偶数时,就是第n/2小和第n/2 + 1小的数为边界的闭区间的任何数。其实这个证明还是蛮简单的,可以移动x轴来观察情况,位于median处(n为奇数)或median范围内(n为偶数)时,设其距离为min,当移动x轴时,移出这个范围,则可以发现所有点(包括median点)到x轴的距离必然大于min。画一下图,就会一目了然。在这里用到了寻找第i小的数#include <iostream>#include <time.h>usingn 阅读全文

posted @ 2011-04-15 18:57 NULL00 阅读(4350) 评论(0) 推荐(0) 编辑

二分查找算法

摘要: 二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的 阅读全文

posted @ 2011-04-15 17:31 NULL00 阅读(123575) 评论(3) 推荐(1) 编辑

算法导论9.3-8习题解答(类似二分查找算法)

摘要: CLRS 9.3-8:设X[1...n]和Y[1...n]为两个数组,每个都包含n个已排序好的数。给出一个求数组X和Y中所有2n个元素的中位数的、O(lgn)时间的算法。算法思想:该算法类似于二分查找算法1.两个数组中小于median的个数为(n - 1)个,假设该median为数组a中的第k个,k为数组下标,那么在数组a中已经存在k个值小于median,那么在数组b中必然有(n - 1) - k = (n-k-1)个数小于median,如果b[n - k - 2] <= median <= b[n - k - 1],那么median就找到了,如果median >= b[n 阅读全文

posted @ 2011-04-15 17:12 NULL00 阅读(2871) 评论(2) 推荐(0) 编辑

2011年4月13日

算法导论9.3-7习题解答

摘要: CLRS 9.3-7 :给出一个O(n)时间的算法,在给定一个有n个不同数字的集合S以及一个正整数k<=n后,它能确定出S中最接近其中位数的k个数。算法思想:1.找到数组a中第n/2小的数median;2.对a中非median数进行|a[i] - median|,得到一个大小为n - 1的数组distance;3.寻找distance中第k小的数值;4.对distance进行一次遍历,找到小于等于k的数,从而对应得到数组a中的k个数。上述每一步的时间复杂度都为O(n),因而最后总的时间复杂度为O(n).#include <iostream>#include <time. 阅读全文

posted @ 2011-04-13 09:20 NULL00 阅读(1221) 评论(0) 推荐(0) 编辑

2011年4月12日

算法导论9.2-3习题解答(寻找第i小的数)

摘要: CLRS 9.2-3 :写出RANDOMIZED-SELECT的一个迭代版本在这里,顺便实现在数组内寻找第i小的数值。#include <iostream>#include <time.h>using namespace std;//随机化分割int randomized_partition(int* a, int p, int r);int randomized_select(int* a, int p, int r, int i);int main(){ int arr[10] = {4, 34, 21, 8, 3, 10, 453, 32, 1, 400}; in 阅读全文

posted @ 2011-04-12 19:56 NULL00 阅读(1494) 评论(0) 推荐(0) 编辑

算法导论9.1-1习题解答(二叉树)

摘要: CLRS 9.1-1 :证明:在最坏情况下,利用n + [lgn] - 2此比较,即可找到n个元素中的第2小元素。(提示:同时找最小元素)算法思想:1.将数组中的元素分组,每组两个元素,然后比较每组中的两个元素得到最小值,重新得到包含原来一半元素的数组,继续重复上述过程,那么最后一个元素必然为最小值。如图所示,数组为{2, 1, 4, 3, 5}2.上述过程形成的是一个二叉树,其中叶子节点都为数组元素,非叶子节点刚好4个,这是二叉树的性质。3.然后我们来找第二小元素,第二小元素必然跟着1,首先赋值为5,然后再赋值为3, 然后赋值为2,即为所求。PS:本章讨论的元素都互异,不存在相同值(见原书) 阅读全文

posted @ 2011-04-12 17:25 NULL00 阅读(2346) 评论(2) 推荐(0) 编辑

2011年4月11日

算法导论8-5习题解答(平均排序)

摘要: CLRS 8-5:平均排序解答:a)非递增完全排序b)2 1 4 3 6 5 8 7 10 9c)展开题目中的公式,然后消除相同项,即可得到此结论。d)算法思想: 1.将数组分成k组,即{a[0], a[k], a[2k] ...}, {a[1], a[1+k], a[zk+1] ...}, ..., {a[i], a[i+k], a[i+2k], ...}, ..., {a[k-1], a[2k-1], ...}. 2.然后对每一组用合并排序或者堆排序进行排序,则每一组的时间为t = n/k*lg(n/k),总的时间为nt,即nlg(n/k).e)由于数组已是k排序的,则可以将数组按d).1 阅读全文

posted @ 2011-04-11 21:06 NULL00 阅读(657) 评论(0) 推荐(0) 编辑

导航