03:数据结构 栈、队列、链表与数组

算法其他篇

目录:

  • 1.1 数据结构中的一些概念
  • 1.2 栈(stack)
  • 1.3 队列
  • 1.4 链表
  • 1.5 python中字典对象实现原理
  • 1.6 数组

1.1 数据结构中的一些概念     返回顶部

  1、数据结构是什么

      1、简单来说,数据结果就是设计数据以何种方式存储在计算机中
      2、比如:列表,集合,与字典等都是一种数据结构
      3、程序 = 数据结构 + 算法

1.2 栈(stack)     返回顶部

  1、栈的定义

                  栈是一种数据集合,可以理解为只能在一端进行插入或删除操作的列表

  2、栈的特点

                  后进先出(last-in, first-out)

  3、栈的概念

                  栈顶,栈底

  4、栈的基本操作

                  进栈(压栈):push

                  出栈:pop

                  取栈顶:gettop

  5、栈的使用匹配括号是否成对出现

def check_kuohao(s):stack = []for char in s:if char in ['(','[','{']:stack.append(char)elif char == ')':if len(stack)>0 and stack[-1] == '(':stack.pop()else:return Falseelif char == ']':if len(stack) > 0 and stack[-1] == '[':stack.pop()else:return Falseelif char == '}':if len(stack) > 0 and stack[-1] == '{':stack.pop()else:return Falseif len(stack) == 0:return Trueelse:return False
print(check_kuohao('(){}{}[]'))  #True
匹配括号是否成对出现

1.3 队列     返回顶部

  1、队列定义

      1、队列是一个数据集合,仅允许在列表的一端进行插入,另一端进行删除
      2、插入的一端称为队尾(rear),插入动作叫进队或入队
      3、进行删除的一端称为对头(front),删除动作称为出队
      4、队列性质:先进先出(First-in, First-out)
      5、双向队列:队列的两端都允许进行进队和出队操作

  2、对列使用方法

      1、导入: from collectios import deque
      2、创建队列:queue = deque(li)
      3、进队: append
      4、出队: popleft
      5、双向队列队首进队:appendleft
      6、双向队列队尾出队:pop

  3、双向对列原理图

      1、 环形对列:当对位指针front == Maxsize + 1 时,再进一个位置就自动到0
      2、 实现方法:求余数运算
      3、 队首指针前进1: front = (front + 1)%MaxSize
      4、 队尾指针前进1:rear = (rear+1)%MaxSize
      5、 队空条件:rear == front
      6、 队满条件:(rear+1)%MaxSize == front

                

1.4 链表     返回顶部

  1、单链表

    注:链表中每个元素都是一个对象,每个对象称为一个节点,包含有数据域key和指向下一节点的指针next,通过各个节点间的相互连接,最终串联成一个链表

    

#! /usr/bin/env python
# -*- coding: utf-8 -*-
class Node(object):def __init__(self, item):self.item = itemself.next = Noneclass DLinkList(object):def __init__(self):self._head = Nonedef is_empty(self):return self._head == Nonedef append(self, item):'''尾部追加元素'''node = Node(item)if self.is_empty():self._head = nodeelse:cur = self._headwhile cur.next != None:cur = cur.nextcur.next = nodedef add(self, item):"""头部插入元素"""node = Node(item)if self.is_empty():self._head = node         # 如果是空链表,将_head指向nodeelse:node.next = self._head      # 将node的next指向_head的头节点self._head = node        # 将_head 指向nodedef travel(self):cur = self._headwhile cur != None:print cur.item,cur = cur.nextprint ""def remove(self, item):"""删除元素"""if self.is_empty():returnelse:cur = self._headif cur.item == item:# 如果首节点的元素即是要删除的元素if cur.next == None:  # 如果链表只有这一个节点self._head = Noneelse:  # 将_head指向第二个节点self._head = cur.nextreturnwhile cur != None:if cur.next.item == item:cur.next = cur.next.nextbreakcur = cur.nextdef insert(self, pos, item):"""在指定位置添加节点"""if pos <= 0:self.add(item)elif pos > (self.length() - 1):self.append(item)else:node = Node(item)cur = self._headcount = 0# 移动到指定位置的前一个位置while count < (pos - 1):count += 1cur_next = cur.next# 将node的next指向cur的下一个节点cur.next = nodenode.next = cur_nextdef length(self):"""返回链表的长度"""cur = self._headcount = 0while cur != None:count += 1cur = cur.nextreturn countif __name__ == '__main__':ll = DLinkList()# 1、将链表后面追加三个元素:1,2,3ll.append(1)ll.append(2)ll.append(3)ll.travel()  # 1 2 3# 2、将链表头部插入一个元素:0
    ll.add(0)ll.travel()  # 1 2 3  ==>  0 1 2 3# 3、删除链表中的元素:3ll.remove(3)ll.travel()  # 0 1 2 3  ==>  0 1 2# 4、在链表的第2号位置插入元素:8ll.insert(2,8)ll.travel()  # 0 1 2  ==>  0 8 1 2 
