首页 文章 精选 留言 我的

精选列表

搜索[数据结构],共7263篇文章
优秀的个人博客,低调大师

Python 数据结构与算法 —— 初识算法

算法是什么? 举个简单例子: 我们要做一份蛋炒饭: 拿钱包,出门,去菜市场购买鸡蛋和大米以及油和盐——购买蛋炒饭的材料 回家将大米淘洗干净放进电饭煲——煮熟大米 将锅放在电磁炉上加热——往锅里倒适量油 将鸡蛋打开放入油锅——翻炒鸡蛋至七分熟 将适量煮熟的米饭倒入锅中,加盐——翻炒两分钟 以上就是制作一份简单蛋炒饭的步骤 如果把这些交给机器来做,也是如此,并且步骤将更加细分和严谨 简单来讲,这就是算法 那么算法到底是什么呢? 先来看一道简单的高中数学题: 现有a,b,c三个自然数,要求满足以下条件: 1.a+b+c = 1000 2.a^2 + b^2 = c^2 (^代表平方) 分析: 首先排除数学公式,我们使用机器思维来计算这道题,能想到的办法也很简单,即一个一个数尝试 ,直到试出准确答案为止,此种方法我们称之为 枚举法 上面数学题使用Python来实现: import time start_time = time.time() for a in range(0, 1001): for b in range(0, 1001): for c in range(0, 1001): if a+b+c == 1000 and a**2 + b**2 == c**2: print("a, b, c: %d, %d,%d" % (a, b, c)) end_time = time.time() print("time:%d" % (end_time - start_time)) print("finished!") 代码执行结果: C:\python3\setup\python.exe C:/Users/limia/Desktop/DataS/01_枚举组合.py a, b, c: 0, 500,500 a, b, c: 200, 375,425 a, b, c: 375, 200,425 a, b, c: 500, 0,500 time:121 finished! Process finished with exit code 0 注释: 在上面的代码中:计算这道数学题的同时,还引入了time模块来计算这段代码的运行时间,以方便之后对比算法效率 通过分析这道题,我们可以得知,a+b+c=1000,在有了a和b的值之后,c的值自然就可以计算为:1000-a-b,分析至此,则代码可以改进为以下: import time start_time = time.time() for a in range(0, 1001): for b in range(0, 1001): c = 1000 - a -b if a**2 + b**2 == c**2: print("a, b, c: %d, %d,%d" % (a, b, c)) end_time = time.time() print("time:%d" % (end_time - start_time)) print("finished!") 代码执行结果: C:\python3\setup\python.exe C:/Users/limia/Desktop/DataS/01_枚举组合.py a, b, c: 0, 500,500 a, b, c: 200, 375,425 a, b, c: 375, 200,425 a, b, c: 500, 0,500 time:1 finished! Process finished with exit code 0 通过对比,可以一目了然的发现,改进后的代码执行效率(1s)明显高于第一种代码执行效率(121s) 算法的概念: 算法是计算机处理信息的本质 算法是独立存在的一种解决问题的方法和思想 计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务 单纯以时间衡量算法效率是否是科学的、客观的? 答案:不客观 假设在一台古老的计算机上运行上面的两个程序,则其所消耗的时间都将是极长的,因此单纯以时间计算算法的效率是不科学的。 在衡量算法的效率时,应当脱离计算机来估算 因此引入时间复杂度来衡量算法的效率 每台计算机执行的总时间不同,但是执行基本运算数量大体相同 上面的两个程序,以时间复杂度来表示算法效率: T = 1000 * 1000 * 1000 * 2 ==》 当计算的不是a+b+c=1000,而是a+b+c=2000时,以时间复杂度表示则 T = 2000 * 2000 * 2000 * 2 ==》 当计算的不是1000或者2000,而是n呢? T(n) = n * n * n * 2 简化: T(n) = n^3 * 2 则此时 **T(n) = n^3 * 2 ** 即为这个程序算法的时间复杂度函数 通过函数 T(n) = n^3 * 2 ,可做出曲线图 系数对曲线形状改变不大,只是陡峭不同,因此 T(n) = n^3 * 2 可以简化为T(n) = n^3 T(n) = n^3 则可以叫做 T(n) = n^3 * 2 的渐进函数 大O表示法 上述 **T(n) = n^3 ** 就是 ** T(n) = n^3 * 2 ** 的大O 表示法 总结: 大O表示法只留下表示特征的部分 常见时间复杂度之间的关系 O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) 个人博客地址:www.limiao.tech 微信公众号:TechBoard 慕课网:techLee 如果觉得文章对您有所帮助,那就伸出小手 ==>> 点击下方 [ like ] 吧

优秀的个人博客,低调大师

java数据结构题之约瑟夫问题

