线性数据结构

一,线性表

线性表(简称表):是一种抽象的数学概念,是一组元素的序列的抽象,它由有穷个元素组成

1, 顺序表:

使用一块连续的内存顺序的存储表中的元素,这样实现的表称为顺序表,或称连续表。在顺序表中,元素的关系使用顺序表的存储顺序自然的表示顺序表开辟内存空间后,首地址就固定了,不能再改动增:- 头部增加insert,引起后面所有元素位置挪动- 中间插入insert,引起其后所有元素的挪动- 尾部追加,推荐使用这种方式删:- 头部删,引起其后元素位置的挪动- 中间删,引起其后元素位置的挪动- 尾部删,推荐使用这种改:- 通过index直接定位元素,覆盖即可,效率很高查:- 通过index查找,效率很高

2,链接表

在存储空间中将分散存储的元素链接起来,这种实现方式称为链接表,简称链表增:- 头部增加insert, 把头部标记移动到增加的元素上,新元素与跟原来的头部元素拉手。代价很低- 中间插入insert,断开手,拉新手。效率相对于顺序表稍微差一点点- 尾部追加,新增的元素跟原来的尾部元素拉手,尾部标记移动到新的尾部元素上面删:- 头部删,移动头部标记就行了,代价低- 中间删,被删除元素两边的元素重新拉手,效率高。但是有个找目标元素的过程,相对于顺序表慢一点- 尾部删,移动尾部标记就行了,效率高改:- 通过index直接定位元素,覆盖即可,效率很高查:- 通过index查找,效率很高

二,队列queue
一般情况下,队列的操作只在某一头,或者两头同时进行,不会在队列中间操作

 - FIFO 先进先出 适合使用链接表实现- LIFO 后进先出 适合使用顺序表实现,也可以选择链接表实现- stack(栈)就是一种后进先出的

三,列表List