单链表增删改查
#! /usr/bin/env python
# -*- coding: utf-8 -*-
class Node(object):def __init__(self, val):self.val = valself.next = Nonedef list_reverse(head):if head == None:return NoneL, R, cur = None, None, head  # 左指针、有指针、游标while cur.next != None:L = R             # 左侧指针指向以前右侧指针位置R = cur           # 右侧指针前进一位指向当前游标位置cur = cur.next    # 游标每次向前进一位R.next = L        # 右侧指针指向左侧实现反转cur.next = R          # 当跳出 while 循环时 cur(原链表最后一个元素) R(原链表倒数第二个元素)return curif __name__ == '__main__':'''原始链表:1 -> 2 -> 3 -> 4反转链表:4 -> 3 -> 2 -> 1'''l1 = Node(1)l1.next = Node(2)l1.next.next = Node(3)l1.next.next.next = Node(4)l = list_reverse(l1)print l.val         # 4  反转后链表第一个值4print l.next.val    # 3  第二个值3
链表反转
#! /usr/bin/env python
# -*- coding: utf-8 -*-
class ListNode(object):def __init__(self, val, next=None):self.val = valself.next = next# 归并法: 对链表排序
class Solution:def sortList(self, head):if head is None or head.next is None:return headpre = headslow = head  # 使用快慢指针来确定中点fast = headwhile fast and fast.next:pre = slowslow = slow.nextfast = fast.next.nextleft = headright = pre.nextpre.next = None  # 从中间打断链表left = self.sortList(left)right = self.sortList(right)return self.merge(left, right)def merge(self, left, right):pre = ListNode(-1)first = prewhile left and right:if left.val < right.val:pre.next = leftpre = leftleft = left.nextelse:pre.next = rightpre = rightright = right.nextif left:pre.next = leftelse:pre.next = rightreturn first.nextnode1 = ListNode(4)
node2 = ListNode(3)
node3 = ListNode(2)
node4 = ListNode(1)node1.next = node2
node2.next = node3
node3.next = node4s = Solution()
result = s.sortList(node1)while (result != None):print result.val,    # 1 2 3 4result = result.next
链表排序:归并排序算法实现
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def mergesort(seq):if len(seq) <= 1:return seqmid = int(len(seq) / 2)left = mergesort(seq[:mid])right = mergesort(seq[mid:])return merge(left, right)def merge(left, right):result = []i, j = 0, 0while i < len(left) and j < len(right):if left[i] <= right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1result += left[i:]result += right[j:]return resultif __name__ == '__main__':seq = [10,4,6,3,8,2,5,7]print mergesort(seq)  # [2, 3, 4, 5, 6, 7, 8, 10]
对python列表排序:归并排序 对比

  2、双链表

    注:双链表中每个节点有两个指针:一个指针指向后面节点、一个指向前面节点

    