约瑟夫问题:转载自约瑟夫问题 据说着名犹太历史/数学家约瑟夫(Josephus)有过以下的故事:在罗马人占领乔塔帕特後,40个犹太士兵与约瑟夫躲到一个洞中,眼见脱逃无望,一群人决定集体自杀,约瑟夫建议自杀方式,41个人排成圆圈,由第1个人开始报数,每报数到5的人就必须自杀,然後由下一个重新报数,直到所有人都自杀身亡为止。如果你是约瑟夫,你应该在哪个位置才能活下来(最后只剩下你)? 我的答案: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package p1; import java.util.LinkedList; import java.util.List; public class KillSelf{ //构造链式列表,用来模拟人。 private static List<String>list= new LinkedList<String>(); //记忆自杀那个人前后的人集合有序子列表 private static List<String>listBefore,listAfter; //自杀那个人的编号从1开始 private static StringkilledNum= null ; private static int KILL_INDEX= 4 ; //记录自杀的总人数 private static int sum= 0 ; public static void main(String[]args){ //记住每个从最开始的编号 for ( int i= 1 ;i<= 41 ;i++) { list.add(i+ "" ); } //其实自杀的过程,是一个循环的过程,所以用循环来解决。 while ( true ) { //获取自杀位置前后的子集 if (list.size()>= 5 ) //当人数大于等于5个人时 { listBefore= new LinkedList<String>(list.subList( 0 ,KILL_INDEX)); //不能直接用subList的返回值,要包装一下 listAfter= new LinkedList<String>(list.subList(KILL_INDEX+ 1 ,list.size())); } else if (list.size()> 1 &&list.size()< 5 ) //当人数多于1个人但是少于5个人时 { KILL_INDEX= 5 %list.size()- 1 ; //这个判断很巧妙 if (KILL_INDEX> 0 &&KILL_INDEX<list.size()- 1 ) { listBefore= new LinkedList<String>(list.subList( 0 ,KILL_INDEX)); //不能直接用subList的返回值,要包装一下 listAfter= new LinkedList<String>(list.subList(KILL_INDEX+ 1 ,list.size())); } else if (KILL_INDEX== 0 ) { listBefore.clear(); listAfter= new LinkedList<String>(list.subList(KILL_INDEX+ 1 ,list.size())); } else if (KILL_INDEX==list.size()- 1 ) { listBefore= new LinkedList<String>(list.subList( 0 ,KILL_INDEX)); listAfter.clear(); } } else break ; //将子集的后与前连接起来,更新总的集合 killedNum=list.get(KILL_INDEX); sum++; System.out.println( "编号" +killedNum+ "已自杀!-----自杀总人数达" +sum); //更新list list.clear(); list.addAll(listAfter); list.addAll(listBefore); System.out.println( "剩余人员编号:" +list); System.out.println( "" ); } System.out.println( "" ); System.out.println( "结论:处在" +list.get( 0 )+ "号才不会自杀" ); } } 但是网上的帖子,几行代码就解决问题了,这就是算法的魅力! 本文转自屠夫章哥 51CTO博客,原文链接:http://blog.51cto.com/4259297/1658382,如需转载请自行联系原作者

优秀的个人博客,低调大师

数据结构与算法之冒泡排序优化

冒泡排序优化 /** * 冒泡排序优化算法 * * @param array */ public static void bubbleSortFast(int[] array) { int len = array.length; for (int i = 0; i < len - 1; i++) { boolean change = false; for (int j = 0; j < len - i - 1; j++) { if (array[j] > array[j + 1]) { int temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; change = true; } } if (!change) { break; } } } /** * 冒泡排序原始算法,未优化 * * @param array */ public static void bubbleSortSlow(int[] array) { int len = array.length; for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { if (array[j] > array[j + 1]) { int temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } } } 测试代码: int[] array = {-30, -40, -99, 27, 88, 66, 89, 99}; 上面数组进行排序,调用传统算法需要遍历28次,调用优化后的算法只需要遍历18次

优秀的个人博客,低调大师

数据结构与算法之八皇后问题

八皇后问题代码实现 package com.pionner.recursion; public class Queen8 { int max = 8; int[] array = new int[max]; static int i = 0; public static void main(String[] args) { Queen8 queen8 = new Queen8(); queen8.check(0); System.out.println(i); } private void print() { for (int item : array) { System.out.print(item + " "); } System.out.println(); } private boolean judge(int n) { for (int i = 0; i < n; i++) { if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) { return false; } } return true; } private void check(int n) { if (n == max) { i++; print(); return; } for (int i = 0; i < max; i++) { array[n] = i; if (judge(n)) { check(n+1); } } } }

优秀的个人博客,低调大师

数据结构(3):队列的原理和实现