1,列表的简介- 一个排列整齐的队列,Python采用顺序表实现
- 列表内的个体称为元素,有0个或者若干个元素组成列表
- 元素可以是任意对象(数字,字符,对象,列表等)
- 列表内元素是由顺序的,可以使用索引
- 列表是线性的数据结构
- 使用[]表示
- 列表是可变的2,列表构建2.1 通过list()构建函数进行构建list():括号内为空或者为一个可迭代对象list() => 构建一个[]空列表list(range(5)) => [0, 1, 2, 3, 4]2.2 通过[]构建[]:构建一个空列表[1,'abc',[2,3.4,'admin']] => [1, 'abc', [2, 3.4, 'admin']]2.3 列表索引(列表索引不能超界)首地址 +index*字节数就能直接得到目标元素的位置。效率最高,时间复杂度为O(1)- 正索引 (从前往后找)索引范围[0,length-1]- 负索引(从后往前找)索引范围[-length,-1]x = [1,'abc',[2,3.4,'admin']]x[1] => 'abc'x[-1] => [2,3.4,'admin']x[-1][1] => 3.42.4 查找元素的位置- index() 查找某个值得索引位置,效率不高,会进行遍历,时间复杂度O(n)L.index(value, [start, [stop]]) -> integer -- return first index of value.x=[1,2,3,1,2,3]x.index(2) => 1 #返回第一个匹配上的元素的索引位置- count() 统计某个值出现的次数,效率不高,会进行遍历,时间复杂度O(n)L.count(value) -> integer -- return number of occurrences of valuex.count(2) => 2- len()  返回对象的长度,时间复杂度O(1),列表有元数据记录了列表的信息2.5 列表操作- 增list. append('value') :在列表的末尾添加元素 ,效率高,时间复杂度O(1)Docstring: L.append(object) -> None -- append object to endx.append(100) => [1, 2, 3, 1, 2, 3, 100]list.insert(index, object):在列表的指定索引位置插入元素。查找快,但是如果在列表开头或者中间部位插入新元素会造成其后元素的位置挪动。插入实际上就是将原先这个位置的元素向后挤。Docstring: L.insert(index, object) -- insert object before index     x.insert(3,'abc') => [1, 2, 3, 'abc', 1, 2, 3, 100]x.insert(-1,'whp') => [1, 2, 3, 'abc', 1, 2, 3, 'whp', 100] #将原先-1索引处的100挤到了后面。正向超索引的作用就相当于append的作用反向超索引会在列表头部插入- 删list.pop() 弹出指定索引出的元素,这个被弹出的元素可以被别的地方使用或引用.默认弹出列表末尾的元素。也可以弹出指定位置的元素,但是会引起后面元素位置的挪动L.pop([index]) -> item -- remove and return item at index (default last).x.pop() => 100    x = [1, 2, 3, 'abc', 1, 2, 3, 'whp']x.pop(3) =>  'abc' x = [1, 2, 3, 1, 2, 3, 'whp']list.remove(value)  删除指定元素,会进行遍历,效率不好L.remove(value) => None -- remove first occurrence of valuex.remove('whp') => [1, 2, 3, 1, 2, 3]- 改 x[4]=999 #将索引为4的元素的值修改为999,效率快,定位覆盖x[4]=999 => [1, 2, 3,1, 999, 3]- 扩展list.extend(iterable) 将一个可迭代对象里面的元素添加到列表的后面。就地修改。Docstring: L.extend(iterable) -> None -- extend list by appending elements from the iterablex.extend(range(4,7)) => [1, 2, 3, 1, 999, 3, 4, 5, 6]- 拼接+ #运算符重载x = list(range(5))y = ['a','b']x + y => [0, 1, 2, 3, 4, 'a', 'b'] #生成新的列表* #运算符重载y*3 => ['a', 'b', 'a', 'b', 'a', 'b'] # 用y的元素重复3次,生成新的列表- 翻转list.reverse() #元素的位置会发生大挪动,最好不用这个方法,可以使用reversed函数来倒着读。Docstring: L.reverse() -- reverse *IN PLACE*x = list(range(5))x.reverse() => [4, 3, 2, 1, 0] - 排序list.sort() #对列表进行排序,就地修改,会改变列表本身Docstring: L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*x = [4, 3, 2, 1, 0]x.sort() => [0, 1, 2, 3, 4]sorted()函数不会改动原列表,返回一个新的列表Signature: sorted(iterable, /, *, key=None, reverse=False)Docstring:Return a new list containing all items from the iterable in ascending order.sorted(x,reverse=True) => [4, 3, 2, 1, 0]- in 成员操作判断一个元素在列表中是否存在,存在返回True,不存在返回False2 in x => True        5 in x => False- 一种特殊现象x = [1] *3 x[1] = 100print(x)   => [1, 100, 1]y = [[1]] * 3print(y)  => [[1], [1], [1]]y[1][0]=200print(y) => [[200], [200], [200]]  #为什么是这个结果?而不是 [[1], [200], [1] 复杂数据类型(列表,元组,字典等)作为一个对象的元素时,存在在这个对象中的不是实际的值,而是一个地址,这个地址指向了实际的值。也就是说,上面例子中[[1], [1], [1]]。列表中的元素[1]不是一个实际的值,而是一个地址,这个地址指向了实际的值1当进行y[1][0]=200修改时,就是修改 [[1], [1], [1]]这个列表中索引为1的这个元素的索引为0这个元素的值为200,3,列表复制构建相同的列表a = list(range(5))b = list(range(5))a == b    => True # 虽然结果为True,但是并不是说明a和b是同一个。它们只是内容完全一样。 == 是内建函数,对元素进行比较a[2]=100a == b    => False # 可以看到只要修改了a中元素的值,a和b就不再相等- copyDocstring: L.copy() -> list -- a shallow copy of L #浅拷贝从原列表拷贝一个副本(里面的内容跟原列表一模一样,不管里面的内容是一个真实的值还是一个引用地址),生成一个新的列表a = list(range(5))b = a.copy()a == b  =>  Truea[2]=200a == b   => False # 说明a和b还是两个不同的列表- = a = list(range(5))c = a  # 相当于c也指向a所指向的位置c == a  => Truec[2]=200c == a => True- copy.deepcopy #深拷贝。如果拷贝的内容里面有引用地址,则将这个引用地址里面的内容也拷贝一份,import copya = [1,[2,3,4],5]b = copy.deepcopy(a) # b 拷贝a的元素,但是a里面的元素[2,3,4]实际上是个引用地址,此时b根据这个引用地址找到实际存放数据的地方,然后把这个数据拷贝一份放到另外一块内存中,b中保存的就是这个心的内存地址。a[1][1] = 200a == b => False

