算法其他篇

目录:

  • 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

03:数据结构 栈、队列、链表与数组相关推荐

  1. 数据结构栈队列链表数组

    目录: 数据结构 栈(stack) 队列 链表 数组 数据结构 数据结构是什么 简单来说,数据结构就是设计数据以何种方式存储在计算机中 比如:列表,集合,与字典等都是一种数据结构 程序 = 数据结构 ...

  2. 常见数据结构-栈-队列-数组-链表-哈希表

    数据结构   数据结构是计算机存储.组织数据的方式.是指相互之间存在一种或多种特定关系的数据元素的集合   通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 持续更新,学一个记一个- 栈 ...

  3. python顺序表的实现_数据结构:队列 链表,顺序表和循环顺序表实现(python版)...

    链表实现队列: 尾部 添加数据,效率为0(1) 头部 元素的删除和查看,效率也为0(1) 顺序表实现队列: 头部 添加数据,效率为0(n) 尾部 元素的删除和查看,效率也为0(1) 循环顺序表实现队列 ...

  4. Java集合常见数据结构-栈/队列/数组/链表/红黑树

    数组 链表 红黑树

  5. 【练习】2021下半年数据结构刷题笔记和总结 (三)栈 队列 链表 枚举算法

    题目来自书或者网站. 解密QQ 号--队列 回文字符串---栈 火柴棍等式 输入数字n,要求输出从1~n的全排列 [力扣]给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 ...

  6. 数据结构 - 栈(链表实现栈的入栈出栈)

    学完链表和栈,数组模拟栈学完后,自己根据链表写了个链栈,虽然只是简单的实现了入栈出栈遍历.收获还是很大的. 在push这里思考了一会,思路是:传入一个数字,push里创建一个节点node,把数据加入n ...

  7. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  8. 常见的数据结构:栈 队列 数组 链表 红黑树——List集合 _ HashSet集合、可变参数 collections集合 Map集合

    2021-06-07复习java 一.常见的数据结构 栈(先进后出) 队列 数组 链表 红黑树 二.List集合_介绍&常用方法 ArrayList集合 Linkedlist集合 三.Hash ...

  9. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  10. 有十五个数按由大到小顺序存放在一个数组中_数据结构基础 (代码效率优化, 线性表, 栈, 队列, 数组,字符串,树和二叉树,哈希表)...

    作者:张人大 代码效率优化 复杂度 -- 一个关于输入数据量n的函数 时间复杂度 -- 昂贵 与代码的结构设计有着紧密关系 一个顺序结构的代码,时间复杂度是O(1), 即任务与算例个数 n 无关 空间 ...

最新文章

  1. python datetime 加一个月_Python 如何计算当前时间减少或增加一个月
  2. Mysql访问新数据时先查表
  3. Pytorch中的variable, tensor与numpy相互转化
  4. spring-boot基础概念与简单应用
  5. 3.运算符与表达式,控制流
  6. 计算机网络读书笔记(1)
  7. Android实现拍照并存储功能,Android实现拍照及图片显示效果
  8. linux服务器拓扑图,Linux服务器作为网关的DNS分离解析服务(CentOS 7版本)
  9. PyCharm中脚本文件无法识别相对路径
  10. 【sklearn第十四讲】决策树之分类篇
  11. Python黑客编程入门教程
  12. abaqus一维固结模拟
  13. 汇编中DOSBox的使用
  14. c语言10h,bios 10h中断是什么意思啊?
  15. 奥克兰大学商学院计算机专业,【奥克兰大学商学院有什么专业】 - 教外新西兰留学网...
  16. 2018年第九届蓝桥杯大赛软件类省赛C/C++B组参赛感想
  17. NDoc - .NET 代码文档生成器
  18. 计算机内存占用过高,如果内存使用率过高怎么办? Win10计算机内存占用率高的原因和解决方案...
  19. 视频倍速 - 在线调倍速的加速器APP工具
  20. 正则表达式在JS中的应用,判断邮箱是否合法

热门文章

  1. android 过滤数组中的重复元素,Flutter List数组避免插入重复数据的实现
  2. java json删除节点_指定json的某个节点进行增、删、改
  3. 使用说明 思迅收银系统_便利店收银使用的收银系统应该取决于什么?
  4. mac下SecureCRT连接阿里云服务器最新教程
  5. java8中Predicate用法
  6. 获取后端接口请求中的参数(@PathVariable,@RequestParam,@RequestBody区别,使用postman请求
  7. 数据库:MYSQL相关设计规范梳理,值得收藏!
  8. 事务管理:事务的状态相关知识笔记
  9. 程序员简历的 8 个建议
  10. 十点总结,为何 Linux 如此深得人心