#! /usr/bin/env python
# -*- coding: utf-8 -*-
class Node(object):"""双向链表节点"""def __init__(self, item):self.item = itemself.next = Noneself.prev = Noneclass DLinkList(object):"""双向链表"""def __init__(self):self._head = Nonedef is_empty(self):"""判断链表是否为空"""return self._head == Nonedef length(self):"""返回链表的长度"""cur = self._headcount = 0while cur != None:count += 1cur = cur.nextreturn countdef travel(self):"""遍历链表"""cur = self._headwhile cur != None:print cur.item,cur = cur.nextprint ""def add(self, item):"""头部插入元素"""node = Node(item)if self.is_empty():# 如果是空链表,将_head指向nodeself._head = nodeelse:# 将node的next指向_head的头节点node.next = self._head# 将_head的头节点的prev指向nodeself._head.prev = node# 将_head 指向nodeself._head = nodedef append(self, item):"""尾部插入元素"""node = Node(item)if self.is_empty():# 如果是空链表,将_head指向nodeself._head = nodeelse:# 移动到链表尾部cur = self._headwhile cur.next != None:cur = cur.next# 将尾节点cur的next指向nodecur.next = node# 将node的prev指向curnode.prev = curdef search(self, item):"""查找元素是否存在"""cur = self._headwhile cur != None:if cur.item == item:return Truecur = cur.nextreturn Falsedef insert(self, pos, item):"""在指定位置添加节点"""if pos <= 0:self.add(item)elif pos > (self.length() - 1):self.append(item)else:node = Node(item)cur = self._headcount = 0# 移动到指定位置的前一个位置while count < (pos - 1):count += 1cur = cur.next# 将node的prev指向curnode.prev = cur# 将node的next指向cur的下一个节点node.next = cur.next# 将cur的下一个节点的prev指向nodecur.next.prev = node# 将cur的next指向nodecur.next = nodedef remove(self, item):"""删除元素"""if self.is_empty():returnelse:cur = self._headif cur.item == item:# 如果首节点的元素即是要删除的元素if cur.next == None:# 如果链表只有这一个节点self._head = Noneelse:# 将第二个节点的prev设置为Nonecur.next.prev = None# 将_head指向第二个节点self._head = cur.nextreturnwhile cur != None:if cur.item == item:# 将cur的前一个节点的next指向cur的后一个节点cur.prev.next = cur.next# 将cur的后一个节点的prev指向cur的前一个节点cur.next.prev = cur.prevbreakcur = cur.nextif __name__ == "__main__":ll = DLinkList()ll.add(1)ll.add(2)# ll.append(3)# ll.insert(2, 4)# ll.insert(4, 5)# ll.insert(0, 6)# print "length:",ll.length()# ll.travel()# print ll.search(3)# print ll.search(4)# ll.remove(1)print "length:",ll.length()ll.travel()
双链表增删改查
#! /usr/bin/env python
# -*- coding: utf-8 -*-
class Node(object):def __init__(self, item):self.item = itemself.next = Noneself.prev = Noneclass DLinkList(object):def __init__(self):self._head = Nonedef is_empty(self):return self._head == Nonedef append(self, item):node = Node(item)if self.is_empty():self._head = nodeelse:cur = self._headwhile cur.next != None:cur = cur.nextcur.next = nodenode.prev = curdef travel(self):cur = self._headwhile cur != None:print cur.item,cur = cur.nextif __name__ == '__main__':ll = DLinkList()ll.append(1)ll.append(2)ll.append(3)# print ll._head.item              # 打印第一个元素:1# print ll._head.next.item         # 打印第二个元素:2# print ll._head.next.next.item    # 打印第三个元素:3ll.travel()    # 1 2 3
双链表追加和遍历

1.5 python中字典对象实现原理     返回顶部

    注:字典类型是Python中最常用的数据类型之一,它是一个键值对的集合,字典通过键来索引,关联到相对的值,理论上它的查询复杂度是 O(1) 

  1、哈希表 (hash tables)

      1. 哈希表(也叫散列表),根据关键值对(Key-value)而直接进行访问的数据结构。

      2. 它通过把key和value映射到表中一个位置来访问记录,这种查询速度非常快,更新也快。

      3. 而这个映射函数叫做哈希函数,存放值的数组叫做哈希表。 

      4. 通过把每个对象的关键字k作为自变量,通过一个哈希函数h(k),将k映射到下标h(k)处,并将此对象存储在这个位置。

  2、具体操作过程

      1. 数据添加:把key通过哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,
                        将value存储在以该数字为下标的数组空间里。

      2. 数据查询:再次使用哈希函数将key转换为对应的数组下标,并定位到数组的位置获取value。

  3、{“name”:”zhangsan”,”age”:26} 字典如何存储的呢? 

      1. 比如字典{“name”:”zhangsan”,”age”:26},那么他们的字典key为name、age,假如哈希函数h(“name”) = 1、h(“age”)=3,

      2. 那么对应字典的key就会存储在列表对应下标的位置,[None, “zhangsan”, None, 26 ]

  4、解决hash冲突

      

  5、python字典操作时间复杂度

      