四,随机数

1,random模块- random.shuffle() 随机打散Signature: random.shuffle(x, random=None)Docstring:Shuffle list x in place, and return None.x = list(range(5))x   => [0, 1, 2, 3, 4]random.shuffle(x)x => [4, 3, 0, 1, 2]- random.randint(a,b) # 随机返回a,b之间的一个整数Signature: random.randint(a, b)Docstring:Return random integer in range [a, b], including both end points.random.randint(1,10) => 7- random.randrange()Signature: random.randrange(start, stop=None, step=1, _int=<class 'int'>)Docstring:Choose a random item from range(start, stop[, step]).for i in range(5):print(random.randrange(1,10,2))79979-random.choice('序列') 随机取一个元素Signature: random.choice(seq)Docstring: Choose a random element from a non-empty sequence.random.choice(x) => 3-random.choices('')  随机取一个或者多个元素,并且可以指定元素的权重。返回的是一个列表Signature: random.choices(population, weights=None, *, cum_weights=None, k=1)Docstring:Return a k sized list of population elements chosen with replacement.for i in range(10):print(random.choices([0,1],[5,1],k=5)) # 从0和1两个元素中选择一个,权重0为5,1为1,选择5个[0, 0, 0, 1, 0][0, 1, 0, 0, 1][0, 0, 0, 0, 1][1, 0, 1, 1, 0][0, 0, 0, 0, 1][0, 0, 0, 0, 0][0, 0, 0, 0, 0][0, 1, 0, 0, 0][0, 1, 0, 0, 0][1, 0, 0, 0, 0]- random.sample() # 采样,采样长度不能超过列表的长度,且列表中的每个元素每次都只能被采样一次Signature: random.sample(population, k)Docstring:Chooses k unique random elements from a population sequence or set.random.sample(x,k=3)  => [0, 4, 1]

五,元组

元组是不可变的有序序列,是顺序表。元组创建之后就不能在更改,所以没有增,删,改等操作。

1,元组的构建

- () :小括号构建元组当小括号里面只有一个元素是,要用逗号分割(1,)这才是元组,(1)不是元组-  tuple():括号内为空或者一个可迭代对象Init signature: tuple(self, /, *args, **kwargs)Docstring:     tuple() -> empty tupletuple(iterable) -> tuple initialized from iterable's itemstuple(range(5))(0, 1, 2, 3, 4)

2,元组的操作

2.1 查找跟列表的查找方式一样,通过索引查找a = ([3],) * 3a => ([3], [3], [3])a[0] = 300 #报错,因为元组里面的元素不能变动a[0][0] = 300 #这个修改的不是a这个元组里面的元素,而是元素指向的实际内容,元素其实还是没变的,因为a[0]这个元素实际上指向的是[3]这个列表,所以a[0][0] = 300实际上是对[3]的修改,而列表是可修改的。a => ([300], [300], [300]) # a[1].append(4)a => ([300, 4], [300, 4], [300, 4])

六,字符串str

1,字符串简介

- 由若干个字符组成的有序的序列(顺序表实现),是字符的集合
- 使用单引号,双引号,三引号引住的字符序列
- 字符串是不可变对象,是字面常量,一旦定义,不可更改
python3起,字符串都是Unicode类型

