Python读CookBook之数据结构和算法

1.将序列分解为单独的变量

任何序列(可迭代的变量)都可以通过一个简单的赋值操作来分解为单独的变量。唯一的要求是变量的总数和结构要与序列相吻合

data = ["Mike", 22, 73, (2017, 12, 28)]
name, age, score, (year, month, date) = data
print(name, age, score, year, month, date)
Mike 22 73 2017 12 28

分解操作时,可以用一个用不到的变量名来丢弃某一变量

data = ["Mike", 22, 73, (2017, 12, 28)]
_, age, score, (_, _, date) = data
print(age, score, date)
22 73 28

2.从任意长度的可迭代对象中分解元素

使用*表达式可以表示被*修饰的变量代表n个元素的列表 n 可以为0 可以为无限大

record = ("Jack", 22, "15012345678", "18099883311")
name, age, *phone = record
print(name, age, phone)
Jack 22 [‘15012345678‘, ‘18099883311‘]

注意:分解一个元素时,只能有一个被*修饰的变量

3.保存最后N个元素

from collections import deque

def search(lines, pattern, history=5):
    previous_lines = deque(maxlen=history)
    for line in lines:
        if pattern in line:
            yield line, previous_lines
        previous_lines.append(line)

if __name__ == "__main__":
    with open("D:/Test1.txt") as f:
        for line, prelines in search(f, "456", 5):
            for pline in prelines:
                print(pline, end="")
            print(line, end="")
            print("-"*20)
123
456
--------------------

collection模块的deque能很好的完成这个工作,切deque在头尾位置插入数据时时间复杂度都为 O(1)

4.找到最大最小N个元素

①找最大最小的元素

使用 min() max()函数,时间复杂度 O(n)--  n为序列的长度

num = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
maxnum = max(num)
minnum = min(num)
print(maxnum, "----", minnum)
42 ---- -4

②相对于列表长度极小(例如 N=2)

使用heapq库中的和heapify使序列成堆的形式分布,且第一个元素永远是最小的那个元素,此时,使用heappop()函数会弹出最小的那个元素,第二小的取而代之处于首元素的位置。

num = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
heap = list(num)
heapq.heapify(heap)
print(heap)
print("="*50)

print(heapq.heappop(heap))
print(heap)
print("="*50)

print(heapq.heappop(heap))
print(heap)
print("="*50)
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
==================================================
-4
[1, 2, 2, 23, 7, 8, 18, 23, 42, 37]
==================================================
1
[2, 2, 8, 23, 7, 37, 18, 23, 42]
==================================================

该方法时间复杂度为O(logn) n 为序列长度

③N相对数组长度小(例如N = 4)

使用heapq模块中的 nlargest() nsmallest()函数,这两个函数可以接受一个key作为参数

data = [
    {"name": "Jack", "age": 21, "score": 99},
    {"name": "Ben", "age": 22, "score": 90},
    {"name": "Mark", "age": 20, "score": 72},
    {"name": "Cook", "age": 20, "score": 53},
    {"name": "Antony", "age": 23, "score": 94},
    {"name": "Chris", "age": 24, "score": 62},
    {"name": "Ken", "age": 22, "score": 81},
    {"name": "Jackie", "age": 20, "score": 85},
    {"name": "David", "age": 22, "score": 89},
    {"name": "Jackson", "age": 23, "score": 89},
    {"name": "Lucy", "age": 22, "score": 77}
]

scoreMax = heapq.nlargest(4, data, key=lambda s: s["score"])
scoreMin = heapq.nsmallest(4, data, key=lambda s: s["score"])
print(scoreMax)
print(scoreMin)
[{‘name‘: ‘Jack‘, ‘age‘: 21, ‘score‘: 99}, {‘name‘: ‘Antony‘, ‘age‘: 23, ‘score‘: 94}, {‘name‘: ‘Ben‘, ‘age‘: 22, ‘score‘: 90}, {‘name‘: ‘David‘, ‘age‘: 22, ‘score‘: 89}]
[{‘name‘: ‘Cook‘, ‘age‘: 20, ‘score‘: 53}, {‘name‘: ‘Chris‘, ‘age‘: 24, ‘score‘: 62}, {‘name‘: ‘Mark‘, ‘age‘: 20, ‘score‘: 72}, {‘name‘: ‘Lucy‘, ‘age‘: 22, ‘score‘: 77}]

