python顺序表的基本操作实现_Python学习笔记(进)-数据结构与算法

一:数据结构部分

1.大O表示法

(渐进函数)

2.时间复杂度

重点《

3.测算耗时

from timeit import timer

def test1():

li = [i for i in range(10000)]

timer1 = timer("test1","from __main__ import test2")

# 模拟次数

print("a",timer1.timeit(1000))

3.数据结构

抽象数据类型(ADT)(面向对象???)

32位:整型占4字节

1个char (字符 字母)占一个字节

顺序表基本布局 与 元素外置

4.顺序表

(存储空间必须连续

顺序表的构建需要预知数据大小申请存储空间,扩充时需要进行数据搬迁)

(1)表头信息+数据

分为两种 一体式结构和分离式结构

顺序表数据区扩充:(支持扩充的顺序表称为动态顺序表)

1.固定数目:节省空间, 扩充操作频繁,操作次数多。

2.扩充容量加倍:减少扩充执行次数,浪费空间资源

python list是根据顺序表实现的

注:8个元素存储区(整型4字节-元素外置:储存地址)

5.链表

节点:数据区+链接区

单链表:

class Node(object):

"""节点"""

def __init__(self, elem):

self.elem = elem

self.next = None

class SingleLinkList(object):

def __init__(self):

self.__head = None

def is_empty(self):

"""链表是否为空"""

return self.__head == None

def length(self):

"""链表长度"""

num = 0

cur = self.__head

while cur != None:

num += 1

cur = cur.next

return num

def travel(self):

"""遍历整个链表"""

cur = self.__head

while cur != None:

print(cur.elem)

cur = cur.next

def add(self, item):

"""链表头部添加元素,头插法"""

node = Node(item)

node.next = self.__head

self.__head = node

def append(self, item):

"""链表尾部添加元素, 尾插法"""

node = Node(item)

if self.is_empty():

self.head = node

else:

cur = self.__head

while cur.next != None:

cur = cur.next

cur.next = node

def insert(self, pos, item):

"""指定位置添加元素:param pos 从0开始"""

num = 0

node = Node(item)

pre = self.__head

if pos <= 0:

self.add(item)

elif pos > (self.length()-1):

self.append(item)

else:

while num < (pos-1):

num += 1

pre = pre.next

cur = pre.next

node.next = cur

pre.next = node

def remove(self, item):

"""删除节点"""

cur = self.__head

pre = None

while cur != None:

if cur.elem == item:

if cur == self.__head:

self.__head = cur.next

else:

pre.next = cur.next

else:

pre = cur

cur = cur.next

def search(self, item):

"""查找节点是否存在"""

cur = self.__head

while cur != None:

if cur.elem == item:

return True

else:

cur = cur.next

return False

还有 双向链表和单项循环链表 (不上代码了)

6.栈和队列

栈:(LIFO)

class Stack(object):

def __init__(self):

self.__list = []

def pop(self):

self.__list.pop()

def push(self, item):

self.__list.append(item)

def peek(self):

if self.__list:

return self.__list[-1]

else:

return None

def is_empty(self):

return not self.__list

def size(self):

return len(self.__list)

队列:(FIFO)

class Queue(object):

def __init__(self):

self.__list = []

def enqueue(self, item):

self.__list.append(item)

def dequeue(self):

self.__list.pop(0)

def is_emppty(self):

return not self.__list

def size(self):

return len(self.__list)

双向队列(懂得都懂)

7.树

二叉树数学性质

二叉树的构建、添加节点 、与遍历

class Node(object):

def __init__(self,item):

self.elem = item

self.l_child = None

self.r_child = None

class Tree(object):

def __init__(self):

self.root = None

def add(self,item):

node = Node(item)

if self.root is None:

self.root = node

return

queue = [self.root]

while queue:

cur_node = queue.pop(0)

if cur_node.l_child is None:

cur_node.l_child = node

return

else:

queue.append(cur_node.l_child)

