算法与数据结构
文章平均质量分 81
sicofield
这个作者很懒,什么都没留下…
展开
-
堆及其算法
堆一般是一种隐式表述(implicit representation),简单的说堆是由另外一种容器实现的。由于堆中的操作都基于搜寻父节点,子节点。如果用数组的话,那么不需要额外的存储空间就可以轻松实现。左子节点标号=父节点标号*2+1;右子节点标号=父节点标号*2+2;父节点标号=(子节点标号-1)/2。如果在用一种小技巧,将标号0处元素保留(或设为无限大(小)值),从而忽略根节点的话,计算式将改原创 2013-03-30 09:50:19 · 1884 阅读 · 0 评论 -
排序
总结一下排序的各类算法,包括冒泡排序、插入排序、快速排序,关于堆排序见博客:堆及其算法。1.冒泡排序 冒泡排序是效率很低(n^2)的排序,一般情况下都不会使用的,在小数据时还可以考虑,不过没有见过算法库使用冒泡排序的,一般的算法库在小数据情况下使用插入排序。 冒泡排序的思想很简单,逆序两两交换,两层循环。 源码:void Bubb原创 2013-04-15 10:14:27 · 1272 阅读 · 0 评论 -
二叉树遍历(递归与迭代)
二叉树遍历算法分为前序(PreOredr),中序(InOrder),后序(PostOrder)遍历。并且可以设计递归型或者迭代型算法。 本文二叉树定义为:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;};1.二叉树原创 2013-06-09 18:47:57 · 20117 阅读 · 0 评论 -
取样(算法)
取样问题并不是随机产生一些一定范围的整数即可。取样问题要求在n个连续有序整数中等概率取出m项,且该m项样本有序。 关键是等概率的问题。考虑m=2,n=5的情况。 如果使用if(rand()%5) 正确的形式应该是这样:void select1(int m, int n){ for(int i=0;i<n;i++) { /*这原创 2013-04-11 21:38:17 · 1514 阅读 · 0 评论 -
公因数与空间换时间思想
问题1.给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3628800,N!的末尾有两个0。问题2.求N!的二进制表示中最低位1的位置。问题3.丑数问题,把只包含因子2、3、5的数称作丑数。写一个函数,要求输入一个数值n(n>0),求从小到大的第n个丑数的值。问题4.质数问题,要求写一个函数,输入数值n(n>0),求不小于n的质数的个数。(注意:问题3与问题4的原创 2013-06-03 21:15:58 · 1265 阅读 · 0 评论 -
包含max(min)的栈及队列
题目一:设计一种栈,在这个栈中实现一个能够得到栈中最小元素的min函数。在该栈中,调用push,pop及min的时间复杂度都是O(1) 可以设计一个栈作为辅助数据结构,这个栈相应位置的值就是主栈中压入相应多元素中的最大值。两个栈保持同等的数据量。辅助栈的目的就是记录主栈拥有相应多个元素时的最大值。template class StackWithMin{public原创 2013-06-11 20:07:02 · 2380 阅读 · 1 评论 -
二叉树的分层遍历
二叉树除了前、中、后序三种遍历方式外,有时候还要用到分层遍历。分层遍历就是二叉树的广度优先算法,暂时还没有见过图的广度优先算法,据说广度优先算法都要使用一个辅助队列。题目一:分层遍历二叉树,从上往下打印二叉树的每一个节点,同一层次的节点按照从左到右的顺序打印。下图顺序输出1 2 3 4 5 6 7 8//用queue更好void PrintBinayTree(BinaryTr原创 2013-06-09 21:58:12 · 7402 阅读 · 2 评论 -
二分查找
一下是一个正确的二分查找程序:int search(int array[], int n, int v){ int left, right, middle; left = 0, right = n - 1; while (left <= right) { middle = (left + right) / 2;原创 2013-06-01 13:38:11 · 1072 阅读 · 0 评论 -
非递归的快速排序
一般的快速排序是用递归来实现的,如何将快速排序改写为迭代而不是递归?由于递归函数需要保护现场(在栈中),所以可以认为的构建一个栈。由于快速排序中处理排序是partition子函数(过程),然后将划分范围减小,来实现排序。所以要保存的是待继续排序(划分)的边界。这样的一个栈很容易自我构建。#include using namespace std;//划分子函数int partition原创 2013-05-08 19:26:04 · 6487 阅读 · 1 评论 -
单链表反转
单链表的翻转是一道很基本的算法题。 方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。 方法2:使用三个指针遍历单链表,逐个链接点进行反转。 方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。 方法1的问题是浪费空间。方法2和方法3效率相当。一般方法2原创 2013-04-25 16:20:26 · 51558 阅读 · 10 评论 -
自己实现的堆结构
之前写过一个堆及其算法的博客(参考:堆及其算法),但是STL源码考虑的问题很多,所以没有突出堆的核心内容。在此用C++实现了堆。#include using namespace std;template class heap{private: int m_capacity; //堆的最大容量 int m_n;原创 2013-04-15 09:40:41 · 1736 阅读 · 0 评论 -
STL的rotate函数分析
STL的rotate其实就可以看做是一个循环移位的函数。 首先对于循环移位操作有以下的几种思路:1)最简单的想法就是每次移动一位进行循环遍历整个容器,算法复杂度为O(n*m)。2)运用分组交换(尽可能使数组的前面连续几个数为所要结果):若a长度大于b,将ab分成a0a1b,交换a0和b,得ba1a0,只需再迭代交换a1 和a0。算法复杂度为O(n)。3)运用3次翻转操作(re原创 2013-03-28 16:36:38 · 4176 阅读 · 1 评论 -
STL中的二分查找——lower_bound 、upper_bound 、binary_search
二分查找很简单,原理就不说了。STL中关于二分查找的函数有三个lower_bound 、upper_bound 、binary_search 。这三个函数都运用于有序区间(当然这也是运用二分查找的前提)。 其中如果寻找的value存在,那么lower_bound返回一个迭代器指向其中第一个这个元素。upper_bound返回一个迭代器指向其中最后一个这个元素的下一个位置(明确点说就原创 2013-03-30 15:06:59 · 22672 阅读 · 0 评论