上面现象可以看出,有相同数据时,优先选取顺序在前的

④当N接近于序列的大小

使用sorted()并进行切片操作

num = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
lst = sorted(num)
lstmax = lst[:8]
print(lstmax)
lstrev = sorted(num, reverse=True)
lstmin = lstrev[:8]
print(lstmin)

num = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
lst = sorted(num)
lstmax = lst[:8]
print(lstmax)
lstmin = lst[-8:]
print(lstmin)

5.实现优先级队列

使用heapq(堆操作)的heappush heappop实现这一操作

import heapq

class PriorityQueue(object):
    def __init__(self):
        self._queue = []
        self._index = 0

    def push(self, item, priority):
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1

    def pop(self):
        return heapq.heappop(self._queue)[-1]

class Item(object):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name

if __name__ == "__main__":
    q = PriorityQueue()
    q.push(Item("Jack"), 1)
    q.push(Item("Mike"), 2)
    q.push(Item("Ben"), 3)
    q.push(Item("David"), 1)
    for i in range(q._index):
        print(q.pop())
Ben
Mike
Jack
David

6.在字典中将键映射到多个值上:

使用collection模块中的defaultdict类来实现

当属性为list

from collections import defaultdict

d = defaultdict(list)
d["a"].append(1)
d["a"].append(1)
d["b"].append(2)
d["c"].append(3)
d["d"].append(4)

for key, values in d.items():
    print(key, ":", values)
a : [1, 1]
b : [2]
c : [3]
d : [4]

当属性为set

from collections import defaultdict

d = defaultdict(set)
d["a"].add(1)
d["a"].add(1)
d["b"].add(2)
d["c"].add(3)
d["d"].add(4)

for key, values in d.items():
    print(key, ":", values)
a : {1}
b : {2}
c : {3}
d : {4}

不过这种方法会预先建立一个空的表项

也可通过普通字典的setdefault属性来实现这个功能

d = {}
d.setdefault("a", []).append(1)
d.setdefault("a", []).append(2)
d.setdefault("b", []).append(3)
d.setdefault("c", []).append(4)

for key, values in d.items():
    print(key, ":", values)
a : [1, 2]
b : [3]
c : [4]

不过这种方法每次都会创建一个新实例 [] 或者 ()

列举一个循环插入的示例:

from collections import defaultdict

d = defaultdict(list)

for key, values in pairs:
    d[key].append[values]

7.让字典保持有序

使用collection模块中的OrderedDict

from collections import OrderedDict

d = OrderedDict()
d["foo"] = 1
d["bar"] = 2
d["spam"] = 3
d["grok"] = 4
d["foo"] = 5

for k in d:
    print(k, ":", d[k])
foo : 5
bar : 2
spam : 3
grok : 4

由此可见,更改已经插入的键的值不会影响该项在排序字典中的位置

OrderedDict由一组双向链表维护,大小为普通字典内存的两倍

可适用于JSON格式文件编码时控制各字段的顺序

8.与字典有关的计算问题

prices = {
    "ACME": 45.23,
    "AAPL": 612.78,
    "IBM": 205.55,
    "HPQ": 37.20,
    "FB": 10.75
}

print(max(zip(prices.keys(), prices.values())))
print(min(zip(prices.keys(), prices.values())))
print("-"*10)
prices_sorted = sorted(zip(prices.keys(), prices.values()))
for k in prices_sorted:
    print(k)
(‘IBM‘, 205.55)
(‘AAPL‘, 612.78)
----------
(‘AAPL‘, 612.78)
(‘ACME‘, 45.23)
(‘FB‘, 10.75)
(‘HPQ‘, 37.2)
(‘IBM‘, 205.55)