完整代码拉到最底下 一、介绍 队列顾名思义就像我们生活中排队一样,先进先出。 如上图所示,25、16、5、9依次在队列中,按照顺序拿出的数据也分别是25、26、5、9。 二、实现过程及思路 底层使用数组来实现,实现的功能有插入数据到队尾、移除队首数据、查看队首数据、判断队列是否为空、判断队列是否存满。 将队列的元素存储在数组的某个区间内,队列在数组中是连续的,所以使用变量标记队列在数组中的位置。 1、编写类及属性 我们可以使用elements变量标记队列中元素的数量,使用front变量标记队首元素在数组的索引,end变量标记队尾元素在数组中的索引。 public class MyQueue { private Object[] arr;//存放队列元素的数组 private int elements;//队列元素数量 private int front;//队头元素在数组中的索引 private int end;//队尾元素在数组中的索引 public MyQueue() { arr = new Object[10]; elements = 0; front = 0; end = -1; } public MyQueue(int maxSize) { arr = new Object[maxSize]; elements = 0; front = 0; end = -1; } } 2、队列是否为空 标记队列元数量的变量 elements 为 0 即为空 public boolean isEmpty() { return elements == 0; } 3、队列是否已经满了 队列元素个数与数组的长度相等即为满 public boolean isFull() { return elements == arr.length; } 4、获取队头元素 获取数组中索引为 front的元素 public Object peek() { return arr[front]; } 5、移除队首元素 每次都是移除数组中索引为 front 的元素,下一个元素就变成了队首,即front+1,队列元素个数elements-1。共有三种情况要考虑,如果队列已经空了就无须做任何操作,如果已经是最后一个元素,直接将标记位置的变量重置即可,其他情况正常操作。 public Object remove() { if (isEmpty()) { throw new RuntimeException("队列已经是空的,放心使用吧"); } Object value = arr[front++]; //如果已经是最后一个元素了,将指针重置即可 if (elements == 1) { end = -1; front = 0; elements = 0; } else { elements--; } return value; } 6、插入 我们编写一个持续可用的队列,所以要考虑到以下情况。 (1)存储队列的数组满了(队列满了),这个好理解,满了就无法向队尾加入元素了。 (2)因为队列在数组中是连续的,如果队列的元素在数组中最后,需要将元素从队首到队尾移到数组中第一位,也就是将后面的位置空出来(参考下图)。 public void insert(Object value) { //检测队列是否已经满了 if (isFull()) { throw new RuntimeException("队列内元素已达到设定长度"); } //如果后面没有空位置,将余下元素放到数组的头 if (elements > 1 && end == arr.length - 1) { int i = 0; for (; i < elements; i++, front++) { arr[i] = arr[front]; } front = 0; end = i-1; } //其他情况正常向后添加元素 arr[++end] = value; elements++; } 7、测试 public static void main(String[] args) { MyQueue queue = new MyQueue(4); queue.insert(11); queue.insert(12); queue.insert(13); queue.insert(14); queue.remove(); queue.remove(); queue.insert(16); //queue.remove(); //queue.remove(); //queue.insert(19); //queue.insert(20); queue.remove(); queue.remove(); queue.insert(21); queue.insert(22); while (!queue.isEmpty()) { System.out.println(queue.remove()); } } 三、完整代码 package com.jikedaquan.datastruct; public class MyQueue { private Object[] arr; private int elements;//队列元素数量 private int front;//队头元素在数组中的索引 private int end;//队尾元素在数组中的索引 public MyQueue() { arr = new Object[10]; elements = 0; front = 0; end = -1; } public MyQueue(int maxSize) { arr = new Object[maxSize]; elements = 0; front = 0; end = -1; } //从队尾插入 public void insert(Object value) { //检测队列是否已经满了 if (isFull()) { throw new RuntimeException("队列内元素已达到设定长度"); } //如果后面没有空位置,将余下元素放到数组的头 if (elements > 1 && end == arr.length - 1) { int i = 0; for (; i < elements; i++, front++) { arr[i] = arr[front]; } front = 0; end = i-1; } arr[++end] = value; elements++; } //删除数据,从队头删除 public Object remove() { if (isEmpty()) { throw new RuntimeException("队列已经是空的,放心使用吧"); } Object value = arr[front++]; //如果已经是最后一个元素了,将指针重置即可 if (elements == 1) { end = -1; front = 0; elements = 0; } else { elements--; } return value; } //查看数据,从队头查看 public Object peek() { return arr[front]; } //判断是否为空 public boolean isEmpty() { return elements == 0; } public boolean isFull() { return elements == arr.length; } public static void main(String[] args) { MyQueue queue = new MyQueue(4); queue.insert(11); queue.insert(12); queue.insert(13); queue.insert(14); queue.remove(); queue.remove(); queue.insert(16); // queue.remove(); // queue.remove(); // queue.insert(19); // queue.insert(20); queue.remove(); queue.remove(); queue.insert(21); queue.insert(22); while (!queue.isEmpty()) { System.out.println(queue.remove()); } } }

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册