![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
编程与算法
梦想与坚持
勤能补拙是良训,每个人生来都不是优秀的。
展开
-
链表(二)——单向链表的基本操作(创建、删除、打印、结点个数统计)
1.指针的联动通过两个指针分别指向前驱和后继结点,并在单向链表上进行移动,当指针指向待处理的结点时,该结点的前驱也有指针指向。2.设有一个无序单向链表,且数据域的值均不相同,使指针pmin指向最小值结点,并使指针prem指向最小值结点的前驱结点:代码片段:for(p = head; p; q = p, p = p->next){ if(pmin->data > p->原创 2014-07-16 20:49:51 · 2578 阅读 · 0 评论 -
判断一个无符号型整数是否是2^n
题目:给出一个无符号型整数,判读其是否是2^n?原创 2014-08-09 15:13:43 · 1152 阅读 · 0 评论 -
笔试题&面试题:给定n个数,要求比较次数1.5n同时找出最大值和最小值
写出一个算法,对给定的n个数的序列,返回序列中的最大和最小的数.设计出一个算法,只需要执行1.5n次比较就能找到序列中最大和最小的数吗?能否再少?分析:要求比较次数为1.5n,使用一般的逐个遍历每个元素然后判断其是否为最大最小值是需要2n次的比较的,所以这样的方法是行不通的。现在考虑采用,每次从数组中取出两个元素,判断其大小,然后再分别判断其是否是最大或最小值,这样一次处理两个元素,每一次原创 2014-08-10 10:50:40 · 5220 阅读 · 0 评论 -
单源最短路径(Dijkstra)——贪心算法
Dijkstra算法是解单源最短路径问题的贪心算法。其基本思想是,设置顶点集合点集合S并不断地做贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设u是G的其一顶点。把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组Distance记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度原创 2014-08-09 11:55:56 · 46626 阅读 · 4 评论 -
汉诺塔——递归
经典汉诺塔问题描述:假设有3个分别命名为X,Y,Z的塔座,在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,……n个圆盘。现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵守下列规则:(1)每次只能移动一个圆盘;(2)圆盘可以插在X,Y和Z中的任一塔座上;(3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。求n个盘至少需移动的次数。分析:设原创 2014-08-13 12:04:08 · 921 阅读 · 0 评论 -
八皇后问题——递归+回溯法
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。求解过程: 采用遍历的办法,就是原创 2014-08-13 17:33:48 · 1857 阅读 · 0 评论 -
排序——堆排序-大根堆(大顶堆)
1.小根堆若根节点存在左子女则根节点的值小于左子女的值;若根节点存在右子女则根节点的值小于右子女的值。2.大根堆若根节点存在左子女则根节点的值大于左子女的值;若根节点存在右子女则根节点的值大于右子女的值。3.结论(1)堆是一棵完全二叉树(如果公有h层,那么1~h-1层均满,在h层连续缺失若干个右叶子)。(2)小根堆的根节点的值是最小值,大根堆的根节点的值是最大值。(3)原创 2014-08-12 12:46:40 · 23190 阅读 · 6 评论 -
排序——选择排序
在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。程序流程:第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换;第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换;以此类推.....原创 2014-08-14 15:50:29 · 918 阅读 · 0 评论 -
排序——插入排序法
插入排序法图示:原创 2014-04-14 16:01:25 · 958 阅读 · 0 评论 -
排序——希尔排序
希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2希尔排序的实现代码:#include using name原创 2014-08-14 12:05:01 · 1073 阅读 · 0 评论 -
排序——冒泡排序(三种方法)
冒泡排序的基本思想: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。关于程序中4中冒泡排序写法的说明:bubble_sort1:基本的冒泡排序的写法。bubble_sort2:基本冒泡排序的不同写法,基本的冒泡排序是每原创 2014-08-15 12:13:20 · 5761 阅读 · 0 评论 -
二叉树(一)——二叉树的基本实现(数组实现和链表实现)
1.树是一种数据结构,树的一些相关的术语:结点的度:一个结点的后继结点的个数。树的度:树中度值最大的结点的度被称为树的度。树的深度:树的层次数。分支结点:度值大于0的结点,分支结点至少含有一个后继,分支结点也称为非终端结点。叶子结点:树中的度值为0的结点。双亲结点:树中某个结点的前驱结点,也成为父节点。子女结点:树中某结点的后继结点。兄弟结点:树中同一层的结点。原创 2014-08-05 16:14:39 · 7463 阅读 · 0 评论 -
排序——归并排序
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路原创 2014-08-18 12:09:39 · 905 阅读 · 0 评论 -
排序——快速排序法
快速排序法基本思想: 快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。程序代码:#include原创 2014-08-15 16:07:11 · 829 阅读 · 0 评论 -
排序——基数排序
基数排序(radix sort)是属于“分配式排序”(distribution sort),基数排序法又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。排序思想: 首先按照数据的最低位(个位)将数据分配到0~9十个桶中,然后依次将这些桶中的数据取出来得到按照个位排序后的结果,然后原创 2014-08-19 10:57:47 · 1061 阅读 · 4 评论 -
面试题&笔试题:求1+x+x^2+x^3+...+x^n的和(尽可能少的使用乘法运算)
题目:求1+x+x^2+x^3+...+x^n的和(尽可能少的使用乘法运算)。分析:可以使用折半的方式,每次计算两个的和,比如首先计算出1+x的值保存,然后用保存的这个值乘以x^2可以得到后面两项的值再保存,依次类推直到计算结束。需要注意的是如果n是奇数或者偶数的情况是不同的,当n为奇数的时候就完全按照前面的方法计算即可,但是n为偶数的时候比较麻烦,因为最后一项的计算比较困难,所以当n为偶数的原创 2014-09-16 20:36:34 · 21473 阅读 · 1 评论 -
笔试题&面试题:设计一个复杂度为n的算法找到单向链表倒数第m个元素
设计一个复杂度为n的算法找到单向链表倒数第m个元素.最后一个元素假定是倒数第0个.提示:双指针查找相对于双向链表来说,单向链表只能从头到尾依次访问链表的各个节点,所以如果要找链表的倒数第m个元素也只能从头到尾进行查找,在查找的过程中,设定两个指针,其中p指针指向当前访问的节点,q指针指向p之前的节点,且两者之间相距m个节点,这样,当p指针指向最后一个节点时,那q指针指向的元素就是倒原创 2014-08-10 11:43:17 · 3424 阅读 · 0 评论 -
最长公共子序列问题—— 动态规划法
经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。【问题】 求两字符序列的最长公共字符子序列问题描述:字符序列的子原创 2014-08-09 17:19:47 · 1922 阅读 · 0 评论 -
0-1背包问题——动态规划法
问题描述:给定n种物品和一背包。物品i的重量是w[i],其价值为v[i],背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?分析:对于一种物品,要么装入背包,要么不装。所以对于一种物品的装入状态可以取0和1。设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-1背包问题。数据:物品个数n=5,物品重量w[5]={2,2,6,5,4},物品价值v[5]={6原创 2014-08-09 08:23:49 · 9861 阅读 · 4 评论 -
链表(三)——链表删除冗余结点&插入结点到有序链表
1.一个以递增方式排列的链表,去掉链表中的冗余值。思路一:设有两个指针p和q,使p不动,q依次往后循环直到p->data不等于q->data,再将中间的冗余数据删除。思路二:设有两个指针p和q,使p在前,q在后,只要找到一个冗余就删除一个,依次往后删除。输入的链表:1 3 3 3 3 6 6 8 9 10删除后的链表:1 3 6 8 9 10比较两种思路,思路二的想法相比于思路原创 2014-07-19 16:39:47 · 1182 阅读 · 0 评论 -
链表(四)——带表头的单向链表
1.带表头的单向链表(1)不带表头的单向链表在实现插入和删除时必须区分头结点和其他节点的处理。(2)使用带表头的单向链表的好处:不用考虑头结点的单独处理。表头节点:数据域没有值,指针域指向单向链表中数据域含值的第一个结点。2.代表头的单向链表的基本操作#include #include #define NULL 0typedef struct node { int原创 2014-07-20 10:53:02 · 3618 阅读 · 0 评论 -
链表(五)——单向循环链表
1.单向循环链表区分单向链表和单向循环链表:单向循环链表的尾指针指向头结点。2.单向循环链表的基本操作#include #include #define NULL 0typedef struct node { int data; struct node *next;}ElemSN;ElemSN * creat_link(int ms); //创建一个单向循环链表原创 2014-07-22 22:05:05 · 2134 阅读 · 1 评论 -
笔试题&面试题:找出一个数组中第m小的值并输出
题目:找出一个数组中第m小的值并输出。代码:#include int findm_min(int a[], int n, int m) //n代表数组长度,m代表找出第m小的数据{ int left, right, privot, temp; int i, j; left = 0; right = n - 1; while(left < right) { privo原创 2014-07-25 20:54:58 · 1734 阅读 · 1 评论 -
栈(一)——栈的基本操作
1.栈的简介栈是一种后入先出的数据结构,一般包含两种最基本的操作:入栈(push)和出栈(pop)。入栈操作:top指针上移,元素入栈。出栈操作:top指针下移。栈空的条件:top == bottom栈满的条件:top == maxsize-12.有数据序列1 2 3一次存入一个栈stack中,则出栈顺序可以为以下四种:1,2,3; 2,1,3; 3,2,1; 1,3,原创 2014-07-28 21:52:34 · 3009 阅读 · 0 评论 -
递归
1.递归的定义递归是函数的自我调用,用于解决规模减小,但性质不变的问题。2.递归的两大重要点(1)结束点:递归是函数的自我调用,那么在什么时候才算自我调用的结束?(2)递归过程:如何拆解问题的规模,使问题的规模一步步的减小?3.递归的实战(1)输出一个十进制正整数(小于65536)的二进制代码。#include void decimal_2_binary(int原创 2014-08-04 11:14:50 · 804 阅读 · 0 评论 -
队列(二)——队列的链表实现方式
1.队列的单向链表的实现方法return只可以返回一个值,单向循环链表来实现队列的时候可以只保留一个指针,因为保留rear指针能够很方便的表示出front指针,所以保留rear指针。另外由于链表的第一个结点处理比较特殊,所以在初始化的时候需要单独处理。链表实现的队列思想也是第一个单元作为头结点,不存放数据,rear指针指向的总是尾结点(在循环链表中也就是头结点的上一个结点)。2.实现方原创 2014-08-04 17:48:22 · 2031 阅读 · 0 评论 -
栈(二)——用栈来实现逆波兰式
中缀双目表达式叫做波兰式,后缀双目表达式叫做逆波兰式。波兰式 逆波兰式2+3 2 3 +2+3*5 2 3 5 * +2*3+5原创 2014-07-29 21:18:15 · 1447 阅读 · 0 评论 -
队列(一)——队列的数组实现方式
1.队列的概念队列是一种特殊的线性表,只允许在队列的一端进行插入而在另一端进行删除。队列一般拥有队首(front指针)和队尾(rear指针),当一个队列并未存入数据的时候,front和rear指针均指向队首。入队的操作:rear后移,存入数据在rear指向的单元,队满不可入队,这同时也表明front总是指向队首元素的前驱。出队的操作:front后移,元素出队,队空不可出队。注意原创 2014-08-04 16:41:50 · 5840 阅读 · 0 评论 -
链表(一)——创建一个最基本的单向链表
1.结点链表中用来存储一个数据的存储单元。一个链表至少需要由两部分组成,就是数据域和指针域,一般形式的结点定义为:struct node{ Elem data; //Elem类型泛指基本数据类型 struct node *next;}typedef struct node Elemsn;以上两步等价于:typedef struct node{原创 2014-07-14 21:33:52 · 1351 阅读 · 0 评论 -
二叉树(二)——遍历、深度统计、叶子结点统计、结点统计
1.二叉树的相关算法的实现(链表)。#include #include #define NULL 0typedef struct tree{ int data; struct tree *left, *right;}ElemBT;void create_btree(ElemBT *root, int list[], int n) /*n表示list数组中元素的个数*/{原创 2014-08-06 10:38:59 · 2085 阅读 · 0 评论 -
笔试题&面试题:输入一个维度,逆时针打印出一个指定的矩阵
题目:用户给定一个维度,打印出指定的一个矩阵,例如用户给定10,输出应该如下图所示:程序如下:#include #include int main(){ int dimension; int *p; int startx, starty, endx, endy; int i, j, value = 0; printf("Please input dimension原创 2014-07-24 15:41:31 · 1722 阅读 · 0 评论 -
笔试题&面试题:顺时针输出一个矩阵
题目:顺时针输出一个矩阵(N*N)。假设一个矩阵为: 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这个问题在网上也搜集了一下答案,没有什么巧妙的办法,所以下面给出的是完全按照顺时针走向输出的一个代码(自己亲手编写原创 2014-06-27 09:45:39 · 2665 阅读 · 0 评论 -
笔试题&面试题:求1+11+111+1111+...+n个1的和中有多少个1?
题目:求1+11+111+1111+...+n个1的和中有多少个1?解答思路:从个位往最高位计算,比如一直加到2014个1,那么个位一共有2014个1相加,先判断相加之后的和最低位(个位是否为1),相加之后的进位为201,其中2,0,1分别对应千位,百位和十位的进位;接下来求十位的和,十位为2013个1加上上一次的进位1,算出本次的进位(相对于十位的计算结果来说,个位的计算结果中只有20才是进原创 2014-06-27 17:07:24 · 6312 阅读 · 3 评论 -
笔试题&面试题:30个人一共花费50先令,求解男人,女人和小孩的人数分别为多少?
马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭共花了50先令,每个男人各花3先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?原创 2014-06-26 11:22:03 · 8703 阅读 · 0 评论 -
n的阶乘结果中末尾有多少个零?
题目:n的阶乘中一共有多少个零?解答:产生零的结果只能有一种可能性那就是2*5=10,然而n的阶乘本质上是可以拆解为很多2和5以及其他不包含2和5的乘数的积,例如5的阶乘:1*2*3*4*5=1*2*3*2*2*5。按照这个思路,将n的阶乘乘积的每一项进行拆解,看看可以拆解出多少个2和多少个5,然后取2的个数和5的个数中最小的即可。程序代码如下:#include int compu原创 2014-09-03 21:38:43 · 1514 阅读 · 5 评论