zip可以反转key和value,且不改变字典原结构,属于迭代器,只能被消费一次

如果比较字典 只会用key进行比较

如果我们换一种方式,操作如下

prices = {
    "ACME": 45.23,
    "AAPL": 612.78,
    "IBM": 205.55,
    "HPQ": 37.20,
    "FB": 10.75
}

minItem = min(prices, key=lambda k: prices[k])
maxItem = max(prices, key=lambda k: prices[k])
minValue = prices[minItem]
maxValue = prices[maxItem]
print(minItem, maxItem, "="*5, minValue, maxValue)
FB AAPL ===== 10.75 612.78

9.在两个字典中寻找相同点

通过keys() items()  的 + - & 计算进行操作

a = {"x": 1, "y": 2, "z": 3}
b = {"w": 10, "x": 11, "y": 2}
# Find Common Keys
print(a.keys() & b.keys())
# Find keys in a but not in b
print(a.keys() - b.keys())
# Find {keys,valus} in commom
print(a.items() & b.items())
# Create a new dictionary with certain keys removed
c = {key: a[key] for key in a.keys() - {"z", "w"}}
print(c)
{‘y‘, ‘x‘}
{‘z‘}
{(‘y‘, 2)}
{‘y‘: 2, ‘x‘: 1}

10.从序列中移除重复项目且保持元素间顺序不变

如过序列中的值可哈希 ---- 生存期内不可变的对象,有一个__hash__()方法,如整数、浮点数、字符串、元组

def dedupe(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)

a = [1, 5, 2, 1, 9, 1, 5, 10]
lst = list(dedupe(a))
print(lst)
[1, 5, 2, 9, 10]

如果值不可哈希

def dedupe(items, key=None):
    seen = set()
    for item in items:
        val = item if key is None else key(item)
        if val not in seen:
            yield item
            seen.add(val)

b = [{"x": 1, "y": 2},
     {"x": 1, "y": 3},
     {"x": 1, "y": 2},
     {"x": 2, "y": 4},
     ]
lst = list(dedupe(b, key=lambda k: (k["x"], k["y"])))
print(lst)
lst2 = list(dedupe(b, key=lambda k: (k["x"])))
print(lst2)

想办法将不可哈希的项改为可哈希的项

set也可以去重复,但是无法保证原来的顺序不变

11.对切片命名

s = "Hello World"
a = slice(2, 5)
print(s[a])
llo

可以使用indice(size)将slice限定在安全的范围内

s = "HelloWorld"
a = slice(5, 50, 2)
print(a.start)
print(a.stop)
print(a.step)
print(a.indices(len(s)))
for i in range(*a.indices(len(s))):
    print(s[i])
5
50
2
(5, 10, 2)
W
r
d

这样就不会因为切片的大小问题出现IndexError

12.找出序列中出现最多次数的元素

collection中的Counter类实现此功能

from collections import Counter

words = [
    ‘ear‘, ‘head‘, ‘nose‘, ‘ear‘, ‘look‘, ‘see‘,
    ‘head‘, ‘ear‘, ‘nose‘, ‘ear‘, ‘read‘, ‘see‘,
    ‘head‘, ‘see‘, ‘watch‘, ‘look‘, ‘hair‘, ‘see‘,
    ‘ear‘, ‘big‘, ‘small‘, ‘do‘, ‘hair‘, ‘nose‘,
    ‘head‘, ‘big‘, ‘large‘, ‘ear‘, ‘do‘, ‘ear‘
]

word_counter = Counter(words)
most_three_couter = word_counter.most_common(3)
print(most_three_couter)
[(‘ear‘, 7), (‘head‘, 4), (‘see‘, 4)]

手动增加计数

