第十七天

数据结构

第一部分

"""
数据结构
数据:能够输入到计算机中,用计算机处理的元素。
结构:数据之间的关系
数据结构:在计算机中,数据相互之间存在的一种,或者多种特定关系的元素的集合。
描述的是 计算机存储或者组织数据方式。

常见的数据结构:
1. 数组
2. 链表
3. 堆栈
4. 队列
5. 数
6. 哈希表
"""

1. 数组:在内存中存储是连续的。通过起始地址+偏移量,访问每一个元素
# 偏移量:每一个元素占用的空间大小,每个按照固定规定的size,每一个元素占的空间大小一样
# 任何一个元素:起始地址+n*size
# 线性存储,时间复杂度O(1)
# 随机访问性好,但是做添加或者删除数据非常麻烦,需要逐个处理元素
# python中列表list就是用数组

2. 链表:也是线性,不是连续的,每一个点被称为是节点, 每一个节点包含两部分
# 一部分是数据,数据域;
# 一部分是下一个元素的地址:指针域。
# 随机访问性不好,但是做添加或者删除元素非常方便,只需要修改对应的指针域即可

# 关于数组和链表的选择:
# 如果既希望有随机访问性,又保证添加删除操作,必须选一种数据结构,数组优先于链表。
# 1 空间上来说,一般情况 数组<链表 2 时间上来说,链表在操作的时候,需要先排序,或者遍历一遍
# 如果做一次插入或者删除。选数组,如果做多次插入或者删除,那么选择链表。
li=[3,5,5,7,8]
li[3]
insert

# 链表:单向链表和双向链表(了解)

3. 堆栈:简称栈 受限的线性表。只能在表头添加或者删除元素,不能在中间添加或者删除。
# 先进后出
# 应用,方法调用,异常抛出
# A---B---C---D

4. 队列:也是受限的线性表,只能在队尾进行添加、删除,不能在中间添加或者删除。
# 先进先出

# 队列也可以两端都添加、删除元素-----双端队列。(了解)可以同时实现队列和堆栈的效果。
# 跟双向链表类似,增强了随机访问性,但是降低了添加、删除元素的效率。

5. 树
# 由节点集 和 连接每对节点的有向边集 组成
# 二叉树:树形结构,特征是任意节点的孩子不超过2(0<=x<=2)
# 深度:树的层数
# m是深度,把具有2^m-1个节点的树------满二叉树----每一个节点下必须有两个孩子
# 编号的顺序,从上到下,从左到右
# 完全二叉树:当二叉树的所有节点的编号跟满二叉树的序号一致。(可以少,但是只要有,就必须编号和满二叉树一样)

# 深度遍历、广度遍历
# 深度遍历:爷爷----父亲-----儿子
# 广度遍历:爷爷----父亲----父亲兄弟----儿子----儿子兄弟

# 二叉树的遍历:先序遍历、中序遍历、后序遍历(根的顺序)
# 先序遍历:先根、左、右
# 中序遍历:先左、根、右
# 后序遍历:先左、右、根

# 对于二叉树的遍历:把数的非线性结构进行线性化操作。
6. 哈希表
# 字典用的就是哈希表
# 相当于把所有的关键字映射到一个有限的地址集,地址集的表----哈希表,映射关系(哈希函数)

第二部分
"""
算法:解决特定问题给出的方案。

任何衡量一个算法:
时间复杂度:算法执行时间长短
空间复杂度:算法为了加快速度或者执行的需要,可能牺牲空间去辅助算法的运行
"""

"""
时间复杂度:
执行时间(相对来说,在同样的电脑配置上,才可以考虑。)
执行的规模(频度):最好的执行次数、平均的执行次数、最坏执行次数(一般以最坏的为准)

"""
常数时间复杂度 O(1)------不是时间复杂度为1的意思,是指时间复杂度是一个常数
x=1
y=2

# O(n) 根据程序循环的次数
# for i in range(n):
# print(i)

# O(n^2) 跟for j in range(n)一样,都是O(n^2)
# for i in range(n):
# for j in range(i):
# print(j)

# O(logn)
while n!=0:
print("ddd")
n=n//2

常用的时间复杂度排序:O(1) < O(logn) < O(n) < O(n^2)
 第三部分
"""
查找
1. 顺序查找
2. 折半查找
"""
li=[23,-8,9,6,18,31]
1. 顺序查找:从前到后,顺序找到跟关键字相符的元素
def searchOrder(li,key):
for index,item in enumerate(li):
if item==key:
return index
else:
return -1
print(searchOrder(li,18))
print(searchOrder(li,0))
# 时间复杂度O(n)

2. 折半查找:选择中间的元素,进行比较,每次排除一半的元素
# 前提条件:必须是有序的
# 时间复杂度O(logn)
# 关键点:
# 1. 排好序
# 2. 最低点0 最高点=len(li)-1
# 3. 遍历条件 low<=high时候,折半查找 获得mid
# 4. key=li[mid] 找到
# 5. key<li[mid]:取前半段,start不变 end=mid-1
# 6. key>li[mid]:取后半段 start=mid+1 end 不变
li=[23,-8,9,6,18,31]
def findMiddle(li,key):
    low=0
    high=len(li)-1
    while low<=high:
        mid=(low+high)//2
        if key==li[mid]:
            return mid
        elif key>li[mid]:
            low=mid+1
        else:
            high=mid-1
    return -1
li.sort()
print(li)
print(findMiddle(li,18))
print(findMiddle(li,17))
# 折半查找,不一定顺序查找
# 因为折半查找需要先排序。
# 如果查找需要执行很多次,可以考虑用折半,如果只做一次,那么可能还不如顺序查找。


 

原文地址:https://www.cnblogs.com/ztx695911088/p/9136348.html