2,字符串构造

s = 'string'
s1 = "string1"
s2 = ''' this's a "string" '''
s3 = 'hello \n world'

3,字符串操作

因为字符串是不可变字面常量,定义后就不能进行增,删,改操作- 查s = 'abcde'for i in s:print(i,type(i))a <class 'str'>b <class 'str'>c <class 'str'>d <class 'str'>e <class 'str'>s[-1] => eindex,rinex(从右往左找),count,len等用法都跟列表的一样,优劣也一样- findDocstring:S.find(sub[, start[, end]]) -> intReturn the lowest index in S where substring sub is found,such that sub is contained within S[start:end].  Optionalarguments start and end are interpreted as in slice notation.s = 'abcdeabcd's.find('bc') => 1 #返回匹配到的索引位置s.find('bd') => -1 #如果没有匹配到字串,返回-1-rfind: 从右往左找,但是返回的索引还是正索引,如果没找到,返回负数s.rfind('bc') => 6- 时间复杂度find,index和count方法的时间复杂度都是O(n)随着字符串长度的增加,效率会下降4,字符串拼接'a' + 'b' => 'ab''ab' * 3 => 'ababab'str.join()Docstring:S.join(iterable) -> strReturn a string which is the concatenation of the strings in theiterable.  The separator between elements is S.'abc'.join('ABC') => 'AabcBabcC'':'.join('ABC') => 'A:B:C'':'.join(("1","2","3")) => '1:2:3'':'.join(["1","2","3"]) => '1:2:3'可以看到join的作用就是,用.前面的字符串分割()内的可迭代对象。可迭代对象里面的元素要是str类型的,如果不是需要转换5,字符串分割字符串分割看起来是改变了字符串,但是实际字符串并没有改变,只是给你生成了一个新的符合规则的字符串。- splitS.split(sep=None, maxsplit=-1) -> list of strings':'.join('ABC').split(":",1) => ['A', 'B:C']split 使用分割符分割给出的字符串,返回一个列表,可以指定切割次数。y  = ':'.join('ABC').split(":") .append('D')请问y的值是什么?结果时None。因为append函数没有返回,或者说返回的结果是None,所以y的值就被赋为None特殊例子":a:b:c:".split(":")   => ['', 'a', 'b', 'c', '']":a:b:c:".split("#")  => [':a:b:c:']  # 如果切割符在字符串中并不存在,则将整个字符串做为一个元素放到列表中返回“a\nb\r\nc\rd\te     \n f”.split()  =>['a', 'b', 'c', 'd', 'e', 'f'] #不指定切割福,默认就会切割尽可能长的连续的空白字符“a\nb\r\nc\rd\te     \n f”.split("\n")  =>[['a', 'b\r', 'c\rd\te     ', ' f']-rsplit  用法跟split一样,只不过是从右往左执行Docstring:S.rsplit(sep=None, maxsplit=-1) -> list of strings-splitlines (把\n,\r等换行符切掉)"a\nb\r\nc\rd\te     \n f".splitlines() => ['a', 'b', 'c', 'd\te     ', ' f']- partitionDocstring:S.partition(sep) -> (head, sep, tail)"a,b,c,d".partition(',') => ('a', ',', 'b,c,d')可以看到partition指定分隔符后不管有多少个符合条件的,它都只切割一次,把字符串用分割符分割成两部分后以元组的方式返回特殊例子:"a:b:c".partition("#") => ('a:b:c', '', '')"a:b:c".rpartition("#") => ('', '', 'a:b:c')6,字符串替换- replaceDocstring:S.replace(old, new[, count]) -> str"a:b:c".replace(':','#')  => 'a#b#c' # 返回的还是一个字符串,原字符串并没有被修改特殊例子:"www.whp.com".replace('w','m') => 'mmm.mhp.com' # 默认全部替换"www.whp.com".replace('w','m',2) => 'mmw.whp.com' # 替换两次"www.whp.com".replace('ww','w') => 'ww.whp.com' # 为什么是这个结果,结果不是还有ww吗,为什么没被替换成w.whp.com?因为对字符串的处理是一直往前走的,处理过的内容就不再处理,所以第一个w已经不在处理范围内了。7,字符串移除- strip (脱)Docstring:S.strip([chars]) -> str'\r\na,b '.strip() => 'a,b' # strip默认将字符串两头的空白字符全部去掉。'a,b,c,b,c'.strip('ac') => ',b,c,b,' # 为什么是这样的结果?- rstrip(右脱)'\r\na,b '.rstrip() => '\r\na,b' # rstrip默认将字符串右边的空白字符全部去掉。- lstrip(左脱)'\r\na,b '.lstrip() => 'a,b ' # lstrip默认将字符串左边的空白字符全部去掉。8,字符串格式化- printf风格的字符串格式化"***%d%5.1f***" % (100,1.264) # 5表示字符占5位右对齐,.1表示截取到小数点后一位返回:'***100  1.3***'"***%d%-5.2f***" % (100,1.264) # -5表示字符占5位,左对齐,.2表示截取小数点后两位"My name is %s,I'm %d" % ('whp',30)返回:"My name is whp,I'm 30""My name is %(name)s,I'm %(age)d" % {'name':'whp',"age":30}返回:"My name is whp,I'm 30"- format"{2}:{1}-{0} {b} {a}".format(10,20,30,a='whp',b=200) # {}内的0,1,2代表的是format内元素的索引,a='whp',b=200 不能被索引,所以只能通过a,b标识符来获取到值返回:'30:20-10 200 whp'"{} +++ {}".format((10,20))返回:IndexError: tuple index out of range # 因为(10,20)是一个元组,只能算是一个元素"{0} +++ {0}".format((10,20))返回:'(10, 20) +++ (10, 20)'"{0[0]} +++ {0[1]}".format((10,20))返回:'10 +++ 20'"{} +++ {}".format(*(10,20)) # *(10,20) 将元组解构了返回:'10 +++ 20'  format格式化时间d = datetime.datetime.now()d = datetime.datetime(2021, 10, 31, 22, 6, 41, 68571)"{}".format(d1)返回:'2021-10-31 22:06:41.068571'"{:%Y-%m-%d %H:%M:%S}".format(d1)返回:'2021-10-31 22:06:41'"{0:b} {0:X} {0:o} {0}".format(20)返回: '10100 14 24 20'"{0:#b} {0:#X} {0:#o} {0}".format(20)返回:'0b10100 0X14 0o24 20'浮点数处理"{:<7.3f}".format(1.4454545) # 对1.4454545进行格式化处理,.3表示返回小数点后三位,7表示占7位,<表示向左对齐,默认就是向左对齐返回:'1.445  '"{:>7.3f}".format(1.4454545) # 对1.4454545进行格式化处理,.3表示返回小数点后三位,7表示占7位,>表示向右对齐返回:'  1.445'