words = [
    ‘ear‘, ‘head‘, ‘nose‘, ‘ear‘, ‘look‘, ‘see‘,
    ‘head‘, ‘ear‘, ‘nose‘, ‘ear‘, ‘read‘, ‘see‘,
    ‘head‘, ‘see‘, ‘watch‘, ‘look‘, ‘hair‘, ‘see‘,
    ‘ear‘, ‘big‘, ‘small‘, ‘do‘, ‘hair‘, ‘nose‘,
    ‘head‘, ‘big‘, ‘large‘, ‘ear‘, ‘do‘, ‘ear‘
]

addwords = [‘ear‘, ‘head‘, ‘small‘, ‘big‘, ‘do‘]

word_counter = Counter(words)

for word in addwords:
    word_counter[word] += 1

print(word_counter)

words = [
    ‘ear‘, ‘head‘, ‘nose‘, ‘ear‘, ‘look‘, ‘see‘,
    ‘head‘, ‘ear‘, ‘nose‘, ‘ear‘, ‘read‘, ‘see‘,
    ‘head‘, ‘see‘, ‘watch‘, ‘look‘, ‘hair‘, ‘see‘,
    ‘ear‘, ‘big‘, ‘small‘, ‘do‘, ‘hair‘, ‘nose‘,
    ‘head‘, ‘big‘, ‘large‘, ‘ear‘, ‘do‘, ‘ear‘
]

addwords = [‘ear‘, ‘head‘, ‘small‘, ‘big‘, ‘do‘]

word_counter = Counter(words)

word_counter.update(addwords)

print(word_counter)
Counter({‘ear‘: 8, ‘head‘: 5, ‘see‘: 4, ‘nose‘: 3, ‘big‘: 3, ‘do‘: 3, ‘look‘: 2, ‘hair‘: 2, ‘small‘: 2, ‘read‘: 1, ‘watch‘: 1, ‘large‘: 1})

Counter可以做加减法

words = [
    ‘ear‘, ‘head‘, ‘nose‘, ‘ear‘, ‘look‘, ‘see‘,
    ‘head‘, ‘ear‘, ‘nose‘, ‘ear‘, ‘read‘, ‘see‘,
    ‘head‘, ‘see‘, ‘watch‘, ‘look‘, ‘hair‘, ‘see‘,
    ‘ear‘, ‘big‘, ‘small‘, ‘do‘, ‘hair‘, ‘nose‘,
    ‘head‘, ‘big‘, ‘large‘, ‘ear‘, ‘do‘, ‘ear‘
]

addwords = [‘ear‘, ‘head‘, ‘small‘, ‘big‘, ‘do‘]

word_counter = Counter(words)
addwords_counter = Counter(addwords)
mix = word_counter + addwords_counter
print(mix)
subtract = word_counter - addwords_counter
print(subtract)
Counter({‘ear‘: 8, ‘head‘: 5, ‘see‘: 4, ‘nose‘: 3, ‘big‘: 3, ‘do‘: 3, ‘look‘: 2, ‘hair‘: 2, ‘small‘: 2, ‘read‘: 1, ‘watch‘: 1, ‘large‘: 1})
Counter({‘ear‘: 6, ‘see‘: 4, ‘head‘: 3, ‘nose‘: 3, ‘look‘: 2, ‘hair‘: 2, ‘read‘: 1, ‘watch‘: 1, ‘big‘: 1, ‘do‘: 1, ‘large‘: 1})

13.通过公共键对字典列表排序

使用operator中的itemgetter函数进行排序

from operator import itemgetter

data = [
    {‘ID‘: 1, "Name": "Ben", "score": 88},
    {‘ID‘: 2, "Name": "Jack", "score": 92},
    {‘ID‘: 3, "Name": "Mike", "score": 73},
    {‘ID‘: 4, "Name": "Mark", "score": 81},
    {‘ID‘: 5, "Name": "Lucy", "score": 95},
]