if cur_node.r_child is None:

cur_node.r_child = node

return

else:

queue.append(cur_node.r_child)

def breadth_travel(self):

"""广度遍历"""

if self.root is None:

return

queue = [self.root]

while queue:

cur_node = queue.pop(0)

print(cur_node.elem, end=" ")

if cur_node.l_child is not None:

queue.append(cur_node.l_child)

if cur_node.r_child is not None:

queue.append(cur_node.r_child)

def preorder(self,node):

"""先序遍历,中左右"""

if node is None:

return

print(node.elem, end=" ")

self.preorder(node.l_child)

self.preorder(node.r_child)

def midorder(self,node):

"""中序遍历,左中右"""

if node is None:

return

self.midorder(node.l_child)

print(node.elem, end=" ")

self.midorder(node.r_child)

#self.midorder(0)

# self.midorder(0.l_child = 1)

# self.midorder(1.l_child = 3)

# self.midorder(3.l_child)

# print(3)

# self.midorder(3.r_child)

# print(1)

# self.midorder(1.r_child = 2)

# print(4)

# print(0)

# self.midorder(0.r_child = 2)

# self.midorder(2.l_child = 5)

# print(5)

# print(2)

# self.midorder(2.r_child = 6)

# print(6)

def postorder(self,node):

"""后序遍历,左右中"""

if node is None:

return

self.postorder(node.l_child)

self.postorder(node.r_child)

print(node.elem, end=" ")

二:算法部分

(一)排序

1.冒泡排序 时间复杂度【O(n^2)】

稳定

(自己敲的↓ 用的指针,while,for)

def bubble_sort(qlist):

a = 1

for x in range(len(qlist)-1):

cur = 1

pre = cur - 1

while cur != (len(qlist)-a):

if qlist[pre] > qlist[cur]:

qlist[pre], qlist[cur] = qlist[cur], qlist[pre]

else:

cur += 1

pre += 1

if qlist[cur] < qlist[pre]:

qlist[cur], qlist[pre] = qlist[pre], qlist[cur]

a += 1

return qlist

b = bubble_sort([5,6,4,3,2,1])

print(b)

(标准思路:for)

def bubble_sort(qlist):

for j in range(len(qlist)-1):

for i in range(len(qlist)-1-j):

if qlist[i] > qlist[i+1]:

qlist[i], qlist[i+1] = qlist[i+1], qlist[i]

return qlist

b = bubble_sort([4,3,2,1])

print(b)

2.选择排序 时间复杂度【O(n^2)】

不稳定

(自己敲 的 ↓)

# a→取几个

def sort(alist,a):

b = 0

min = b #注意放外面

for j in range(0,a):

for i in range(b+1,len(alist)):

if alist[min] > alist[i]:

min = i

alist[b], alist[min] = alist[min], alist[b]

b += 1

return alist

s = sort([2,3,4,5,1],2)

print(s)

# 全部排序

def sort(alist):

b = 0

for j in range(0,len(alist)-1):

min = b

for i in range(b+1,len(alist)):

if alist[min] > alist[i]:

min = i

alist[b], alist[min] = alist[min], alist[b]

b += 1

return alist

s = sort([6,2,3,4,5,1,8,99,77],)

print(s)

标准思路:

def sort(alist):

for j in range(0,len(alist)-1):

min = j

for i in range(j+1,len(alist)):

if alist[min] > alist[i]:

min = i

alist[j], alist[min] = alist[min], alist[j]

return alist

z = sort([2,3,4,5,1,99,88,77,66])

print(z)

3.插入排序:时间复杂度【O(n^2)】

稳定

1:(for)

def insert_sort(alist):

# 指针后移,插入元素

for i in range(1,len(alist)): #[12345] i=1234

# 后面元素与前面比较

for j in range(i,0,-1): #j=1 21 321 4321

if alist[j] < alist[j-1]:

alist[j-1], alist[j] = alist[j], alist[j-1]

return alist

