数据结构和算法
文章平均质量分 82
JUST_ONE_MORE
这个作者很懒,什么都没留下…
展开
-
面试100题---1反转链表
题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:struct ListNode{ int m_nKey; ListNode*m_pNext;};分析:这是一道广为流传的微软面试题。由于这道题能够很好的反应出程序员思维是否严密,在微软之后已经有很多公司在面试时采用了这道题。为了正确地反转一个链表,需要调整转载 2015-04-17 16:15:18 · 251 阅读 · 0 评论 -
二叉排序树
二叉排序树二叉排序树又称“二叉查找树”、“二叉搜索树”。二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;3. 它的左、右子树也分别为二叉排序树。 二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树可得到一转载 2015-05-09 10:58:11 · 657 阅读 · 0 评论 -
面试题39_2 判断一棵树是不是平衡二叉树
思想一:在求树深度的基础下,对每个节点的左右子树求深度,按照定义,左右子树的深度差不超过1就是平衡二叉树。缺点:需要重复遍历//求树的深度int TreeDepth(BinaryTreeNode* pRoot){if(pRoot == NULL)return 0;int nletf=TreeDepth(pRoot->m_pLeft);int nright=TreeD原创 2015-05-20 16:58:45 · 1361 阅读 · 0 评论 -
面试题49 把字符串转换为整数
【题 目】输入一个表示整数的字符串,把该字符串转换成整数并输出。例如:输入“123”,输出整数123. 【思 路】当然首先想到的就是C语言库函数atoi,一行代码就完事了,当然我们是想不借助该库函数来实现自己的算法。首先,我们考虑怎么把字符串转换成整数,我们输入“123”,我们可以遍历这个字符串,首先读入1,然后读到2,这时我们想要的是12=1×10+2;然后读入3,我们想要的是转载 2015-05-20 15:23:25 · 354 阅读 · 0 评论 -
面试题38 数字在排序数组找那个出现的次数
例如输入数组{1,2,3,3,3,3,4,5,6}中查找3出现的次数。最为简单的方法就是从头遍历这个数组,统计3出现的次数,可是这样没有利用这是一个排序了的数组这个条件,时间复杂度O(n)。另一种方法就是利用二分查找的算法找到一个3,然后分别向左和向右查找第一个和最后一个3所在的位置,这样虽然比第一种方法效率提高了,但是当最坏的情况时,即数组中所有的元素都是3时,这样时间复杂度依然转载 2015-05-20 15:39:35 · 636 阅读 · 0 评论 -
面试题50 树中两个节点的最低公共祖先LCA(Lowest Common Ancestor )
题目是树的最低公共祖先,我们先来考虑树是什么树?我们从最简单的情况开始分析。情况一:是二叉树,且是二叉搜索树(二叉排序树,二叉查找树)分析:由于二叉排序树具有这样的特点:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。所以我们只需要从树的根节点开始和输入的两原创 2015-05-20 09:58:55 · 824 阅读 · 0 评论 -
面试题39_1 二叉树的深度
递归思想:如果一颗树只有一个节点,它的深度为1.如果根节点只有左子树没有右子树,那么它的深度为左子树的深度加1,同理,只有右子树没有左子树,它的深度为右子树深度加1,如果既有左子树又有右子树,它的深度为左右子树深度较大的加1。递归很容易实现: int FindTreeDeep(BinTree BT){ if(BT==NULL) return 0; int lchi原创 2015-05-20 16:05:48 · 422 阅读 · 0 评论 -
面试题40 数组中只出现一次的数字
题目一:一个数组里除了一个数之外,其他的数都出现了两次,请找出这个数。思想:题目里强调, 一个数字出现了一次,其余的都出现了两次。我们想到异或的一个性质:任何一个数字异或自身等于0.也就是说,如果我们从头到尾异或数组中的每一个数字,那么结果为只出现一次的数字,因为出现两次的数字全部抵消了。void FindNumberAppearOnce(int data[] ,int原创 2015-05-21 08:43:23 · 382 阅读 · 0 评论 -
面试题41_2 输入一个正数s,打印所有和为s的连续正数序列(至少两个数)
有了面试题41_1的经验,我们也可以考虑用两个数 small 和 big分别表示序列的最小值和最大值,首先将small=1,big=2;如果small~big的和大于s,small++;如果small~big的和小于S,big++;直到small=(s+1)/2;void printfContinueNumbers(int small,int big){int i;for(原创 2015-05-21 11:22:12 · 567 阅读 · 0 评论 -
内部选择排序---堆排序
堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。二叉堆的定义二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足二个特性:1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。当父结点的键值总是大于或等于任何一个子节转载 2015-04-17 16:01:55 · 285 阅读 · 0 评论 -
内部非比较排序---计数排序
计数排序是一种算法复杂度 O(n)的排序方法,适合于小范围集合的排序。比如100万学生参加高考,我们想对这100万学生的数学成绩(假设分数为0到100)做个排序。我们如何设计一个最高效的排序算法。本文不光给出计数排序算法的传统写法,还将一步步深入讨论算法的优化,直到时间复杂度和空间复杂度最优。计数排序是一个类似于桶排序的排序算法,其优势是对已知数量范围的数组进行排序。它创建一个长度为这个数转载 2015-04-17 16:05:43 · 354 阅读 · 0 评论 -
内部插入排序---希尔排序
希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因转载 2015-04-17 15:50:56 · 273 阅读 · 0 评论 -
内部交换排序---快速排序
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。总的说来,要直接默写出快速排序还是有一定难度的,因为本人就自己的理解对快速排序作了下白话解释,希望对大家理解有帮助,达到快速转载 2015-04-17 16:00:13 · 369 阅读 · 0 评论 -
内部插入排序---折半插入排序
折半插入排序 只有比别人更早、更勤奋地努力,才能尝到成功的滋味。 ------麦克马斯特大学训言 先找到插入位置(折半查找),再插入。(可减少交换次数)。 记得之前总结过插入排序,有兴趣的可以看看---插入排序。 如果在最复杂的情况下,所要排序的整个数列是逆序的,当第 i-1 趟需要将 第 i 个元素插入前面的 0~i -1 个元转载 2015-04-17 15:55:41 · 407 阅读 · 0 评论 -
内部插入排序---直接插入排序
直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。设数组为a[0…n-1]。1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=12. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。3. i++并重复转载 2015-04-17 15:57:11 · 260 阅读 · 0 评论 -
内部非比较排序---桶排序
桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将阵列分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的阵列内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响。 例如要对大小为[1转载 2015-04-17 16:04:34 · 347 阅读 · 0 评论 -
内部非比较排序---基数排序
基数排序:基数排序首先从最低有效位数字进行排序,然后重复这个过程,直到最高有效位数字排序完毕。一个实例如图所示。在基数排序中,最重要的一点是按位排序使用的算法一定要是稳定的。在常见的排序算法中,选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、合并排序是稳定的排序算法。当然,基数排序也是稳定的。(参考)转载 2015-04-17 16:07:09 · 304 阅读 · 0 评论 -
内部交换排序---冒泡排序
冒泡排序是非常容易理解和实现,,以从小到大排序举例:设数组长度为N。1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。3.N=N-1,如果N不为0就重复前面二步,否则排序完成。 按照定义很容易写出代码:[cpp] view plaincopy转载 2015-04-17 15:57:14 · 373 阅读 · 0 评论 -
内部选择排序---简单选择排序
给定待排序序列A[ 1.....n ],选择出A中最小的记录(也可以理解为求一个无序数组A中的最小的元素)。下面给出代码如下: //选择待排序序列a中的最小记录,其下标为index for(index=i=1;i if(a[i] index=i; } 相信这段代码大家都能看懂转载 2015-04-17 16:02:59 · 448 阅读 · 0 评论 -
面试题41_1 和为S的数
题目一:在一个递增排序数组里,查找两个数,使他们的和正好为S,有多对输出一对即可。方法一:先在数组中固定一个数,然后判和其余n-1个数的和是否等于S。时间复杂度 O(n^2);方法二:我们先在数组中选择两个数(我们选择数组的第一个和最后一个),如果他们等于S,我们就找到了这两个数,如果小于S,我们将较小的数字换为后面的数字,因为排在后面的数字要大些。如果大于S,我们将较大的原创 2015-05-21 10:42:29 · 493 阅读 · 0 评论