rows_by_Name = sorted(data, key=itemgetter(‘Name‘))
rows_by_Score = sorted(data, key=itemgetter(‘score‘))
print(rows_by_Name)
print(rows_by_Score)
[{‘ID‘: 1, ‘Name‘: ‘Ben‘, ‘score‘: 88}, {‘ID‘: 2, ‘Name‘: ‘Jack‘, ‘score‘: 92}, {‘ID‘: 5, ‘Name‘: ‘Lucy‘, ‘score‘: 95}, {‘ID‘: 4, ‘Name‘: ‘Mark‘, ‘score‘: 81}, {‘ID‘: 3, ‘Name‘: ‘Mike‘, ‘score‘: 73}]
[{‘ID‘: 3, ‘Name‘: ‘Mike‘, ‘score‘: 73}, {‘ID‘: 4, ‘Name‘: ‘Mark‘, ‘score‘: 81}, {‘ID‘: 1, ‘Name‘: ‘Ben‘, ‘score‘: 88}, {‘ID‘: 2, ‘Name‘: ‘Jack‘, ‘score‘: 92}, {‘ID‘: 5, ‘Name‘: ‘Lucy‘, ‘score‘: 95}]

可以用lamda来代替itemgetter 但是通常itemgetter效率高

14.对不原生支持比较操作的对象排序

比如必将两个对象就可以通过对象的属性进行比较

class User(object):

    def __init__(self, id):
        self.id = id

    def __repr__(self):
        return "User({})".format(self.id)

users = [User(2), User(3), User(1)]
print(users)
user_ordered = sorted(users, key=lambda k: k.id)
print(user_ordered)
[User(2), User(3), User(1)]
[User(1), User(2), User(3)]

也可以使用operator中的attrgetter()

from operator import attrgetter

class User(object):

    def __init__(self, id):
        self.id = id

    def __repr__(self):
        return "User({})".format(self.id)

users = [User(2), User(3), User(1)]
print(users)
user_ordered = sorted(users, key=attrgetter(‘id‘))
print(user_ordered)

同理使用attrgetter的效率高一些

15.根据字段将记录分组

通过itemgetter与itertools模块中的groupby实现

from operator import itemgetterfrom itertools import groupby

data = [    {"Name": "Jack", "Age": 21},    {"Name": "Ben", "Age": 22},    {"Name": "Lucy", "Age": 23},    {"Name": "Lily", "Age": 23},    {"Name": "Mike", "Age": 21},    {"Name": "Martin", "Age": 21},    {"Name": "Susan", "Age": 23},    {"Name": "Rose", "Age": 22},    {"Name": "Hill", "Age": 22},]

sortdata = sorted(data, key=itemgetter(‘Age‘))

for age, rows in groupby(sortdata,key=itemgetter("Age")):    print(age)    for row in rows:        print(" ", row)
21
  {‘Name‘: ‘Jack‘, ‘Age‘: 21}
  {‘Name‘: ‘Mike‘, ‘Age‘: 21}
  {‘Name‘: ‘Martin‘, ‘Age‘: 21}
22
  {‘Name‘: ‘Ben‘, ‘Age‘: 22}
  {‘Name‘: ‘Rose‘, ‘Age‘: 22}
  {‘Name‘: ‘Hill‘, ‘Age‘: 22}
23
  {‘Name‘: ‘Lucy‘, ‘Age‘: 23}
  {‘Name‘: ‘Lily‘, ‘Age‘: 23}
  {‘Name‘: ‘Susan‘, ‘Age‘: 23}

分组之前先对序列进行排序

16.筛选序列中的元素:

内建函数fiter

def is_int(Val):
    if isinstance(Val, int):
        return True
    else:
        return False

a = [1, 2, "aaa", "b", 5, "cc"]
b = list(filter(is_int, a))
print(b)
[1, 2, 5]

itertools库中的compress

from itertools import compress

name = ["Jack", "Lucy", "Ben", "Lily", "Mike"]
age = [8, 11, 12, 9, 11]

more = [n > 10 for n in age]
print(more)

l = list(compress(name, more))
print(l)
[False, True, True, False, True]
[‘Lucy‘, ‘Ben‘, ‘Mike‘]

