数据结构和算法
简介:
数据结构是存储和组织数据的一种方式,算法是位实现业务目的的各种方法和思路,作用是大大提升程序性能
1.算法的特性:
1.独立性: 算法是独立存在的一种解决问题的方法和思想对于算法而言;实现的语言并不重要,重要的是思想;算法可以有不同的语言描述实现版本(如C描述、C++描述、Python描述等)
2.算法的五大特性:
①有输入
算法具有0个或多个输入
②有输出
算法至少有1个或多个输出
③有穷性
算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
④确定性
算法中的每一步都有确定的含义,不会出现二义性
⑤可行性
算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
时间复杂度介绍:
概述:
它可以反应一个算法的优略,表示一个算法随着问题规模变化而表现出来的趋势
大O标记法:
忽略次要条件,只考虑主要条件,就会得到时间和n(问题规模)的关系用O(n)表示
时间复杂度的的计算:
①基本操作
时间复杂度为O(1)
②顺序结构
时间复杂度按加法进行计算
③循环结构
时间复杂度按乘法进行计算
④分支结构
时间复杂度取最大值
⑤判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
⑥在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
所消耗的时间从小到大,常见的时间复杂度关系有:
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3)
空间复杂度从小到大
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3)
2.数据结构的概念:
数据结构是存储、组织数据的方式 ,指相互之间存在一种或多种特定关系的数据元素的集合
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 , 数据结构往往影响着算法的效率,相同的数据采用不同的方式也就不同的数据结构存储,带来的运行或者存储效率是不同的
数据结构羽算法的关系
数据结构只是静态的描述了数据元素之间的关系,是存储和组织数据的方式。
高效的程序需要在数据结构的基础上设计和选择算法
算法是为了解决实际问题而设计的,数据结构是算法需要处理问题的载体
最常用的数据运算有五种:
插入,删除,修改,查找,排序等
内存中的储存结构
内存是以字节为基本存储单位的, 每个基本存储空间都有自己的地址(注意:一个内存地址代表一个字节(8bit)的存储空间)。
如:
整形(int) : 4个字节
字符(char): 1个字节 . 单个字符“a”占1个字节, 字符串“abc”占3个字节
数据结构的类型
一.线性结构
特点:每个节点都可以有多个子节点(后继节点)和 多个父节点(前驱节点)
代表: 栈,队列,链表…
分类:
顺序表: 将元素顺序的放在一块连续的存储区域里面,元素间的关系有他们的存储顺序自然表示
分为:
一体式存储
分离式结构
链表: 将元素存放在通过链接构造起来的一系列存储块中,存储区是非连续的
2.顺序表介绍:
他属于线性结构的一种,栈,队列,都属于顺序表,特点是所有元素在内存中以连续的方式来存储
顺序表的存储结构
顺序表的完整信息包括两部分:
①数据区
②信息区,即元素存储区的容量和当前表中已有的元素个数
(大白话:信息区对数据进行描述、信息显示)
数据区和信息区在一起的叫一体式存储,分 开的叫分离式存储
顺序表的扩充策略
- 每次扩充固定数目的位置 (时间换空间的策略)
- 每次扩充容量加倍 (空间换时间的策略)
a. 尾端加入元素,时间复杂度为O(1)
b. 非保序的加入元素(不常见),时间复杂度为O(1) eg:在指定位置1号位置加入111元素
c. 保序的元素加入,时间复杂度为O(n)
a. 删除表尾元素,时间复杂度为O(1)
b. 非保序的元素删除(不常见),时间复杂度为O(1),比如:在指定位置删除(1号位置)删除111,153填进来
c. 保序的元素删除,时间复杂度为O(n)
3.链表介绍
他是有节点组成的,每个节点又有 数值域 和 地址域来组成
特点是所有元素在内存中以 非连续的内存空间来存储,即: 有地方就行
链表根据节点不同,主要分为:
1.单向链表 2.单向循环链表 3.双向链表 4.双向循环链表
单链表代码演示:
'''
链表介绍
属于线性结构,每个节点都有一个父节点和子节点,
链表可以看作是把节点链接起来的一个链
由元素域 和 地址域组成
单链表: 每个节点由一个数值域和地址域组成,且每一个节点的地址域指向下一个节点的地址
且最后一个节点的地址域为:None
单向循环链表:每个节点由一个数值域和地址域组成,且每一个节点的地址域指向下一个节点的地址
且最后一个节点的地址域为:第一个节点的地址
双向链表: 每个节点由1个数值域和2个地址域组成,且每个节点的地址域分别指向前后两个节点
前一个节点的前地址域为:None 最后一个节点的后地址域为:None
双向循环链表: 每个节点由1个数值域和2个地址域组成,且每个节点的地址域分别指向前后两个节点
前一个节点的前地址域为:最后一个节点 最后一个节点的后地址域为:第一个节点
'''
'''
is_empty(self) 链表是否为空
length(self) 链表长度
travel(self. ) 遍历整个链表
add(self, item) 链表头部添加元素
append(self, item) 链表尾部添加元素
insert(self, pos, item) 指定位置添加元素
remove(self, item) 删除节点
search(self, item) 查找节点是否存在
'''
# 链表节点
class Mynode:
def __init__(self, item):
self.item = item
self.next = None
# 单链表
class SingleLinkedList:
def __init__(self, head=None):
self.head = head
def add(self, item):
'''
链表头添加节点
:param item:
:return:
'''
mynode = Mynode(item)
mynode.next = self.head
self.head = mynode
def append(self, item):
'''
链表尾添加节点
:return:
'''
if self.is_empty():
mynode = Mynode(item)
mynode.next = self.head
self.head = mynode
print('添加成功')
return True
head = self.head
while head:
item1 = head
head = head.next
head = item1
mynode = Mynode(item)
head.next = mynode
print('添加成功')
return True
def is_empty(self):
'''
判断链表是否为空
:return:
'''
return self.head is None
def length(self):
'''
返回列表长度
:return:
'''
length = 0
head = self.head
while head:
head = head.next
length += 1
return length
def remove(self, item):
'''
删除第一个值为item的节点
:param item:
:return:
'''
if not self.search(item):
print(f'删除失败')
return False
if self.head.item == item:
self.head = self.head.next
print(f'删除该节点成功')
return True
head = self.head
last = self.head
while head:
if head.item == item:
last.next = head.next
print(f'删除该节点成功')
return True
last = head
head = head.next
def search(self, item):
head = self.head
count = 1
while head:
if head.item == item:
print(f'在第{count}节点找到{item}')
return True
head = head.next
print(f'未找到节点{item}')
return False
def insert(self, pos, item):
'''
指定位置插入节点
:param pos:
:param item:
:return:
'''
if pos == 0:
# 头部添加
self.add(item)
print('添加成功')
return True
pos -= 1
if pos > self.length():
print('插入失败,超长')
return False
count = 0
head = self.head
while count < pos:
head = head.next
count += 1
mynode = Mynode(item)
mynode.next = head.next
head.next = mynode
print('插入成功')
return True
def travel(self):
'''
遍历链表输出每个节点
:return:
'''
count = 0
head = self.head
while head:
count += 1
print(f'第{count}个节点,值: {head.item}')
head = head.next
if __name__ == '__main__':
sll = SingleLinkedList()
print(sll.is_empty())
sll.append(123)
sll.add('abc')
sll.add('abc')
sll.add('abc')
sll.append(0)
print(sll.is_empty())
print(sll.length())
sll.travel()
sll.insert(0, 456)
sll.travel()
sll.search('abc')
sll.search('12344')
sll.remove('1233')
sll.remove('abc')
sll.travel()
sll.remove(456)
sll.travel()
sll.add(456)
sll.search(456)