python基础学习(三)之线性数据结构相关推荐

  1. python基础学习(一)---数据结构和流程

    Python数据结构 1 整数和浮点数 2 字符串和编码 3 list和tuple list列表 tuple元组 4 dict字典 5 set集 Python语句 1 条件判断语句 2 循环语句 1. ...

  2. python基础语法-三大内建数据结构之列表(list)

    定义 列表(list):一组有顺序的数据的集合(用中括号包裹). 元组tuple是一种特殊的列表,不能修改,具有list除了修改的所有操作(用圆括号括着).这里的不可修改是指那一份数据不可修改,两个t ...

  3. python基础语法-三大内建数据结构之字典(dict)

    定义 字典(dict):一组无序的组合数据,以键值对形式出现. 声明 # 1 dict1 = {} # 2 dict1 = {"one": 1, "two": ...

  4. python基础语法-三大内建数据结构之集合(set)

    定义 set(集合):一组无重复无序的数据.就像数学中集合的概念.它没有标准的括号包裹,[]表示list,()表示tuple,{}表示dict. 但是我们可以用带值的大括号来定义. 还有一种集合叫冰冻 ...

  5. 【Python基础学习】基本数据结构:列表、元组、栈、字典、集合与队列

    [Python基础学习]基本数据结构:列表.元组.栈.字典.集合与队列 Python的基本数据结构中,包含了列表.元组等一系列数组式数据结构,但各个结构各有不同.因此单独列出来,分析相同与不同 列表( ...

  6. Python基础学习笔记三

    Python基础学习笔记三 print和import print可以用,分割变量来输出 import copy import copy as co from copy import deepcopy ...

  7. python基础学习_转行零基础该如何学习python?很庆幸,三年前的我选对了

    这似乎是一个如荼如火的行业,对于一直在思考着转行的我,提供了一个不错的方向. 这个行业当然就是python程序员,真正开始决定转行是在24岁的时候,到现在已经有三年多了,我从零开始,每天用业余两个小时 ...

  8. Python基础学习笔记之(一)

    Python基础学习笔记之(一) zouxy09@qq.com http://blog.csdn.net/zouxy09 前段时间参加微软的windows Azure云计算的一个小培训,其中Pytho ...

  9. Python基础学习笔记(一)

    Python基础学习笔记(一) 基本数据类型   整型(int):1.2.10--   浮点型(float):1.2.2.4.10.00--   布尔型(bool):True.False   字符串( ...

  10. python自学用什么书好-适合python基础学习的好书籍

    分享几本python基础学习的书籍给大家 <Python编程:从入门到实践> 内容简介:本书是一本针对所有层次的Python 读者而作的Python 入门书.全书分两部分:第一部分介绍用P ...

最新文章

  1. TensorFlow1.8.0正式发布,Bug修复和改进内容都在这里了
  2. mysql怎么加全局锁_MySQL锁机制/管理(并发锁,行锁,表锁,预加锁,全局锁等等)
  3. angular 学习理解笔记
  4. ITK:将BinaryMorphologicalClosingFilter应用于给定LabelMap的一个LabelObject
  5. 系统集成项目管理工程师考试大纲第二版
  6. jmeter模拟登陆
  7. inchat库下载 python_Linux 环境下安装 Python3 的操作方法
  8. CSDN 编辑器使用指南
  9. 墙裂推荐!2020Android阿里腾讯百度字节美团网易爱奇艺校招面试汇总
  10. ES6 走马观花(ECMAScript2015 新特性)
  11. 用英语介绍计算机系统,如何用英语介绍计算机系统
  12. 怎么完全卸载赛门铁克_赛门铁克(sep)卸载方法
  13. Clouda 之我见
  14. javase简单入门1
  15. 主流图数据库对比,Neo4j、ArangoDB、OrientDB、JanusGraph、HugeGraph
  16. Java基础Swing实现网络聊天室(视频+源码)
  17. postgresql11.2修改分区表中复合索引字段长度遇到的BUG
  18. SQL 获取 weekday
  19. Python中__dict__属性的详解(思维导图版)
  20. TS7016: Could not find a declaration file for module ‘@/api/checkitem.js‘.解决办法

热门文章

  1. 编译PX4时,报错error ‘i‘ does not name a type __ULong i[2];解决方法
  2. 2.2 Collections类 (Collections源码解析)
  3. 第一次实验结论与总结
  4. Android 项目是如何编译成.apk的
  5. (python)生产者消费者模型
  6. 《Java SE实战指南》10:特性修饰符
  7. NVIDIA JETSON AGX XAVIER DEVELOPER KIT刷机教程(各种踩雷篇)
  8. 用for循环解决鸡兔同笼问题:上有三十五头,下有九十四足,问雉兔各几何?
  9. MNN C++输入图片多通道
  10. Linux_CA三种申请证书的方法