1.6 数组     返回顶部

  1、数组定义

      1. 所谓数组,就是相同数据类型的元素按一定顺序排列的集合

      2. 在Java等其他语言中并不是所有的数据都能存储到数组中,只有相同类型的数据才可以一起存储到数组中。

      3. 因为数组在存储数据时是按顺序存储的,存储数据的内存也是连续的,所以他的特点就是寻址读取数据比较容易,插入和删除比较困难。

  2、python中list与数组比较

      1. python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。

      2. 在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据

      3. 这样保存一个list就太麻烦了,例如list1=[1,2,3,'a']需要4个指针和四个数据,增加了存储和消耗cpu。

      

 

 

 

 

 

转载于:https://www.cnblogs.com/xiaonq/p/8574655.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力登:以智能化管理提升数据中心服务能力成熟度

2017年2月28日&#xff0c;由全国信息技术标准化技术委员会信息技术服务分技术委员会指导的《信息技术服务数据中心服务能力成熟度模型》发布&#xff0c;在业界首次提出“数据中心服务能力成熟度”概念&#xff0c;使得数据中心的管理真正实现了数字化和持续优化&#xff0c;是…

基于.NET 7 的 WebTransport 实现双向通信

Web Transport 简介WebTransport 是一个新的 Web API&#xff0c;使用 HTTP/3 协议来支持双向传输。它用于 Web 客户端和 HTTP/3 服务器之间的双向通信。它支持通过 不可靠的 Datagrams API 发送数据&#xff0c;也支持可靠的 Stream API 发送数据。因为 HTTP/3 使用了基于 UDP…

Django01: 安装/基础命令/设置笔记

安装 按官网版本支持&#xff0c;现在比较适合使用1.11版本。 下载安装命令 pip3 install django1.11.9 新建项目 django-admin startproject mysite 运行项目 python manage.py runserver 127.0.0.1:8000 运行相关 目录介绍 mysite/ ├── manage.py # 管理文件 └…

线上问题随笔记录数据库连接池问题

修改方法 转载于:https://www.cnblogs.com/lvgg/p/8581506.html

数据底座_体验当今计算机的未来:通过智能底座将您的Galaxy S4变成PC

数据底座Have you ever thought that Smartphones these days are so advanced they could actually replace the PC in your everyday computing life? Today, we here at HTG will review using the Galaxy S4 with the “Smart Dock Multimedia Hub” as a PC replacement.…

如何实现 WPF 代码查看器控件

如何实现 WPF 代码查看器控件CodeViewer作者&#xff1a;WPFDevelopersOrg - 驚鏵原文链接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40&#xff1b;Visual Studio 2019;代码展示需要使用到AvalonEdit是基于WPF的代码显示控件&#xff0c;…

谈大数据也谈人工智能 郭为告诉你一个不一样的神州控股

毋庸置疑&#xff0c;我们深处一个数据无处不在的时代&#xff0c;也就是大数据时代。作为中国智慧城市领导者的神州数码控股有限公司&#xff08;以下简称“神州控股”&#xff09;近年来也在积极布局大数据&#xff0c;不过在神州控股董事局主席郭为看来&#xff0c;神州控股…

Django02: pycharm上配置django

1.setting导入 File-->Setting-->Project-->Project Interface 2.new project 新窗口 圖片畫錯 3.调试 点击右上角调试

dropbox_来自提示框:望远镜激光瞄准器,Dropbox桌面和Kindle剪辑转换

