数据结构与算法
数据结构与算法
停5s
这个作者很懒,什么都没留下…
展开
-
剑指offer_面试题_从上往下打印二叉树
题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。例如输入图4.5中的二叉树,则依次打印出8、6、10、5、7、9、11。 8 / \ 6 10 / \ / \ 5 7 9 11思路:树的层序遍历。应用 队列 这一数据容器。如上图的输出顺原创 2015-08-17 09:33:37 · 950 阅读 · 0 评论 -
剑指offer_面试题22_栈的压入、弹出序列(总结规律)
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列:1、2、3、4、5 是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2 就不可能是该压栈序列的弹出序列。原创 2015-08-17 09:16:11 · 1028 阅读 · 0 评论 -
剑指offer_面试题21_包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小最小元素的min函数。在该栈中,调用min、push 及 pop的时间复杂度都是O(1)。本题关键问题在于:O(1)时间复杂度的 min 函数。即无论占中元素如何变化。都要在 O(1)内知道最小值。因此,需要设置两个栈:1、数据栈,用于数据的压入和弹出2、辅助栈,存入与数据栈中相对应的最小元素即 数据栈每压入一原创 2015-08-16 21:35:22 · 506 阅读 · 0 评论 -
剑指offer_面试题20_顺时针打印矩阵(思路在一步步分解之中)
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16则依次打印出数字:1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。思路如下:算法如下:#inclu原创 2015-08-13 21:31:40 · 716 阅读 · 0 评论 -
剑指offer_面试题19_二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。解题方法:遇到复杂问题,可以通过画图、举例等方法,来让自己加深理解。思路往往就在你一步步的分析之中。思路:遍历这颗树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。交换完所有非叶子结点的左右孩子结点后,就得到了树的镜像。写递归时的想法;该设置的退出条件设置好,该进行的交换操作写好,当孩子结点不为空的时候,就去递归孩子原创 2015-08-13 20:15:15 · 612 阅读 · 0 评论 -
剑指offer_面试题18_树的子结构
题目:输入两棵二叉树 A 和 B,判断 B 是不是 A 的子结构。两个步骤:1、第一步在树 A 中找到和树 B 的根结点的值一样的结点 R2、第二步再判断树 A 中以 R 为根结点的子树是不是包含和树 B 一样的结构。对于递归:想好判断条件,以及 什么条件下该去递归。#include #include using namespace std;typedef str原创 2015-08-13 19:59:05 · 672 阅读 · 0 评论 -
剑指offer_面试题17_合并两个排序的链表(两种思维)
题目:输入两个递增排序的链表,合并这两个链表,并使新链表中的结点仍然是按照递增排序的。第一种思维:合并两个排序的链表,类似于合并两个排序数组,所不同的仅是一个用链表保存数据,一个用数组保存数据。算法如下:(下面的算法前提是:头结点 不是 链表的第一个数据节点。)/**方法一:合并两个排序链表,使用了新创建的链表来保存,没有改动两个原始链表*/ListNode *merge_tow原创 2015-08-10 22:13:06 · 867 阅读 · 0 评论 -
剑指offer_面试题16_反转链表(两种方法)
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。在解决问题前,先想好测试用例:1、功能测试:输入的链表含有多个结点,链表中只有一个结点2、特殊输入测试:头结点为 NULL指针解决这个问题有两种方式:前提:这两种方式 是以 头结点并不是第一个数据节点 为基准 表示的。这种方式,头结点并不保存链表的结点数据,其数据位只保存链表结点总数。原创 2015-08-10 11:00:21 · 3429 阅读 · 0 评论 -
剑指offer_面试题14_调整数组顺序使奇数位于偶数前面(函数指针用法)
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。1、一般想法,不考虑时间复杂度:每次遍历数组,碰到一个偶数就拿出来,将后面所有数字向前挪动一位,在将该偶数放到最后。2、利用冒泡排序的思想,两个指针,一前以后,如果前为偶数,后为奇数,就交换。算法如下:void Reorder_array(int p[],i原创 2015-08-09 21:06:03 · 704 阅读 · 0 评论 -
剑指offer_面试题15_链表中倒数第k个节点(考虑问题要全面)
题目:输入一个链表,输出该链表中第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第一个节点。例如一个链表有6个节点,从头结点开始它们的值依次是1,2,3,4,5,6。这个链表的倒数第3个节点是值为4的结点。本题收获:考虑问题要全面,保持代码的鲁棒性(健壮性)。提高代码的鲁棒性的有效途径是进行防御性编程。防御性编程 是 一种编程习惯,是指预见在什么地方可能会原创 2015-08-09 20:34:30 · 667 阅读 · 0 评论 -
剑指offer_面试题12_打印1到最大的n位数(大数问题)
题目:输入数字n,按顺序打印出从 1 最大的 n 位十进制数。比如输入3,则打印出 1、2、3 一直到最大的三位数即 999。由于题目中,没有说明n的大小,因此这是一个大数问题。代码如下:/*数值每次增 1,用一个量来保存,每次增 1,就返回打印*//*算法主要分两块:数值增 1,以及 打印*/bool Increment_2(string &str){ if原创 2015-08-08 20:51:38 · 756 阅读 · 0 评论 -
剑指offer_面试题55_字符流中第一个不重复的字符 *
题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符“go”时,第一个只出现一次的字符是“g”。当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符时“l”。ps. 本题,我在阿里二面的时候,被问到了,需要注意。第一种解法:一种很笨的解法,时间效率低下,但确是我的第一反应。需要记下以便反思。1、首先用一个指原创 2015-08-07 10:08:38 · 2368 阅读 · 0 评论 -
剑指offer_面试题11_数值的整数次方(*)
题目:实现函数 double Power(double base, int exponent),求 base 的 exponent 次方。不得使用库函数,同时不需要考虑大数问题。 通过这道题,了解一些不曾注意的知识点:1、变量命名要合理且明了2、需确保代码的完整性,从三个角度下手: 1)功能测试:确保主体功能 2)边界测试:考虑各种边界值原创 2015-08-05 14:28:49 · 864 阅读 · 0 评论 -
剑指offer_面试题10_二进制中1的个数(位运算)
题目:请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如把 9 表示成二进制 1001,有 2 个 1。因此如果输入9,该函数输出2。 位运算基本概念:五种位运算:与(&)、或(|)、异或、左移 和 右移。ps:其中 异或(运算符 ^),1 ^ 0 = 1; 1 ^ 1 = 0; 0 ^ 0 = 0; 0 ^ 1 = 1; 即 相同为假,不同为真。左移原创 2015-08-03 16:43:25 · 664 阅读 · 0 评论 -
剑指offer_面试题9_斐波那契数列
题目一:写出一个函数,输入n,求斐波那契数列的第n项。题目二:一只青蛙一次可以跳上1级台阶,也可以跳上2级。请求青蛙上一个 n 级的台阶总共有多少种跳法。第二个题目,其实就是第一个题目的意思。若将 n 级台阶时的跳法看成是 n 的函数,记为 f(n)。青蛙在第一级台阶时,有两种跳法:第一次跳 1 级,那么,还剩 n-1 级台阶,那么其跳法总数为 f(n-1)第一次跳 2 级,那原创 2015-08-03 11:06:21 · 544 阅读 · 0 评论 -
剑指offer_面试题7_用两个栈实现队列(让我熟悉了类模板的使用)
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。template class CQueue{private: stack stack1; stack stack2;public: CQueue(void); ~CQueue(void);原创 2015-07-28 21:17:54 · 639 阅读 · 0 评论 -
剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。 感触:复杂问题,要将它分解成一个个小问题,逐个击破,从而解决大问题。我们都知道一个概念原创 2015-07-26 17:16:19 · 886 阅读 · 1 评论 -
剑指offer_面试题5_从尾到头打印链表(栈和递归实现)
题目:输入一个链表的头结点,从尾到头反过来打印出每个节点的值考察 单链表操作、栈、递归等概念。理解:要实现单链表的输出,那么就需要遍历。遍历的顺序是从头到尾,而节点输出的顺序是从尾到头。因此,先遍历到的节点后输出,这是一个典型的 “后进先出”。要实现这样的输出,可以使用栈,或,递归。通过这道题,让我对 “递归在本质上就是一个栈结构” 理解的更加深刻。代码如下:/****原创 2015-07-24 17:03:59 · 853 阅读 · 0 评论 -
剑指offer_面试题4_替换空格(注意时间效率)
题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如:输入“We are happy.”,则输出“We%20are%20happy.” 对于这个问题,初见,可能感觉会比较简单,但隐藏了很多陷阱,需要考虑全面。陷阱1:由一个字符,替换为,三个字符,那么字符串肯定变长,需要考虑原字符串内存是否足够陷阱2:空指针检查,不能忘记陷阱3:时间复杂度很关键最直观的做法(从前向后原创 2015-07-23 20:37:47 · 642 阅读 · 0 评论 -
剑指offer_面试题3_二维数组中的查找(简单问题亦不能忽视)
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样一个二维数组和一个整数,判断数组中是否含有该整数。数组如下:在该数组中查找一个整数隐含的几个规律:1、在数组中选取一个数,如果与所查目标相等,那么查找结束2、若所选数字,小于,要查找的目标,则要查找的目标应该在当前选取的位置的右边或者下边3、若所选数字,原创 2015-07-23 12:19:01 · 876 阅读 · 0 评论 -
剑指offer_面试题26_复杂链表的复制
题目:请实现函数ComplexListNode * Clone(ComplexListNode * pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个 m_pNext 指针指向下一个结点外,还有一个 m_pSibling 指向链表中的任意结点或者NULL。复杂链表结构定义如下:typedef struct Node{ int m_nValue; struct原创 2015-08-17 21:29:43 · 785 阅读 · 2 评论 -
堆、栈 的区别
预备知识—程序的内存分配一个由C/C++编译的程序占用的内存分为以下几个部分:1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap) :一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。3、全局区(静态区)(static):全转载 2015-08-12 21:48:51 · 420 阅读 · 0 评论 -
递归法判断一个数组为递增
题目:递归法判断一个数组为递增数组。算法如下:#include using namespace std;bool is_increease_array(int a[],int n){ if(n == 1) return false; if(n == 2) return a[n-1] > a[n-2]; return is_i原创 2015-09-20 10:08:35 · 632 阅读 · 0 评论 -
剑指offer_面试题25_二叉树中和为某一值的路径
题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路劲。举例: 10 / \ 5 12 / \ 4 7分析:1、从头结点 10 开始 =====》遍历左结点 5====》判断是否是叶结点 ===否===》原创 2015-08-17 13:53:29 · 719 阅读 · 0 评论 -
剑指offer_面试题24_二叉搜索树的后序遍历序列(递归)
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。二叉搜索树规律:1、若 左子树 不空,则 左子树上所有结点的值 均小于它的根结点的值。2、若 右子树 不空,则 右子树上所有结点的值 均大于它的根结点的值。3、左右子树也分别为二叉搜索树。举例1:输入数组:{5、7、6、原创 2015-08-17 10:01:46 · 654 阅读 · 0 评论 -
log(n)怎么理解
1、理解什么是对数参考回忆:https://baike.baidu.com/item/%E5%AF%B9%E6%95%B0/91326?fr=aladdin2、log(n)理解,参考:https://www.cnblogs.com/glzgc/p/10831877.html原创 2021-03-03 19:29:35 · 3916 阅读 · 1 评论 -
图_邻接矩阵_DFS_BFS
图(Graph)由顶点的 有穷非空集合 和 顶点之间边的集合 组成。 表示为:G(V,E),G:图,V:图G中 顶点的集合,E:图G中 边的集合 图的邻接矩阵存储结构表述如下:#define VEX_MAX 100 /*最大顶点数*/typedef char Vtype; /*顶点类型*/typedef int Etype;原创 2015-05-23 21:58:26 · 743 阅读 · 0 评论 -
快速排序
关于快速排序的学习,请参考这一篇博文,讲得清楚明了: http://blog.csdn.net/morewindows/article/details/6684558快速排序,是冒泡排序的升级版,属于交换类排序。 原理,挖坑填数: 在待排序数列中,选定一个基准数。小于这个基准树的数据移到前面,大于这个基准数的放到后面,在分别对前面部分的数据,和后面部分的数据,进行选基准数移动。依次递归,可得到原创 2015-06-24 20:55:23 · 481 阅读 · 0 评论 -
归并排序(递归和非递归法)
本文主要参考两篇博文: 递归法归并排序函数代码来自: http://blog.csdn.net/morewindows/article/details/6678165/ 非递归法归并排序函数代码来自: http://www.cnblogs.com/xing901022/p/3671771.html以下是我根据两篇博文,写的一点学习笔记。归并排序原理: 含有 n 个元素的数列,可以将其分解成原创 2015-06-24 20:30:16 · 563 阅读 · 0 评论 -
堆排序
在理解堆排序之前需要知道两个知识点:二叉树性质5 以及 堆的概念。 二叉树性质5:如果对一棵有n个结点的完全二叉树(其深度为log2(n)+1)的结点按层序编号(从第1层到第log2(n)+1层,每层从左到右),对任一结点 i(1<= i <=n)有: (根结点下标为1开始) 1、如果 i=1,则结点 i 是二叉树的根,无双亲;如果 i>1,则其双亲是结点 [ i/2 ] 2、如果 2i >原创 2015-06-24 09:48:26 · 474 阅读 · 0 评论 -
斐波那契查找算法
对于斐波那契查找算法的学习,建议根据程序代码,找一组数据一步步测试一下,会比较容易加深理解。 斐波那契查找算法类似于折半查找算法(二分查找算法) 对于折半查找:其 mid 处于 low 和 high 的中间。 而斐波那契查找算法,其 mid 处于 low 和 high 的黄金分割点处。 /斐波那契数列,越往后其前一数值与后一数值的比值会越来越接近于0.618/#include <iostre原创 2015-06-01 17:38:01 · 925 阅读 · 0 评论 -
希尔排序
前面几篇文章,如冒泡排序、简单选择排序和直接插入排序,它们的算法复杂度皆为 o(n^2),然而是否所有的排序算法,都无法突破这个数字,显然不是。希尔排序(Shell sort)是D.L.Shell于1959年提出的一种排序算法,它是最早突破 o(n^2)这个复杂度的算法之一。希尔排序与直接插入排序的异同点: 1、希尔排序时插入排序方法的一种,其原理为分组插入排序。它将无序数组分割为若干个子序列,子原创 2015-06-18 10:14:29 · 522 阅读 · 0 评论 -
简单选择排序
选择排序法的初步思想来源: 冒泡排序的思想就是不断地在交换,通过交换完成最终的排序,这和做股票短线频繁操作的人类似。我们可不可以像只有在时机非常明确到来时才出手的股票高手一样,也就是在排序时找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作呢? /这段话我挺喜欢的,好算法就是这样,一个玩股票的高手/简单选择排序法(Simple Selection Sort)就是通过 n -原创 2015-06-12 14:27:09 · 469 阅读 · 0 评论 -
数据结构与算法之七大排序总结
排序基本概念: 稳定性:假设Ki = Kj(1排序分类: 1)内排序:在排序整个过程中,待排序的所有记录全部被放置在内存中。 2)外排序:是由于排序的记录个数太多,不能同时放置在内存中,整个排序过程需要在内外存之间多次交换数据才能进行。 对内排序来说,排序算法的性能主要受3个方面影响: 1)时间性能: 排序算法的时间开销是衡量其好坏的最重要标志。 在内排序中,主要进行两种操作:比较原创 2015-07-02 10:05:03 · 535 阅读 · 0 评论 -
冒泡排序(C++语言描述)
冒泡排序(Bubble Sort):一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。其时间复杂度为:O(n^2) 以下是我写的代码及其程序结果,程序用C++写的,因为想回顾以下C++的基本知识,包括类、构造函数、友元等概念在程序中被应用到。 一直用C语言写程序,渐渐地C++的一些写法都忘了,所以我在复习数据结构的过程中,尝试用C++的思想和语言来写原创 2015-06-12 14:13:50 · 2985 阅读 · 0 评论 -
单链表基本操作总结
链表基本概念: 链表:线性表的链式存储。 数据域:存储数据信息。即数据。 指针域:存放下一节点的位置信息。即该指针指向下一节点。单链表:每一个节点node:一个数据域 + 一个指针域。 头节点: 1、数据域可以存放线性表长度等公共信息。 2、指针域,指向第一个节点(数据域)的位置。 3、头结点不一定是链表的必须元素。不过有了头结点,对第一个元素节点前插入和删除元素,就和其它节点一原创 2015-07-02 22:07:02 · 1900 阅读 · 0 评论 -
双向链表基本操作
双向链表的情况与单链表类似,只是增加了一个前置链(即指向前一结点的指针域) 算法等,与单链表很相似。只是需要安置好前向指针域。注意点:在写关于链表的插入删除操作时,一定要注意该结点是不是最后一个结点,以免出现 p->next == NULL,p->next->next 未定义的情况,从而导致程序在特定条件下(比如你删除最后一个节点)出错。 也就是需要注意,最后一个节点和其他节点的操作不同,需要分原创 2015-07-03 15:13:18 · 400 阅读 · 0 评论 -
二叉树遍历(图解)
二叉树的顺序存储结构就是用一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系。—–>一般只用于完全二叉树 链式存储—–>二叉链表 定义: lchild | data | rchild(两个指针域,一个数据域)typedef struct Node { ElemType data; struct Node *lchild原创 2015-07-11 16:59:10 · 35792 阅读 · 1 评论 -
树(基本概念及存储结构)
树的定义—-递归(两者相联系) 根节点:唯一 节点的度:节点拥有的子树数,度为0—>称为终端节点或叶节点 树的度:树内各节点的度的最大值 内部节点:除根节点外的节点 孩子(child):节点的子树的根 称为该节点的 孩子,反过来,称为双亲(parent) 兄弟(sibling):同一双亲的孩子之间的关系 节点的祖先:从根到该节点所经分支上的所有节点 节点层次:根为第一层,根的孩子为第原创 2015-07-11 16:20:26 · 856 阅读 · 0 评论 -
队列基本操作(链式结构)
基本概念: 队列:是只允许在一端进行插入操作,而在另一端进行删除操作的线性表(或单链表,无头结点)。 即:先进先出 队尾:允许插入的一端;队头:允许删除的一端队列示意图如下: 注意next指针的指向与链栈不同 代码如下:#include <iostream>using namespace std;typedef struct node{ int data; struct n原创 2015-07-05 21:11:39 · 662 阅读 · 0 评论