![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法与数据结构
Geek_ymv
公众号 geekymv
展开
-
合并两个有序数组
需求有两个有序数组a[] 和 b[],将它们合并成数组c[],要求数组c[]也是有序数组。例如 数组a[] = {4, 6}; 数组b[] = {1, 2, 3, 5}; 那么合并后的数组c[] = {1, 2, 3, 4, 5, 6}。实现过程1、定义数组c[] 长度为数组a[] 的长度与数组b[] 长度之和;2、定义三个变量i, j, k 分别指向数组a[]、数组b[] 和 数组c[] 的起始下标;3、遍历数组a[] 和 数组b[] ,比较a[i] 和 b[j] 大小,将较小的一个值放入c[原创 2021-01-19 23:03:51 · 590 阅读 · 0 评论 -
详解选择排序
选择排序(Selection Sort)与插入排序有点类似都有已排序区间和未排序区间,选择排序是在未排序区间找到最小元素,然后将其添加到已排序区间末尾(与未排序区间的第一个元素交换位置)。开始时已排序区间为空,未排序区间就是整个待排序的数组,首先找到数组中最小的那个元素,然后将它和数组的第一个元素交换位置(如果第一个元素就是最小元素,那么它就和自己交换)。这个时候第一个元素就在已排序区间,剩余的元素在未排序区间。接下来,在剩下的元素(未排序区间)中找到最小元素,将它与数组的第二个元素交换位置。如此往复,直原创 2021-01-01 19:51:01 · 159 阅读 · 2 评论 -
详解插入排序
插入排序(Insertion Sort)的过程就像我们排序扑克牌一样(从左到右,从小到大)。开始时我们左手为空,然后我们从桌子上拿起一张牌并将它插入到左手中正确的位置,为了找到这个位置,我们将这张牌与左手中从右向左的每张牌进行比较,直到找到比它小或相等的牌的后面。与排序扑克牌类似插入排序的原理是:将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素,接着取未排序区间中的元素(数组的第二个元素),在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一原创 2020-12-17 22:11:59 · 181 阅读 · 0 评论 -
详解冒泡排序,不能再详细了!
在我们日常开发中,排序是非常常见的一种需求,提供一组数据元素,把这些数据元素按照一定的规则进行排序。比如微信公众号的文章是按照文章的发布时间进行排序,再比如在电商类APP中查询一些商品,按照商品的价格进行排序,更复杂的会根据用户的喜好进行排序。在平常的项目中,简单的排序需求我们可以使用数据库提供的order by 语句进行排序,我们也可以使用JDK提供的工具方法(比如Arrays.sort())进行排序,这些排序方式都是别人封装好的,内部肯定使用了某种排序算法。我们有必要去了解一些经典的排序算法,接下来的原创 2020-12-11 21:23:40 · 261 阅读 · 0 评论 -
从一个故事开始讲递归
讲个故事从前有座山,山上有座庙,庙里有个老和尚和一个小和尚,一天,老和尚给小和尚讲了一个故事,故事的内容是“从前有座山,山上有座庙,庙里有个老和尚和一个小和尚,一天,老和尚给小和尚讲了一个故事,故事的内容…”。这个故事自己套着自己,没完没了,像是某种特征在不断重复,这就是我们今天要将的主题「递归」了。递归递归(Recursion)是一种非常广泛的算法,更是一种编程技巧。英文 Recursion 的中文翻译“递归”表达了两个意思“递”+“归”,去的过程叫做递,回来的过程叫做归,在编程语言中递归可以简单原创 2020-12-07 23:33:36 · 1142 阅读 · 0 评论 -
表达式求值
在上篇文章的最后留下了一个问题,求表达式4 + 2 * 3 - 10/5 的值。对于计算机来说,它看到的就是用户输入的字符串,这个字符串是由运算符和数字组成的。为了使问题简单化,我们这里仅讨论最常见的加减乘除四则运算。那么如何解析出运算符和数字以及如何处理运算符的优先级问题呢?我们可以通过上篇文章学习到的栈来解决,这里需要两个栈,一个栈用来保存数字,另一个栈保存运算符。下面我将一步一步展示表达式4 + 2 * 3 - 10 / 5 的计算过程:为了解析出操作数和运算符我们需要从左向右遍历表达式。当遇.原创 2020-11-15 22:51:39 · 324 阅读 · 0 评论 -
栈
在之前的文章中详细介绍过队列这种数据结构,队列是一种先入先出(FIFO)的线性表。和队列相反,今天要讲的栈(stack)是一种先入后出(first in last out,FILO)的线性表。举一个生活中的例子,我们平时放盘子的时候是从上往下一个一个的放,取的时候我们也是从上往下一个一个的取,不能从中间任意取出。栈是一种操作受限的线性表,只能在一端进行插入和删除数据。允许插入和删除的一端为变化的一端,称为栈顶(top),另一端为固定的一端,称为栈底(bottom)。最先放入栈中的元素在栈底,最后放入的元素原创 2020-11-15 22:43:01 · 414 阅读 · 0 评论 -
面试官让我手写一个双向链表
笔者之前参加过一场视频面试,其中一个问题是说说ArrayList、LinkedList的区别,参加过面试的同学可能经常会被问到这个问题,当我说到ArrayList是基于数组实现的LinkedList是基于双向链表实现的时候,面试官说那你能写一个双向链表吗?因为面试邀请邮件中告知面试时需要写代码,笔者在面试之前虽然看了一些数据结构方面的知识点,但当真正手写的时候还是费了一番功夫。趁着这次周末有空,写一篇文章总结下双向链表。在前面的文章单链表的CRUD中详细介绍过单链表的插入、查找、修改和删除操作。我们可以原创 2020-11-10 11:48:22 · 672 阅读 · 0 评论 -
约瑟夫问题
问题来源约瑟夫问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家,他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定杀掉谁,约瑟夫和另外一个人是最后留下的两个人。约瑟夫说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫把他的存活归因于运气或天意,他不知道是究竟是哪一个。约瑟夫问题是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并原创 2020-10-31 16:39:47 · 4794 阅读 · 0 评论 -
单向循环链表(Java版)
前面的文章中介绍到单链表,它的尾结点(最后一个结点)的指针域next都是指向null,如下图:单链表的指针域只存储了向后的指针,到了尾结点就无法继续向后的操作。本篇文章将介绍单向循环链表,它和单链表的区别在于结尾点的指针域不是指向null,而是指向头结点,形成首尾相连的环。这种首尾相连的单链表称为单向循环链表。循环链表可以从任意一个结点出发,访问到链表中的全部结点。和单链表一样,为了使空链表与非空链表处理一致,我们通常会设置一个头结点。当然,之前提到的单链表和本文的单向循环链表都不是必须要有头结点原创 2020-10-14 23:44:56 · 669 阅读 · 0 评论 -
单链表的反转(Java版)
上一篇文章单链表的CRUD 介绍了单链表的查找、插入、删除、修改等操作,本篇文章是在上一篇的基础上实现单链表的反转功能。所谓反转就是将链表整体反过来,比如原链表是 a —> b —> c —> null,则反转后的链表是 c —> b —> a —> null。如下图所示:实现思路:1.首先新创建一个链表2.遍历原链表把原链表中每个结点的数据域依次插入到新链表头结点后面,比如依次将a、b、c 这3个数据域依次添加到新链表头结点后面:/** * 单链表的反转原创 2020-10-11 23:22:51 · 198 阅读 · 0 评论 -
单链表的CRUD(Java版)
我们知道数组需要一块连续的内存空间来存储数据,数组中逻辑上相邻的两个元素在物理位置上也相邻。而链表就不一样了,它不需要一块连续的存储空间,它通过指针将一组零散的内存块串起来。我们把内存块称为结点(Node)。链表为了将所有的结点串起来,链表的每个结点除了存储数据外,还需要存储一个指向其下一个结点位置的指针。所以链表有两块存储区域,其中存储数据的域称为数据域,存储下一个结点存储位置的域称为指针域。单链表我们在第一个结点之前增设一个结点,叫做头结点,头结点的数据域可以不存储任何信息,也可以存储如链表的原创 2020-09-27 00:58:26 · 249 阅读 · 0 评论 -
循环队列(Java版)
在上一篇文章的最后,我们提到了可以用循环队列来解决顺序队列只能使用一次的问题。在循环队列中,我们依然需要使用两个变量head(指向队列中的第一个元素,初始值为0)和tail(指向队列中最后一个元素的下一个位置,初始值为0)。在顺序队列中,我们需要判断队空和队满的情况,同样在循环队列也需要判断队满和队空的情况。上图中这个队列大小size为8,开始队列空时head和tail都指向下标0。依次添加元素a、b,此时如上图所示head位置不变,tail向后移指向下标为2的位置。继续添加元素c、d、e、f、g,原创 2020-09-22 22:18:47 · 323 阅读 · 0 评论 -
顺序队列(Java版)
上一篇文章介绍了队列的基本概念,并且通过画图的形式分析了入队出队的过程。本篇文章我将通过Java代码实现顺序队列。话不多说,先上代码。public class ArrayQueue { private Integer[] items; private int size; private int head = 0; private int tail = 0; public ArrayQueue(int size) { this.size =原创 2020-09-09 23:43:10 · 346 阅读 · 0 评论 -
队列
队列队列是一个有序列表,可以用数组或是链表实现。你可以想象下10年前去火车站排队买票的场景,在同一个窗口排成长长的队,先来的先买,后来的只能站在最后面排队,不允许插队。先来的人先买票(先进先出),后来的后买票(后进后出)。遵循先入先出的原则,即:先存入队列的数据,要先取出,后存入的要后取出。示意图:队列最基本的两个操作:入队(enqueue),放一个数据到队列的尾部;出队(dequeue)从队列头部取一个元素。顺序队列和链式队列用数组实现的队列叫顺序队列,用链表实现的队列叫链式队列。本篇文章原创 2020-09-08 23:34:00 · 273 阅读 · 0 评论 -
稀疏数组
稀疏数组(Sparse Array)应用场景假设我们正在开发一个五子棋程序,有存盘退出和复盘的功能。在五子棋游戏中,我们现在要开发存盘退出功能,那么我们首先需要记录棋盘上黑白子的位置,棋盘其实可以使用二维数组来表示,那么我们可以使用二维数组来保存黑白子的位置坐标,如下图所示的五子棋游戏中我们可以使用二维数组记录棋盘,如下所示:我们其实没有必要保存整个棋盘的位置,而是只保存有黑白子的位置...原创 2020-04-16 20:57:39 · 214 阅读 · 0 评论 -
(2013-4-1)数据结构实验一:打印成绩最高和最低的学生信息
#include#define MAXNUM 20typedef struct node{ int num; char name[20]; float score;}ElemType;//输入数据函数void Create(ElemType stu[],int *n){ struct node *k; int i = 1; printf("Please input n原创 2013-04-05 14:36:34 · 1119 阅读 · 0 评论 -
(2013-4-21)数据结构实验三:狐狸逮兔问题(方法一:顺序表实现)
/*问题描述:围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:"可以,但必须找到我,我就藏身于这十个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第三次隔2个洞(即6号洞)找,以后如此类推,次数不限。"但狐狸从早到晚进进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?*/#include#include#define OK 1#define OVERFL原创 2013-04-23 16:33:45 · 4733 阅读 · 1 评论 -
(2013-4-21)数据结构实验三:狐狸逮兔问题(方法二:链式)
#include#include#define OK 1#define OVERFLOW -2typedef int status;typedef struct Snode{ int key; int flag; struct Snode *next;}Snode,*LinkList;//初始化status InitList_Sql(LinkList *L){原创 2013-04-23 22:38:34 · 2820 阅读 · 0 评论 -
单链表的创建、插入、删除等操作
#include #include #include #define OK 1#define ERROR 0typedef int Status;typedef int ELemType;/*用结构指针描述单链表*/typedef struct Node{ ELemType data; //数据域 struct Node* next; //指针域原创 2013-05-15 21:12:53 · 781 阅读 · 0 评论 -
数据结构练习:用顺序栈实现进制间的转换
/*用顺序栈实现进制的转换*/#include#include#define OK 1#define ERROR 0#define OVERFLOW 0typedef int SElemType;typedef int Status;#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef struct原创 2013-05-14 18:07:54 · 3344 阅读 · 0 评论 -
算法实验一:二分查找算法改进: 当搜索元素x不存在时,返回小于x的最大元素位置i和大于x的最小元素位置j. 当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
import java.util.Map;import java.util.Scanner;public class RandomArray { public static void main(String[] args) { int arr[] = new int[10]; //随机生成数组 Tools.randomArr(arr, arr.length); T原创 2013-11-21 16:52:49 · 5766 阅读 · 0 评论 -
学习算法-选择排序
/** * 选择排序 * 1.找到数组中最小的元素; * 2.将它和数组的第一个元素交换位置; * 3.再剩下的元素中找到最小的元素; * 4.将它与第二个元素交换位置; * 5.如此往复,直到将整个数组排序 */public class SelectionSort { public static void main(String[] args) { in...原创 2019-04-11 19:44:17 · 129 阅读 · 0 评论 -
倒置
package P0;import java.util.Scanner;public class NumberDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final int n =原创 2012-12-14 19:37:27 · 650 阅读 · 0 评论