8.基本数据结构-顺序表和链表
一.内存
- 计算机的作用:对数据进行存储和运算。首先我们需要知道我们目前使用的计算机都是二进制的计算机,就以为着计算机只可以存储和运算二进制的数据。例如下载好的一部电影,该电影可以存储到计算机中,计算机中存储的是基于二进制的电影数据,然后我们可以通过相关的视频播放软件结合相关的硬件对电影的二进制数据进行相关的运算操作,所产生的结果就是我们可以看到电影的画面和听到音频的声音。
- 问题:阐述计算机如何计算1+2的结果?
- 阐述:简单理解为,首先可以将1和2输入到计算机中,然后计算机会将1和2转换成二进制的数据进行数据存储,然后通过加法器进行两个二进制数值的计算并返回结果。
- 分析:上述的阐述中提到,计算机首先需要存储1和2这两个数值,那么计算机如何进行数据的存储呢?那么毫无疑问,计算机可以将数据直接存储到内存中。
- 变量:我们在编程世界中,可以将某个数值直接赋值给一个变量,但是最终数值会被存储到计算机的内存中,因此我们可以理解为,变量表示的就是计算机中进行数据存储的某一块内存。
- 如何形象化的理解计算机的内存?
- 举例:将计算机的内存空间映射到我们现实生活中的话,内存就好比是我们在现实生活中三维立体的空间。生活在北京的北漂们,几乎都居住的是一个独立的公寓或者合租在一个几居室的某一个房间中,那么北漂甲就好比是数据,而他所居住的房间则就是存储数据的一块内存空间。
- 分析:从上述案例中,我们可以得知北漂甲居住的房间会有两个基本的属性,其一就是房间空间的大小,其二就是房间的一个位置标识(门牌号)。那么计算机中存储数据的内存空间也会有这两个最基本的属性:内存空间大小和内存空间的地址。内存空间的大小可以表示该空间可以存储数据值的大小范围,内存空间的地址(用十六进制数值表示)可以用来通过寻址定位、查找到该内存空间中所存储的数据值。
- 如何理解 a = 10 这条赋值语句对应的内存图呢?
- 引用:当一个变量中存储的是某一块内存空间的地址,则该变量即可成为那块内存空间的引用。a=10,a就是10所在内存空间的一个引用。
- 指向:当一个变量中存储了一块内存空间的地址,则称该变量(引用)指向了那块内存。
- 不同类型数据占用内存空间的大小:整形(4字节),浮点型(8字节),字符型(1字节)
二.顺序表:集合中存储的元素是有顺序的。顺序表的结构可以分为两种形式:单数据类型和多数据类型。
- 单数据类型:在内存中如何存储 int a = 10,20,30,如何取得每一个数据值呢?
- 多数据类型:在内存中如何存储 li = 10,'a',96.5,如何获取每一个数据值呢?
- 顺序表的弊端:顺序表的结构需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁。
- Python中的 list 和 tuple 两种类型采用了顺序表的实现技术。
三.链表:相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
- 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是每一个结点(数据存储单元)里存放下一个结点的信息(即地址):
- 1、单向链表
单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
- 表中元素elem用来存放具体的数据。
- 链接域next用来存放下一个节点的位置。
- 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。
- 单向链表的抽象数据类型定义:
. is_empty():链表是否为空
. length():链表长度
. travel():遍历整个链表
. add(item):链表头部添加元素
. append(item):链表尾部添加元素
. insert(pos, item):指定位置添加元素
. remove(item):删除节点
. search(item):查找节点是否存在
- 代码实现:
class Node():def __init__(self,item):self.item = itemself.next = Nonedef __str__(self):return str(self.item) class Link():def __init__(self):#永远指向链表中第一个节点self._head = Nonedef isEmpty(self):return self._head is Nonedef add(self,item):node = Node(item)node.next = self._headself._head = nodedef length(self):count = 0if self.isEmpty():return countelse:cur = self._headwhile cur is not None:count += 1cur = cur.nextreturn countdef travel(self):cur = self._headwhile cur is not None:print(cur)cur = cur.nextdef append(self,item):node = Node(item)cur = self._headif self.isEmpty():self._head = nodeelse:while cur is not None:#因为循环遍历结束后cur会指向空并非最后一个节点pre_cur = curcur = cur.nextpre_cur.next = nodedef search(self,item):ex = Falsecur = self._headwhile cur is not None:if cur.item == item:ex = Truebreakcur = cur.nextreturn exdef insertTo(self,item,index):cur = self._headex = 0node = Node(item)#插入到第一个节点位置if index <= 0:self.add(item)#插入到最后一个节点位置elif index >= self.length():self.append(item)else:while cur is not None:pre = cur cur = cur.next#此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1if ex == index-1:node.next = curpre.next = nodebreakex += 1def remove(self,item):pre = Nonecur = self._head#删除的是第一个节点if cur.item == item:self._head = cur.nextelse:while cur is not None:pre = curcur = cur.nextif cur.item == item:pre.next = cur.nextcur.next = Nonecur = cur.next#测试代码 link = Link() link.add('bobo') link.add('jay') link.add('tom') link.add('jerry') # print(link.search('tom')) # link.insertTo('haha',1) link.remove('bobo') link.travel()
- 2.单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头结点。
- 基本操作和单链表基本一样,实现代码如下:
# coding=utf-8 # 单向循环链表class Node:"""节点"""def __init__(self, item):self.item = itemself.next = Nonedef __str__(self):return str(self.item)class SinCycLinkedList:"""单向循环链表"""def __init__(self):self._head = Nonedef is_empty(self):"""判断链表是否为空"""return self._head is Nonedef length(self):"""链表长度"""if self.is_empty():return 0count = 1cur = self._headwhile cur.next != self._head:# print("cur", cur.item)count += 1cur = cur.nextreturn countdef travel(self):"""遍历"""if self.is_empty():returncur = self._headprint(cur.item)while cur.next != self._head:cur = cur.nextprint(cur.item)def add(self, item):"""在头部添加一个节点"""node = Node(item)if self.is_empty():self._head = nodenode.next = self._headelse:node.next = self._headcur = self._headwhile cur.next != self._head:cur = cur.nextcur.next = nodeself._head = nodedef append(self, item):"""在尾部添加一个节点"""node = Node(item)if self.is_empty():self._head = nodenode.next = self._headelse:cur = self._head# print(type(cur), cur.item, cur.next)while cur.next != self._head:cur = cur.next# print(cur.item)cur.next = nodenode.next = self._headdef insert(self, pos, item):"""指定位置pos添加节点"""if pos <= 0:self.add(item)elif pos > (self.length() - 1):self.append(item)else:node = Node(item)cur = self._headcur_pos = 0while cur.next != self._head:if (pos - 1) == cur_pos:node.next = cur.nextcur.next = nodebreakcur_pos += 1cur = cur.nextdef remove(self, item):"""删除一个节点"""if self.is_empty():returnpre = self._head# 删除首节点if pre.item == item:cur = prewhile cur.next != self._head:cur = cur.nextcur.next = pre.next # 删除首节点(跳过该节点)self._head = pre.next # 重新指定首节点# 删除其他的节点else:cur = prewhile cur.next != self._head:if cur.next.item == item:cur.next = cur.next.nextcur = cur.nextdef search(self, item):"""查找节点是否存在"""if self.is_empty():return -1cur_pos = 0cur = self._headif cur.item == item:return cur_poswhile cur.next != self._head:if cur.item == item:return cur_poscur_pos += 1cur = cur.nextif cur_pos == self.length() - 1:return -1if __name__ == "__main__":ll = SinCycLinkedList()ll.add(1) # 1ll.add(2) # 2 1# ll.travel()ll.append(3) # 2 1 3ll.insert(2, 4) # 2 1 4 3ll.insert(4, 5) # 2 1 4 3 5ll.insert(0, 6) # 6 2 1 4 3 5print("length:", ll.length()) # 6ll.travel() # 6 2 1 4 3 5print("search(3)", ll.search(3)) # 4print("search(7)", ll.search(7)) # -1print("search(6)", ll.search(6)) # 0print("remove(1)")ll.remove(1)print("length:", ll.length()) # 6 2 4 3 5print("remove(6)")ll.remove(6)ll.travel()
3.双向链表:一种更复杂的链表是 "双向链表" 或 "双面链表"。每个节点有两个链接:一个指向前一个节点,当次节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
- 代码实现:
# coding=utf-8 # 双向链表class Node:"""节点"""def __init__(self, item):self.item = itemself.prev = Noneself.next = Noneclass DLinkList:"""双向链表"""def __init__(self):self._head = Nonedef is_empty(self):"""判断链表是否为空"""return self._head is Nonedef length(self):"""获取链表长度"""if self.is_empty():return 0else:cur = self._headcount = 1while cur.next is not None:count += 1cur = cur.nextreturn countdef travel(self):"""遍历链表"""print("↓↓" * 10)if self.is_empty():print("")else:cur = self._headprint(cur.item)while cur.next is not None:cur = cur.nextprint(cur.item)print("↑↑" * 10)def add(self, item):"""链表头部添加节点"""node = Node(item)if self.is_empty():self._head = nodeelse:cur = self._headnode.next = curcur.prev = nodeself._head = nodedef append(self, item):"""链表尾部添加节点"""node = Node(item)if self.is_empty():self._head = nodeelse:cur = self._head# 遍历找到最后一个节点while cur.next is not None:cur = cur.next# 在尾节点添加新的节点cur.next = nodenode.prev = curdef insert(self, pos, item):"""指定位置添加"""# 头部添加if pos <= 0:self.add(item)# 尾部添加elif pos > (self.length() - 1):self.append(item)# 其他位置添加else:node = Node(item)cur = self._headcur_pos = 0while cur.next is not None:if cur_pos == (pos - 1):# 与下一个节点互相指向node.next = cur.nextcur.next.prev = node# 与上一个节点互相指向cur.next = nodenode.prev = curcur_pos += 1cur = cur.nextdef remove(self, item):"""删除节点"""if self.is_empty():returnelse:cur = self._head# 删除首节点if cur.item == item:self._head = cur.nextcur.next.prev = None# 删除其他节点else:while cur.next is not None:if cur.item == item:# 删除之前:1 ←→ [2] ←→ 3# 删除之后:1 ←→ 3cur.prev.next = cur.nextcur.next.prev = cur.prevcur = cur.next# 删除尾节点if cur.item == item:cur.prev.next = Nonedef search(self, item):"""查找节点是否存在"""if self.is_empty():return -1else:cur = self._headcur_pos = 0while cur.next is not None:if cur.item == item:return cur_poscur_pos += 1cur = cur.nextif cur_pos == (self.length() - 1):return -1if __name__ == "__main__":ll = DLinkList()ll.add(1) # 1ll.add(2) # 2 1ll.append(3) # 2 1 3ll.insert(2, 4) # 2 1 4 3ll.insert(4, 5) # 2 1 4 3 5ll.insert(0, 6) # 6 2 1 4 3 5print("length:", ll.length()) # 6ll.travel() # 6 2 1 4 3 5print("search(3)", ll.search(3))print("search(4)", ll.search(4))print("search(10)", ll.search(10))ll.remove(1)print("length:", ll.length())ll.travel()print("删除首节点 remove(6):")ll.remove(6)ll.travel()print("删除尾节点 remove(5):")ll.remove(5)ll.travel()
转载于:https://www.cnblogs.com/bobo-zhang/p/10529330.html
8.基本数据结构-顺序表和链表相关推荐
- C语言链表的转置算法,c语言编程集 数据结构 顺序表 点链表 数制转换 矩阵转置.doc...
c语言编程集 数据结构 顺序表 点链表 数制转换 矩阵转置 #include "stdio.h" #include "malloc.h" /*typedef s ...
- 数据结构 | 顺序表、链表和数组是逻辑结构还是物理(存储)结构?
1.逻辑结构和物理结构的定义 首先数据结构分为两个层次:逻辑结构 和 物理结构(存储方式) . 逻辑结构是用来描述数据元素之间的逻辑关系,是一个抽象概念,与数据的实际存储无关,独立于计算机存在. 物理 ...
- 数据结构--顺序表、链表、栈、队列、树、文件(visual studio可运行)
顺序表的顺序存储(增删查) #include <stdio.h> #include <stdlib.h> #define MaxSize 50 typedef int Elem ...
- 大话数据结构顺序表和链表
一 .顺序表 基本定义 typedef struct {int data[MAXSIXE];int len; }SeqList; 基本操作 //初始化 SeqList *Init_SeqList() ...
- 【顺序表和链表】实现增删查改数据结构 OJ题编程
目录 线性表 一.顺序表 1.使用顺序表MyArrayList增删查改 MyArrayList.java TestDemo.java 二.链表 1.带头 / 不带头 循环 / 非循环 2.创建链表并访 ...
- python列表是顺序表还是链表_Python数据结构与算法(链表使用详解)
链表 单向链表 p是头节点,指向第一个值,最后一个是伪节点,因为不指向地址. 表元素域elem用来存放具体的数据 链接域next用来存放下一个节点的位置(python中的标识) 变量p指向链表的头节点 ...
- 数据结构顺序表的查找_数据结构1|顺序表+链表
数据结构学习笔记1 进度:静态分配顺序表+单链表 参考资料:b站 王道考研+小甲鱼 < 判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注最高项目.的阶数. 推导大O阶方法 ...
- java数据结构与算法之顺序表与链表深入分析
转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结 ...
- 数据结构与算法之线性表(超详细顺序表、链表)
原创公众号:bigsai 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 通过前面数据结构与算法基础知识我么知道了数据结构的一些概念和重要性,那么我们今天总结下线性表相关的内容 ...
最新文章
- Specification使用notin
- Eclipse - CDT使用GDB调试C++的问题-无源文件命名(No source file named)
- how is SAP UI5 bindItems implemented
- flask-session总结
- python中try命令_Python 异常处理 Python 基础教程 try..except
- PHP如何解决网站大流量与高并发
- zabbix修改和查看登录密码
- 同样的事情,小孩叫逆反,大人叫抬杠
- 使用一键重装工具制作U盘启动盘失败的解决方法
- Invocation failed Unexpected end of file from server
- php拼手速 抢红包,拼手速必备 | 这样设置,微信抢红包速度更快!
- 打包时错误 Entry name ‘classes.dex‘ collided 的解决办法
- B2C商城项目源码,基于Java开发的高可用分布式B2C商城系统,Java+Spring MVC+Dubbo+Zookeeper+MySQL+Redis+FastDFS+Nginx+Solr
- 【Netty报错:】XXXDecoder.decode() did not read anything but decoded a message.
- 部分经济学术语英文简写
- VsCode:设置前进和后退 (返回上一个浏览位置/下一个浏览位置)快捷键
- Unity 获取手机触摸方法
- 【Java的语言特点是什么?】
- Hackergame 2020
- 社交电商·生鲜行业转型方案
热门文章
- python教学数据库_Python学习之数据库初识
- 阿尔卡特朗讯sdh设备板卡汇总_全球通信设备企业集中,中国企业脱颖而出!
- 第4.3节 Python中与迭代相关的函数
- var、let 及 const 区别
- JQuery中text(),html(),val()的区别
- vue - 官方 - 上手
- 洛谷2055 [ZJOI2009]假期的宿舍
- 在CentOS6.5上安装Tomcat7
- How to install sharepoint server 2010 sp2 in window 7 x64
- 【HTML 初学】1、HTML元素