数据结构与算法
元气少女帕吉
文不能测字,武不能防身
展开
-
常用的查找方法之二分查找
二分查找:二分查找适用有序数列二分查找有两种一种递归,一种非递归思路:1首先确定该数组的中间的下标 mid=(left + right)/22然后让需要查找的数,findVal和arr[mid]比较3。1如果:findVal > arr[mid] 说明你要查找的数在mid的右边,因此需要递归向右查找3.2 如果findVal < arr[mid] 说明你要查找的数在mid的左边,因此需要递归向左查找3.3 findVal = arr[mid] 找到了,返回递归退出的条件:1找原创 2021-01-14 20:20:08 · 196 阅读 · 0 评论 -
常用的查找方法之线性查找
常用的查找方法:顺序(线性)查找二分查找/折半查找插值查找斐波那契查找线性查找public class SeqSearch { public static void main(String[] args) { //可以有序可以无序 int arr[] = {1, 9, 11, -1, 34, 89}; int index = seqSearch(arr, 11); if(index == Integer.MAX_VALUE) { System.out.println(原创 2021-01-14 20:16:58 · 196 阅读 · 0 评论 -
基数排序radix sort
基数排序(radix sort) 属于“分配式排序”,又称“桶子法”。它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法稳定性:打比方你的数组里有两个2,稳定性排序排序完了后,你之前在前面的2排序完后还是在另一个2的前面基数排序是桶排序的扩展将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列原创 2021-01-13 09:49:44 · 194 阅读 · 0 评论 -
归并排序
//归并排序/**MERGE-SORT是利用归并的思想实现的排序方法,该算法采用经典的分治策略;分而治之*/public class MergeSort { public static void main(String[] args) { int[] arr = {8, 4, 5, 7, 1, 3, 6, 2}; int temp[] = new int[arr.length]; mergeSort(arr, 0, arr.length - 1, temp); System原创 2021-01-12 19:22:20 · 83 阅读 · 0 评论 -
快速排序Quicksort
/**快速排序Quicksort对冒泡排序的一种改进通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列*/public class Quicksort { public static void main(String[] args) { int arr[] = {-9, 78, 0, 23, -56, 70}; quickSort(ar原创 2021-01-12 18:19:19 · 90 阅读 · 0 评论 -
希尔排序ShellSort
// 希尔排序/*** 希尔排序也是一种插入排序,简单插入排序的高效版本,也成为缩小增量排序* 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的* 关键词越来越多,当增量减至1时,整个文件恰好分成一组,算法终止*///交换式 public static void shellSort(int[] arr) { int temp = 0; for (int gap = arr.length / 2; gap > 0; gap /=原创 2021-01-12 17:38:33 · 76 阅读 · 0 评论 -
插入排序
/**插入排序属于内部排序法,是对预排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的基本思想:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表只包含一个元素,无序表中包含n-1个元素排序过程中每次从无序表中取出第一个元素,把他的排序码依次与有序表元素的排序码进行比较,将他插入到有序表中适当的位置,使之成为新的有序表*///插入排序 public static void inserSort(int[] arr) { for (int i = 1; i &原创 2021-01-12 16:11:19 · 105 阅读 · 0 评论 -
选择排序
选择排序(select sorting):选择排序属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置,达到排序的目的。选择排序(select sorting)基本思想:第一次从arr[0]~arr[n-1]中选取最小值,与arr[0]交换第二次从arr[1]~arr[n-1]中选取最小值,与arr[1]交换依次类推第n-1次从arr[n-2]~arr[n-1]中选取最小值,与arr[n-2]交换public class SelectSort { public s原创 2021-01-12 13:19:59 · 81 阅读 · 0 评论 -
冒泡排序
这里写目录标题冒泡排序冒泡排序冒泡排序(Bubble Sorting)的基本思想:通过对待排序序列从前向后,依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底的气泡一样逐渐向上冒。一共进行数组大小-1次的循环每一趟排序的次数逐渐减少如果某次排序中,没有发生一次交换,可以提前结束排序public class BubbleSort { public static void main(String[] args) { int arr[] = {9, 2, 4,原创 2021-01-12 10:11:10 · 103 阅读 · 0 评论 -
排序算法介绍
排序算法的介绍排序也成排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程。排序的分类:1内部排序:需要处理的所有数据都加载到内部存储器中进行排序2外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序常见的排序算法:直接插入排序希尔排序简单选择排序堆排序冒泡排序快速排序归并排序基数排序算法的时间复杂度时间频度:一个算法中的语句执行次数称为语句频度或时间频度,记为T(n)时间复杂度:一般情况下,算法中的基本操作语句的重复执行原创 2021-01-12 09:31:20 · 91 阅读 · 0 评论 -
递归解决8皇后问题八皇后回溯
/** * @ClassName: Queue8 * @author 63417 * @Description: TODO * @date 2021年1月11日 */public class Queen8 { //定义一个max表示共有多少个皇后 int max = 8; //定义数组array,保存皇后放置位置的结果 int[] array = new int[max]; static int count = 0; public static void main(String[原创 2021-01-11 22:32:36 · 144 阅读 · 0 评论 -
迷宫回溯问题递归最短路径
public class Labyrinth { public static void main(String[] args) { //创建一个二维数组,模拟迷宫 //地图 int[][] map = new int[8][7]; //使用1表示墙,先把上下全部置为1 for (int i = 0; i < 7; i++) { map[0][i] = 1; map[7][i] = 1; } //左右全部置为1 for(int i = 0; i < 8原创 2021-01-11 20:36:34 · 431 阅读 · 0 评论 -
递归java肯定不是最详细的递归说明
递归:方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题。递归的规则:1、当程序执行到一个方法时,就会开辟一个独立的空间(栈)2、每个空间的数据(局部变量),是独立的图片来自网络递归的注意事项1、执行一个方法时,就创建一个新的受保护的独立空间(栈空间)2、方法的局部变量是独立的,不会互相影响3、如果方法中使用的是引用类型变量,就会共享该引用类型的数据4、递归必须向退出递归的条件逼近,否则就是无限递归(StackOverflowError)5、当一个方法执行完.原创 2021-01-11 09:43:39 · 84 阅读 · 0 评论 -
简单逆波兰计算器的实现后缀表达式
public class InversePolish { public static void main(String[] args) { //先定义一个逆波兰表达式,数字和符号使用空格隔开 String expression = "4 4 + 5 * 6 -"; //先将"3 4 + 5 * 6 -"放入ArrayList中 //将ArrayList传递给一个方法,遍历ArrayList配合栈完成计算 List<String> rpnList = getListStrin原创 2021-01-10 21:18:49 · 91 阅读 · 0 评论 -
前缀(波兰表达式)、中缀、后缀表达式(逆波兰表达式)
前缀表达式:前缀表达式又称波兰表达式,前缀表达式的运算符位于操作数之前。例如:(3+4)*5-6 对应的前缀表达式为 - * + 3456前缀表达式的计算机求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对他们做相应的计算(栈顶元素和次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。中缀表达式:中缀表达式就是常见的运算表达式,如(3+4)*5-6中缀表达式对计算机来说不好操作,因此在计算结果时,往往会将原创 2021-01-10 20:04:38 · 268 阅读 · 0 评论 -
栈实现综合计算器(中缀表达式)
使用栈完成表达式的计算通过一个index(索引),来遍历表达式如果是一个数字,就直接入栈(存放数字的栈)如果是一个符号:3.1 如果符号栈为空,符号直接入栈3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出两个数,从符号栈中pop出一个符号,进行运算,将得到的结果入数栈,然后将当前操作符入符号栈;如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运算最后在数栈原创 2021-01-10 16:52:26 · 162 阅读 · 0 评论 -
栈(Stack)数组模拟栈
栈是一个先入后出的有序列表栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶,另一端为固定的一端,称为栈底。最先放入栈中的元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先被删除,最先放入的元素最后删除。出栈(pop)入栈(push)使用数组模拟栈1、使用数组来模拟栈2、定义一个top来表示栈顶,初始化为-1(此时没有任何数据,因为数组第一个元素下标为0);3、入栈操作,当有数据加入到栈时,t.原创 2021-01-10 14:13:21 · 831 阅读 · 0 评论 -
环形链表的创建和遍历
//创建环形单向链表class CircleSingleLinkedList { //创建一个first节点,当前没有编号 private Boy first = null; //添加一个Boy节点,构建成一个环形的链表 public void addBoy(int nums) { //参数为节点数量 //nums 做一个数据验证 if(nums < 1) { System.out.println("nums的值不正确"); return; } Boy cu原创 2021-01-10 13:10:53 · 391 阅读 · 0 评论 -
双向链表指定位置插入节点(链表排序问题)
指定位置插入节点先找到要插入的位置(通过节点的属性,比如id或者有序数字)与单链表不同的时候插入后,next 和 pre 都要与前后节点相连// 按排序插入节点 public void addByOrder(Node2 node) { // 头节点不能动,通过辅助指针来找到添加的位置 Node2 temp = head; boolean flag = false; // 标志添加的编号是否存在 while (true) { if (temp.next == null) { .原创 2021-01-10 13:04:32 · 1190 阅读 · 1 评论 -
双向链表的增删改查
单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找单向链表不能自我删除,需要靠辅助节点,而双向链表可以自我删除class DoubleLinkedList { // 先初始化一个头节点 private Node2 head = new Node2(0, "", ""); // 头节点不存放数据 //返回头节点 public Node2 getHead() { return head; } //遍历双向链表的方法 // 显示链表(遍历) public voi.原创 2021-01-09 16:52:26 · 341 阅读 · 4 评论 -
单链表的一些题目,面试题
获取单链表的节点个数(如果是带头节点的链表,需求不统计头节点)/** * * @MethodName: 获取单链表的节点个数(如果是带头节点的链表,需求不统计头节点) * @Description: TODO * @author 63417 * @param head 链表的头节点 * @return 返回有效节点的个数 * @date 2021年1月9日 */ public static int getLength(Node head) { if(head.n.原创 2021-01-09 16:08:03 · 171 阅读 · 0 评论 -
单链表按顺序插入节点、修改节点、删除节点
首先找到新添加的节点的位置,是通过一个辅助指针(temp)来找的让新的节点.next = temp.next将temp.next = 新的节点//顺序插入节点 public void addByOrder(Node node) { //头节点不能动,通过辅助指针来找到添加的位置 //因为单链表,找的temp是位于添加位置的前一个节点 Node temp = head; boolean flag = false; //标志添加的编号是否存在 while(true) { i.原创 2021-01-09 12:42:01 · 728 阅读 · 0 评论 -
链表(Linked List)之单向链表的创建
链表是有序的列表链表是以节点的方式存储每个节点包含data域,next域:指向下一个节点链表的各个节点不一定是连续存放链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定先创建一个head头节点,作用表示单链表的头每添加一个节点,就直接加入到链表的最后class SingleLinkedList { //先初始化一个头节点 private Node head = new Node(0, "", ""); //头节点不存放数据 //添加节点到单.原创 2021-01-09 10:18:24 · 357 阅读 · 0 评论 -
数组模拟环形队列
1、front指向队列的第一个元素,front初始值为02、rear指向队列的最后一个元素的后一个位置,rear初始值为03、当队列满时,条件是(rear + 1)% maxSize == front4、队列为空,条件rear = front5、队列中有效的数据个数: (rear + maxSize - front)%maxSizeclass CircleQueue{ private int maxSize; //表示数组的最大容量 private int front; //队列头指向.原创 2021-01-09 09:06:06 · 196 阅读 · 0 评论 -
数组模拟队列
class ArrayQueue{ private int maxSize; //表示数组的最大容量 private int front; //队列头 private int rear; //队列尾 private int[] arr; //该数组用于存放数据,模拟队列 //创建队列的构造器 public ArrayQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; fro原创 2021-01-09 08:26:49 · 199 阅读 · 0 评论 -
稀疏数组与二维数组的转换
稀疏数组的使用场景:当一个数组中大部分元素为0,或者为同一个值的时候,可以使用稀疏数组来保存该数组。比如这样一个数组,里面除了1和2之外其余全为0。二维数组转成稀疏数组的思路1、记录该二维数组一共几行几列,有多少不同的值2、把具有不同值的元素的行列及值记录在一个小规模的数组中比如下面这张图:左边二维数组为6行7列,其中有8个非零的值,所以将【6,7,8】存在第0行后面开始记录原二维数组有效数据的位置,比如有效数据22,其位于原二维数组的下标为[0][3],所以我们将【0,3,22】.原创 2021-01-08 20:57:27 · 197 阅读 · 0 评论