算法入门——数组,链表,选择排序
目录
内存的工作原理
数组和链表
数组
链表
比较
整体比较
时间复杂度
python中实现链表
测试
选择排序
小结
内存的工作原理
大家逛超市的时候,应该都看见过门口有储存柜,进去逛超市时,就把东西存入储存柜,如果你东西很多,就可能需要开两个柜子来放你的东西,然后你就只需要拿着储存柜小票轻轻松松去逛超市了,等逛完超市,你凭借小票在把自己的东西拿出来。其实计算机内存的工作原理大致就是这样。计算机就是超市门口这一堆储物柜的集合,每个单独的储物柜都有对应的小票,都有它们的地址。
当我们需要将数据存储到内存时,我们请求到计算机,计算机再分配给我们一片空间用于存储。
数组和链表
数组
数组(Array)是有序的元素序列。它的所有元素在内存中是相连的(紧靠在一起的)。
链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,即链表中的元素可储存在内存的任何地方。链表中存储了每个元素即下一个元素的地址,所以在插入元素的情况下,它比数组更具有优势,因为它只需要将元素存入内存,然后将其地址储存在上一个元素中,不需像数组那样将后面的元素依次退位。
比较
整体比较
数组 | 链表 | |
内存占用 | 需要连续的内存空间 | 不需要连续的内存空间 |
大小可变 | 固定,分配多少就是多少,不能动态扩展,可能会浪费内存 | 链表的大小可动态变化 |
插入(中间) | 较慢,需要将插入元素之后的所有元素往后移动 | 较快,只需要放入内存,并将其地址放入前一个元素 |
删除 | 较慢,需要将删除元素之后的所有元素往前移 | 较快,只需要修改前一个元素的指向的地址即可 |
查询 | 较快,可以通过下标直接访问 | 较慢,只能通过遍历查询 |
访问形式 | 即可随机访问也可顺序访问 | 只能顺序访问 |
扩展性 | 不可动态扩展 | 可以动态扩展 |
存储数据类型 | 必须一致 | 可以不一致 |
时间复杂度
查询 | 插入 | 删除 | |
数组 | O(1) | O(n) | O(n) |
链表 | O(n) | O(1) | O(1) |
需要说明的是,数组如果通过下标随机查询,它的时间复杂度为O(1),但如果通过顺序访问,那么时间复杂度和链表一样为O(n),但如果这是个有序数组,通过顺序访问,那么根据二分查找,它的时间复杂度为O(logn)。上面的插入,删除仅仅指这一个操作,并不包含查询的时间,之所以数组的插入和删除操作的时间复杂度为O(n),是因为数组插入和删除一个元素时,其他元素的位置也要相应移动,在头部和尾部插入(注意考虑内存是否足够,足够时时间复杂度为O(1))的时间复杂度都为O(n),而链表只需要插入元素,再在前一个元素中添加地址即可,所以时间复杂度为O(1),总的来说,不能过于记住结论,需要实际情况灵活分析。
在实际生活中,其实数组用的情况更多,因为它支持随机访问,你想要哪个元素,你可以通过下标直接跳到你想要的元素,所有它的读取速度更快,而在生活中,很多情况都要求能够随机访问。
python中实现链表
下面会简单演示单向链表的实现。双向链表,循环链表的实现大家可以去看看这篇文章
Python 数据结构之链表 - 知乎
单向链表实现,具有增删检查等功能,主要运用类与对象等知识
# @Time:2022/1/2813:21
# @Author:中意灬
# @File:链表.py
# @ps:tutu qqnum:2117472285
# #定义结点
class Node(object):#单向链表的节点def __init__(self,item):self.item=item#item存放数据元素self.next=None#next是下一个节点的标识
class SingleLinkList(object):#单向链表def __init__(self):self.head=Nonedef is_empty(self):#判断链表是否为空return self.head == Nonedef length(self):#链表长度#初始指针指向head头部cur=self.headcount=0#指针指向None表示达到了尾部while cur != None:count+=1#指针下移cur=cur.nextreturn countdef items(self):#遍历链表#获取head指针cur=self.head#循环遍历while cur is not None:#返回生成器yield cur.itemcur=cur.nextdef add(self,item):#向链表头部添加元素node=Node(item)#新节点指针指向原头部节点node.next=self.head#头部节点指针修改为新节点self.head=nodedef append(self,item):#尾部添加元素node=Node(item)#先判断是否为空链表if self.is_empty():#空链表,head指向新节点self.head=nodeelse:#不是空链表,找到尾部,将尾部next节点指向新节点cur=self.headwhile cur.next != None:cur=cur.nextcur.next=nodedef insert(self, index, item):# 指定位置插入元素# 指定位置在第一个元素之前,在头部插入if index <= 0:self.add(item)# 指定位置超过尾部,在尾部插入elif index > (self.length() - 1):self.append(item)else:# 创建元素结点node = Node(item)cur = self.head# 循环到需要插入的位置for i in range(index - 1):cur = cur.nextnode.next = cur.nextcur.next = nodedef remove(self, item):#删除元素cur = self.headpre = Nonewhile cur != None:# 找到指定元素if cur.item == item:# 如果第一个就是删除的节点if not pre:# 将头指针指向头节点的后一个节点self.head = cur.nextelse:# 将删除位置前一个节点的next指向删除位置的后一个节点pre.next = cur.nextreturn Trueelse:# 继续按链表后移节点pre = curcur = cur.nextdef find(self, item):#查找元素是否存在return item in self.items()
测试
if __name__ == '__main__':link_list=SingleLinkList()#添加元素for i in range(5):link_list.append(i)print('节点:',end='')for i in link_list.items():print(i, end='\t')#头部插入元素link_list.add(6)print('插入头部元素后:',end='')for i in link_list.items():print(i, end='\t')#尾部添加元素link_list.append(10)print('尾部添加元素后:',end='')for i in link_list.items():print(i,end='\t')#中间插入元素print('')link_list.insert(3,9)print('中间插入元素后:',end='')for i in link_list.items():print(i, end='\t')#删除元素link_list.remove(3)print('删除元素后:',end='')for i in link_list.items():print(i, end='\t')#查找元素a=link_list.find(4)print('是否查找到4这个元素:',end='')print(a)
运行结果:
选择排序
假如辅导员让你做成绩分析,让你对整个专业的绩点进行一个从高到低的排序,该如何做?
姓名 | 平均绩点 |
张三 | 2.1 |
李四 | 3.2 |
老五 | 4.2 |
王麻子 | 0.8 |
一种办法是遍历这个列表,找出绩点最高的人,然后添加到一个新的列表,然后重复这个操作,就能得到一个有序列表,而这便是选择排序,时间复杂度为O(n^2)
另外一种方法是用快速排序的方法来实现,时间复杂度为O(nlogn),比选择排序较快。这里只讲解选择排序,后面再谈快速排序。
这是降序排序,升序思想一样
# @Time:2022/1/301:02
# @Author:中意灬
# @File:选择排序.py
# @ps:tutu qqnum:2117472285
#找出最大元素,返回其下标
def find_Max_num(arr):Max_num=arr[0]Max_num_index=0for i in range(1,len(arr)):if arr[i]>Max_num:Max_num=arr[i]Max_num_index=ireturn Max_num_index
#排序
def sort_num(arr):newArr=[]for i in range(len(arr)):Max_num_index=find_Max_num(arr)newArr.append(arr.pop(Max_num_index))#找到一个,弹出一次,再次循环return newArr
if __name__ == '__main__':arr=[3.1,3.5,0.2,4.2]new=sort_num(arr)print(new)
运行结果:
[4.2, 3.5, 3.1, 0.2]
小结
- 计算机内存如一大堆储物柜
- 储存多个元素是,可使用数组或链表
- 数组的元素地址连着一起
- 链表的元素地址分开的,其中每个元素都包含着下一个元素的地址
- 数组有两种访问方式,随机访问和顺序访问,随机访问速度很快
- 链表只有一种访问方式,顺序访问,访问速度较慢
- 链表的插入和删除速度很快,数组较慢
- 在同一个数组中,所有元素的类型都必须一样,链表可以不一致
算法入门——数组,链表,选择排序相关推荐
- 排序算法入门之简单选择排序
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 在学了冒 ...
- java 排序 1和1_新手入门-冒泡排序和选择排序第一节排序1.1排序概述排序(
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 新手入门-冒泡排序和选择排序 第一节排序 1.1排序概述 排序(sorting)的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列.  ...
- 加标志量的选择排序算法c语言,置换选择排序算法详解(C语言实现)
上一节介绍了增加 k-路归并排序中的 k 值来提高外部排序效率的方法,而除此之外,还有另外一条路可走,即减少初始归并段的个数,也就是本章第一节中提到的减小 m 的值. m 的求值方法为:m=⌈n/l⌉ ...
- 输入法按照选字频率排序的C语言程序算法,算法与数据结构之选择排序(C语言)...
#include #include void SelectSort(int *a,int n);//预声明要调用的函数 int main(void) { int k; int x[]={,,,,,,, ...
- 【简单排序算法】:简单选择排序、直接插入排序和冒泡排序
[简单排序算法]:简单选择排序.直接插入排序和冒泡排序 简单选择排序: 原理:设所排序序列的记录个数为n.i取1,2,-,n-1,每次从所有n-i+1个记录(Ri,Ri+1,-,Rn)中找出最小的记录 ...
- 蛮力法查找有序数列c语言,算法——蛮力法之选择排序和冒泡排序c++实现
这次实现的是蛮力法中的两个例子,选择排序法和冒泡排序法,使用的编译环境是vs2013,下面对这两个算法做一个简单介绍,然后是两个算法的c++实现代码. 选择排序法比较的范围是整个列表,每次扫描结束找出 ...
- 【排序算法】图解简单选择排序(图解堪比Debug显示每次循环结果)
[排序算法]图解简单选择排序(图解堪比Debug分析每次循环结果) 写在前面: 本文主要介绍简单选择排序算法,通过图片一步步解释每一趟每一次的后移.代码通过C#实现,并输出每一次交换的情况和比较次数, ...
- 算法一之简单选择排序
一. 选择排序的思想 选择排序的基本思想是:每一趟在n-i+1(i=1,2,-n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录.基于此思想的算法主要有简单选择排序.树型选择排序和堆排序. ...
- C语言排序算法(一)——选择排序实现
C语言排序算法(一)--选择排序实现 编写程序,实现从键盘输入10个数,并用选择法从小到大排序. 简单选择排序的基本思想:第1趟,在待排序记录r[1]r[n]中选出最小的记录,将它与r[1]交换:第2 ...
- 链表选择排序算法功能实现演示
算法: 狭义的算法是与数据的存数方式密切相关 广义的算法是与数据的存储方式无关 泛型: 利用某种技术达到的效果就是:不同的存数方式,执行的操作是一样的 #include <stdio.h> ...
最新文章
- JavaScript表单验证,输入中文时字符长度为2
- Visual Studio “类视图”和“对象浏览器”图标含义
- 2020太湖杯 | Wp及复现
- 自己构建GlassFish 4.0快照
- html嵌入audio格式不支持,html5中audio支持音频格式的解决方法
- idea 生成自己项目 API (跟jdk api 一样的界面) 香吧
- ASP.NETSpring.NETNHibernate最佳实践(七)——第3章人事子系统(4)人事子系统小结...
- Flutter之Binding简单梳理
- opera mini 7.5安卓改服版
- 想知道你和她在网易云喜欢的音乐的重合率?
- python最长的单词判断_Python 找出英文单词列表(list)中最长单词链
- webpy中如何返回json格式给前端
- 桌面窗口管理器 GPU 3D 占用100% 的解决方法
- 出现了,PPT 制作新方式
- sourceTree细节安装
- 根据ACR/EULAR 2010 标准定义RA放射学侵蚀病变
- 图与排列、图的存在性
- 上海交大计算机科学技术导师介绍,上海交大电子信息与电气工程学院研究生导师介绍:申丽萍(计算机应用研究所)...
- matlab 拉马努金恒等,广州恒大海报谜底:拉马努金恒等式:欧拉公式
- 如何将MIke的结果转成Tecplot格式--基于python
热门文章
- 用HTML+CSS做一个简单的新闻门户 1页网页
- matlab c2d的c语言实现,Matlab c2d()函数的用法
- Python对word文档进行操作
- dbt2 mysql_mysql压力测试工具-DBT2 Benchmark Tool下载0.37.50.14-西西软件下载
- 说说如果meta标签没有写charset属性,将会如何?
- APP注册名称的一些问题
- CentOS 7拨号上网(ADSL PPPoE)
- New Concept English3 Lesson 2. Thirteen equals one【精讲学习笔记】
- antd modal层级混乱
- The operator ‘SUBTRACT‘ is not supported between objects of type ‘null‘ and ‘java.lang.Integer‘