dropboxOnce a week we round up some great reader tips and share them with everyone; this week we’re looking at telescope laser sights, syncing your desktop with Dropbox, and converting your Kindle Clippings file. 每周一次&#xff0c;我们收集一些很棒的读者…

在 EF Core 7 中实现强类型 ID

本文主要介绍 DDD 中的强类型 ID 的概念&#xff0c;及其在 EF 7 中的实现&#xff0c;以及使用 LessCode.EFCore.StronglyTypedId 这种更简易的上手方式。背景在杨中科老师 B 站的.Net Core 视频教程[1]其中 DDD 部分讲到了强类型 ID&#xff08;Strongly-typed-id&#xff09…

如何快速打造一款高清又极速的短视频APP?

2019独角兽企业重金招聘Python工程师标准>>> 整个短视频的市场规模一直在增长&#xff0c;网络数据显示2018年已经突破100亿大关&#xff0c;在2019年预测将超过200亿。纵观行业&#xff0c;在生活资讯、美食、搞笑、游戏、美妆等领域&#xff0c;短视频流量巨大但竞…

Django03: django加入APP

使用命令在已有project创建 1.创建 在manage.py同级运行命令 python manage.py startapp app01 2.django中加入app 在settings.py里的INSTALLED_APPS加入app01.apps.App01Config, INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttype…

如何将Windows 10帐户还原为本地帐户(在Windows Store劫持它之后)

If your Windows 10 user account is currently a Microsoft account (by your choice or because you got, one way or another, roped into it) it’s easy to revert it back to a local account if you know where to look. Read on as we show you how. 如果您的Windows 1…

【译】Dapr 是一个“10倍好”平台 !?

译者注在正式阅读本文之前&#xff0c;我们有必要先了解下什么是“10 倍好”。10 倍好理论最早出自彼得蒂尔的《从 0 到 1》&#xff0c;他说一个新创企业&#xff0c;要想获得快速成长&#xff0c;其提供的解决方案要比现有方案好 10 倍以上&#xff0c;这个好 10 倍&#xff…

1. ReactJS基础(开发环境搭建)

本文主要介绍通过React官方提供的create-react-app脚手架进行开发环境的搭建。 1.安装node环境(安装过程这里不做介绍&#xff0c;可参考其他博文) 在cmd中输入node -v 如果可以看到相应版本号&#xff0c;说明node环境安装成功 2.npm全局安装create-react-app脚手架 3.cmd命令…

“云计算+DevOps”的正确打开方式

以我们的经验看&#xff0c;技术和工具是很重要&#xff0c;但是技术和工具本身却不能产生价值&#xff0c;而将DevOps和云计算结合却可以。事实上&#xff0c;云计算的特性决定了&#xff0c;云计算和DevOps势必如影随形&#xff0c;而云计算与DevOps的结合也正在为企业用户提…

微服务和分布式系统中的授权解决方案

本文是 《精读 Mastering ABP Framework》 2.3 探索横切关注点 - 使用授权和权限系统 一节的扩充内容&#xff0c;重点探讨了授权在分布式和微服务系统中遇到的挑战&#xff0c;以及 ABP Framework 中采用的解决方案。认证 & 授权• 认证&#xff08;Authentication&#x…

如何从命令行浏览和连接到无线网络

() We are always on the lookout for geeky ways to impress our friends, and recently we came across a way to connect to our wireless network from the command prompt, so today we’ll show you how to do it as well. 我们一直在寻找令人印象深刻的方式来打动我们的…

html 基础之canvas 和 localStorage

1&#xff0c;建立一个canvas 画布&#xff1a; 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <meta name"viewport" content"widthdevice-width, initial-scale1.0">…

国产数据助力金融行业维护信息安全

金融信息系统作为国家关键信息基础设施&#xff0c;直接关系到国家经济、社会的正常运行。长期以来&#xff0c;我国金融信息化依赖进口设备和系统&#xff0c;金融行业尤其是银行业被IBM、HP、甲骨文等外商捆绑较深&#xff0c;金融行业信息化设备的软硬件系统被外商垄断。这等…