b = insert_sort([6,5,4,3,2,1])

print(b)

2.(while) 最优O(n)

def insert_sort(alist):

# 插入数字

for j in range(1,len(alist)):

i = j

# 移动

while i > 0:

if alist[i] < alist[i-1]:

alist[i], alist[i-1] = alist[i-1], alist[i]

else:

break

i -= 1

return alist

b = insert_sort([6,5,4,3,2,1])

print(b)

4.希尔排序

def shell_sort(alist):

n = len(alist)

gap = n // 2

while gap > 0 :

for j in range(gap,n): # 1 2 3 4 5 6

for i in range(j,0,-gap):

if alist[i] < alist [i-gap]:

alist[i-gap], alist[i] = alist[i], alist[i-gap]

gap //= 2

return alist

s = shell_sort([6,5,4,3,2,1,88,77,99,123,6589])

print(s)

优化一点:(复杂度降低)

def shell_sort(alist):

n = len(alist)

gap = n // 2

while gap > 0 :

for j in range(gap,n): # 1 2 3 4 5 6

i = j

while i > 0:

if alist[i] < alist [i-gap]:

alist[i-gap], alist[i] = alist[i], alist[i-gap]

i -= gap

else:

break

gap //= 2

return alist

s = shell_sort([6,5,4,3,2,1,88,77,99,123,6589])

print(s)

快速排序:

def quick_sort(alist,start,end):

if start >= end:

return

mid_value = alist[start]

low = start

high = end

while low < high:

while low < high and alist[high] >= mid_value:

high -= 1

alist[low] = alist[high]

while low < high and alist[low] < mid_value:

low += 1

alist[high] = alist[low]

alist[low] = mid_value

quick_sort(alist,start,low-1)

quick_sort(alist,low+1,end)

return alist

归并排序:

def merge_sort(alist):

n = len(alist)

if n <= 1:

return alist

mid = n//2

left_pointer = 0

right_pointer = 0

# 拆分

left_li = merge_sort(alist[:mid])

right_li = merge_sort(alist[mid:])

result = []

# 重组

while left_pointer < len(left_li) and right_pointer < len(right_li):

if left_li[left_pointer] <= right_li[right_pointer]:

result.append(left_li[left_pointer])

left_pointer += 1

else:

result.append(right_li[right_pointer])

right_pointer += 1

result += left_li[left_pointer:]

result += right_li[right_pointer:]

return result

(二)搜索

1.二分查找

最优时间复杂度 O(1)

最劣时间复杂度 O(log2 n )

(自己敲出来的 emmm)

(好像只能查找 item在列表中的情况 如果不存在会无限递归。。。)

def find(alist, start, end, num):

"""start是列表起始下标, end是列表结束下标,num是查找的东西"""

left = start

right = end

mid = (left+right)//2

# 分开 查找 一次

if num > alist[mid]:

return find(alist,mid+1,end,num)

elif num < alist[mid]:

return find(alist,start,mid-1,num)

elif num == alist[mid]:

return True

else:

return False

(修改版)

def find(alist, start, end, num):

left = start

right = end

mid = (left+right)//2

# 分开 查找 一次

if left == right and alist[mid] != num:

return False

if num > alist[mid]:

return find(alist,mid+1,end,num)

elif num < alist[mid]:

return find(alist,start,mid-1,num)

elif num == alist[mid]:

return True

视频版:

1.递归版:

def binary_search(alist,item):

n = len(alist)

mid = n//2

if n > 0 :

if alist[mid] > item:

return binary_find(alist[:mid],item)

elif alist[mid] < item:

return binary_find(alist[mid+1:],item)

elif alist[mid] == item:

return True

return False

2.非递归版:

def binary_search(alist,item):

n = len(alist)

left = 0

right = n-1

while left <= right :

mid = (left + right)//2

if alist[mid] > item:

right = mid - 1

elif alist[mid] < item:

left = mid + 1

elif alist[mid] == item:

return True

return False

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值