得到一组BOOL变量后使用compress

17.从字典中获取子集

字典推导式

data = {
    "a": 1,
    "b": 3,
    "c": 5,
    "d": 7,
    "f": 8
}

sondata1 = {k: v for k, v in data.items() if v > 4}
dataname = ["a", "c", "f"]
sondata2 = {k: v for k, v in data.items() if k in dataname}
print(sondata1)
print(sondata2)
{‘c‘: 5, ‘d‘: 7, ‘f‘: 8}
{‘a‘: 1, ‘c‘: 5, ‘f‘: 8}

18.将名称映射到序列的元素中

使用collection模块中的namedturple

from collections import  namedtuple

name = ("Data", ["Name", "Id"])
Data = namedtuple(name[0], name[1])
data = Data("Mike", 1)
print(data)

def change_data(s):
    return data._replace(**s)

a = {"Name": "Jack", "Id": 2}
b = change_data(a)
print(b)
Data(Name=‘Mike‘, Id=1)
Data(Name=‘Jack‘, Id=2)

元素不能改变,通过_replace改变,数据量大使用类__slot___方式实现

19.同时对数据做转换和运算

生成器列表

num = [1, 2, 3, 4, 5]
sum = [n * n for n in num]
print(sum)
[1, 4, 9, 16, 25]

20.将多个映射合并为单个映射

collection模块中的ChainMap

有相同的键会使用第一个字典的值,增删改查操作总是会影响第一个字典

from collections import ChainMap

a = {"x": 1, "y": 2}
b = {"z": 3, "y": 4}
c = ChainMap(a, b)
print(c)
print(c["y"])
a["x"] = 5
print(c)
ChainMap({‘x‘: 1, ‘y‘: 2}, {‘z‘: 3, ‘y‘: 4})
2
ChainMap({‘x‘: 5, ‘y‘: 2}, {‘z‘: 3, ‘y‘: 4})

同样可以建立一个用于合成两个字典的新字典 使用update

a = {"x": 1, "y": 2}
b = {"z": 3, "y": 4}
c = dict(a)
c.update(b)
print(c)
a["x"] = 5
print(c)
{‘x‘: 1, ‘y‘: 4, ‘z‘: 3}
{‘x‘: 1, ‘y‘: 4, ‘z‘: 3}

原文地址:https://www.cnblogs.com/Msh0923/p/8138271.html

时间: 2024-12-29 23:11:19

Python读CookBook之数据结构和算法的相关文章

Python Cookbook - 1 - 数据结构和算法

1 序列解压:通过*来通配 *a, b = somelist,   first, *mid, last = somelist,  a, *b = somelist 2 使用双向队列: from collections import deque q = deque(maxlen=5)  可以固定长度 q = deque()   也可以任意长度 可以从两端进行插入和删除,append, appendleft, pop , popleft 3 查找最大或最小的N个元素: 使用heapq (堆队列) h

python基础下的数据结构与算法之顺序表

一.什么是顺序表: 线性表的两种基本的实现模型: 1.将表中元素顺序地存放在一大块连续的存储区里,这样实现的表称为顺序表(或连续表).在这种实现中,元素间的顺序关系由它们的存储顺序自然表示. 2.将表中元素存放在通过链接构造起来的一系列存储模块里,这样实现的表称为链接表,简称链表. 二.顺序表两种基本形式: 三.顺序表结构: 四.实现方式: 五.增加元素: a. 尾端加入元素,时间复杂度为O(1) b. 非保序的加入元素(不常见),时间复杂度为O(1) c. 保序的元素加入,时间复杂度为O(n)

python 下的数据结构与算法---1:让一切从无关开始

我也忘了大概多久了,好像是三周多一点,终于把Data Structure and Algorithms with python以及 Problem Solving with  Algorithms and DataStructures看完了(图那部分没仔细看,太难太费时间,毕业设计开始了,有点忙).[github地址,包含了那两本书带笔记版以及下面零的代码] 所以啦,这作为第一篇总结笔记就从点无关的开始吧(也就是这两本书中提到的python相关但是与数据结构和算法无关的东东) 目录: 零:有些什

数据结构与算法+Python语言描述pdf

下载地址:网盘下载 本书基于Python语言介绍了数据结构与算法的基本知识,主要内容包括抽象数据类型和Python面向对象程序设计.线性表.字符串.栈和队列.二叉树和树.集合.排序以及算法的基本知识.本书延续问题求解的思路,从解决问题的目标来组织教学内容,注重理论与实践的并用. 下载地址:网盘下载 原文地址:https://www.cnblogs.com/cf3276625841/p/9325994.html

Python 数据结构和算法

一.写在前面 这篇文章主要介绍了python 内置的数据结构(list.set以及字典),从一些实际的场景中来说明解决方案,主要是阅读<python cookbook>时写下的阅读记录,提高自己在Python开发方面的理解,记录在这里是为了方便可以随时查阅使用.因为时间仓促以及个人理解有限,固有错误的地方请指出,谢谢! 如果转载,请保留作者信息. 邮箱地址:[email protected] 个人博客:http://www.smallartisan.site/ CSDN博客:http://bl

python数据结构与算法 38 分析树

分析树 树的结构完成以后,该是时候看看它能做点什么实事儿了.这一节里,我们研究一下分析树.分析树能够用于真实世界的结构表示,象语法或数学表达式一类的. 图1 一个简单语句的分析树 图1所示是一个简单语句的层级结构,把语句表示为树结构可以让我们用子树来分析句子的组成部分. 图2 ((7+3)?(5?2))的分析树 我们也可以把数学表达式如((7+3)?(5?2))表示为分析树,如图2.此前我们研究过完全括号表达式,这个表达式表达了什么呢?我们知道乘法的优先级比加减要高,但因为括号的关系,在做乘法之

python数据结构与算法 39 树的遍历

树的遍历 在学习完成树的基本结构以后,我们开始研究一些树的应用模式.访问树的全部节点,一般有三种模式,这些模式的不同之处,仅在于访问节点的顺序不同.我们把这种对节点的访问称为"遍历",这三种遍历模式叫做前序.中序和后序.下面我们对遍历模式作更仔细的定义,同时研究使用这延续模式的例子. 前序遍历 在前序遍历中,先访问根节点,然后用递归方式前序遍历它的左子树,最后递归方式前序遍历右子树. 中序遍历 在中序遍历中,先递归中序遍历左子树,然后访问根节点,最后递归中序遍历右子树. 后序遍历 在后

python数据结构与算法 36 树的基本概念

树 学习目标 理解什么是树及使用方法 学会使用树实现映射 用列表实现树 用类和引用实现树 用递归实现树 用堆实现优先队列 树的例子 前面我们学习过栈和队列这类线性数据结构,并且体验过递归,现在我们学习另一种通用数据结构,叫做树.树在计算机科学中应用广泛,象操作系统.图形学.数据库系统.网络等都要用到树.树和他们在自然界中的表哥--植物树--非常相似,树也有根,有分枝,有叶子.不同之处是,数据结构的树,根在顶上,而叶子在底部. 在开始学习之前,我们来研究几个普通的例子.第一个是生物学上的分级树.图

[0x01 用Python讲解数据结构与算法] 关于数据结构和算法还有编程

忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处. ——奥维德 一.学习目标 · 回顾在计算机科学.编程和问题解决过程中的基本知识: · 理解“抽象”在问题解决过程中的重要作用: · 理解并实现抽象数据结构: · 复习Python编程语言 二.写在前面 自第一台电子计算机使用线路和开关传达人类的指令以来,我们编程的思考方式有了很大的改变,在很多方面,计算机技术的发展为计算机科学家提供了众多的工具和平台去实现他们的想法.高性能理器,高速网络和大内存使得计算机研究者必须掌握在这样复杂的螺旋式通道中