Python基础算法:排序、查找、二叉树

文章目录

排序算法

1、插入排序

import random

"""头插法"""
def insert(ls):
	for i in range(len(ls)-1):
		print('\033[036m',i,ls,'\033[0m')
		min_=ls[i]
		index=i
		for j in range(i+1,len(ls)):
			if ls[j]<min_:
				min_=ls[j]
				index=j
		ls.insert(i,min_)
		del ls[index+1]
	return ls
a=[0,11,22,33,44,55,66,77,88,99]
random.shuffle(a)
print(insert(a))

"""尾插法"""
def append_sort(ls):
    for i in range(len(ls),0,-1):
        min_=ls[0]
        index=0
        print('\033[36m',i,ls,'\033[0m')
        for j in range(i):
            if ls[j]<min_:
                min_=ls[j]
                index=j
        ls.append(min_)
        del ls[index]
    return ls
a=[0,11,22,33,44,55,66,77,88,99]
random.shuffle(a)
print(append_sort(a))

2、交换排序

import random

def interchange(ls):
	for i in range(len(ls)-1):
		print('\033[036m',i,ls,'\033[0m')
		min_=ls[i]
		index=i
		for j in range(i+1,len(ls)):
			if ls[j]<min_:
				min_=ls[j]
				index=j
		ls[i],ls[index]=min_,ls[i]
	return ls

a=[0,11,22,33,44,55,66,77,88,99]
random.shuffle(a)
print(interchange(a))

3、冒泡排序

import random

def bubble(ls):
    go_on=1
    for i in range(len(ls)-1):
        print('\033[036m',i,ls,'\033[0m')
        go_on=0
        for j in range(len(ls)-1,i,-1):
            if ls[j]<ls[j-1]:
                ls[j-1],ls[j]=ls[j],ls[j-1]
                go_on=1
        if not go_on:
            break
    return ls

a=[0,11,22,33,44,55,66,77,88,99]
random.shuffle(a)
print(bubble(a))

4、归并排序

def merge(ls1,ls2):
    ls3=[]
    i=j=0
    while i<len(ls1) and j<len(ls2):
        if ls1[i]<ls2[j]:
            ls3.append(ls1[i])
            print('\033[036m',i,ls3,'\033[0m')
            i+=1
        else:
            ls3.append(ls2[j])
            print('\033[036m',j,ls3,'\033[0m')
            j+=1
    if i<len(ls1):
        for ii in ls1[i:]:
            ls3.append(ii)
    else:
        for jj in ls2[j:]:
            ls3.append(jj)
    return ls3

a=[1,3,5,6]
b=[0,2,4,7,8,9]
c=merge(a,b)
print(c)

查找算法

1、顺序查找

# sequential search
def sequential(ls,value):
    for i in range(len(ls)):
        print('\033[036m',i,ls[i],'\033[0m')  # show steps
        if ls[i]==value:
            return i

l=[0,11,22,33,44,55,66,77,88,99]
print(l)
for i in range(9):
    v=int(input('look up number').strip())
    print(sequential(l,v))

2、二分查找

# binary search
def binary(ls,value):
    head,tail=0,len(ls)-1
    mid=(head+tail)//2
    while head<=tail:
        if ls[mid]==value:
            return mid
        elif value<ls[mid]:
            print('\033[036m',mid,ls[mid],'\033[0m')  # show steps
            tail=mid-1
            mid=(head+tail)//2
        elif ls[mid]<value:
            print('\033[036m',mid,ls[mid],'\033[0m')  # show steps
            head=mid+1
            mid=(head+tail)//2

l=[0,11,22,33,44,55,66,77,88,99]
print(l)
for i in range(9):
    v=int(input('look up number').strip())
    print(binary(l,v))

3、字符串查找

# string find 1
def find1(sentence,word,start=0,end=None):
    if not end:
        end=len(sentence)-len(word)+1
    if end>start and end<=len(sentence)-len(word)+1:
        for i in range(start,end):
            for j in range(len(word)):
                print(i,j,sentence[i+j],word[j],sep='\t')  # show steps
                if sentence[i+j]!=word[j]:
                    break
            else:
                return i

s='To see a world in a grain of sand. And a heaven in wild flower.'
print('find1(s," a ",7)',find1(s,' a ',7))
print('find1(s," a ",7,17)',find1(s,' a ',7,17))
for i in range(9):
    for i in range(len(s)):
        print(i%10,end='')
    print('\033[036m')
    print(s,'\033[0m')
    w=input('word: ')
    n=input('start number: ')
    e=input('end number: ')
    if w and n.isdigit() and e.isdigit():
        print('\033[031m',find1(s,w,int(n),int(e)),'\033[0m')

完全二叉树

1、创建树节点【TN】、创建树【FBT】、打印树【FBT.tree】

import math
# Tree Node
class TN:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
    def __str__(self):
        return str(self.data)


# Full Binary Tree
class FBT:
    def __init__(self, ls):
        self.nodes = [TN(i) for i in ls]
        for i in range(len(self.nodes)-1, 0, -1):
            if i % 2 == 0:
                self.nodes[int(i/2-1)].right = self.nodes[i]
            else:
                self.nodes[int(i/2)].left = self.nodes[i]
        self.tree()
    # 树结构
    def tree(self):
        # 节点数
        length = len(self.nodes)
        # 总层数
        layers = math.ceil(math.log2(length))
        # 总宽度
        width = 2 ** layers - 1
        # 分隔符
        branch = ' '
        # 初始化顶层,并打印
        layer = [self.nodes[0].data]
        interval = 2 ** layers - 1
        for i in range(2, length + 1):
            if math.log2(i) % 1 == 0:
                # 打印当前层
                print((branch * interval).join(layer).center(width))
                layer = []
            # 元素进入当前层
            layer.append(self.nodes[i - 1].data)
            # 节点间空隙
            interval = 2 ** (layers - int(math.log2(i))) - 1
        # 打印底层
        print(branch.join(layer))
ls = [chr(i) for i in range(65, 91)]
fbt = FBT(ls)

打印结果

               A               
       B               C       
   D       E       F       G   
 H   I   J   K   L   M   N   O 
P Q R S T U V W X Y Z

2、递归法遍历

# 先序遍历
def preorder_traversal(node):
    print('%3s' % node, end='')
    if node.left:
        preorder_traversal(node.left)
    if node.right:
        preorder_traversal(node.right)
# 中序遍历
def inorder_traversal(node):
    if node.left:
        inorder_traversal(node.left)
    print('%3s' % node, end='')
    if node.right:
        inorder_traversal(node.right)
# 后序遍历
def postorder_traversal(node):
    if node.left:
        postorder_traversal(node.left)
    if node.right:
        postorder_traversal(node.right)
    print('%3s' % node, end='')
# traversal
print('\npreorder')
preorder_traversal(fbt.nodes[0])
print('\ninorder')
inorder_traversal(fbt.nodes[0])
print('\npostorder')
postorder_traversal(fbt.nodes[0])

打印结果

preorder
  A  B  D  H  P  Q  I  R  S  E  J  T  U  K  V  W  C  F  L  X  Y  M  Z  G  N  O
inorder
  P  H  Q  D  R  I  S  B  T  J  U  E  V  K  W  A  X  L  Y  F  Z  M  C  N  G  O
postorder
  P  Q  H  R  S  I  D  T  U  J  V  W  K  E  B  X  Y  L  Z  M  F  N  O  G  C  A

3、递归效率较低,可改用【栈】

# 先序遍历
def preorder_traversal(node):
    ls = []
    while True:
        # 节点不为空时
        while node:
            print('%3s' % node, end='')
            # 入栈
            ls.append(node)
            # 进入左节点
            node = node.left
        # 栈为空时退出
        if ls == []:
            break
        # 出栈
        node = ls.pop()
        # 进入右节点
        node = node.right
# 中序遍历
def inorder_traversal(node):
    ls = []
    while True:
        # 节点不为空时
        while node:
            # 入栈
            ls.append(node)
            # 进入左节点
            node = node.left
        # 栈为空时退出
        if ls == []:
            break
        # 出栈
        node = ls.pop()
        print('%3s' % node, end='')
        # 进入右节点
        node = node.right
# 后序遍历,难度较大,以后再补充
def postorder_traversal(node):
    pass
# traversal
ls = [chr(i) for i in range(65, 91)]
fbt = FBT(ls)
print('\npreorder')
preorder_traversal(fbt.nodes[0])
print('\ninorder')
inorder_traversal(fbt.nodes[0])

打印结果同上,不作重复

4、层序遍历

from collections import deque
# 层序遍历
def level_order(node):
    print('\nlevel order')
    # 根节点入队
    q = deque([node])
    # 先进先出
    while q:
        node = q.popleft()
        print('%3s' % node, end='')
        if node.left:
            q.append(node.left)
        if node.right:
            q.append(node.right)
# traversal
level_order(fbt.nodes[0])

打印结果

level order
  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z

5、探索树的深度

# 树深度,递归法
def depth(node):
    if node is None:
        return 0
    dl = depth(node.left)
    dr = depth(node.right)
    return max(dl, dr) + 1
# the depth of tree
print('the depth of tree:', depth(fbt.nodes[0]))

打印结果

the depth of tree: 5

6、遍历指定层

from collections import deque
# 层序遍历
def level_order(node, layer=2):
    print('\nlevel order')
    # 根节点入队
    q = deque([(node, 1)])
    # 先进先出
    while q:
        node, depth = q.popleft()
        if depth == layer:
            print('%3s' % node, end='')
        if node.left:
            q.append((node.left, depth + 1))
        if node.right:
            q.append((node.right, depth + 1))
# traversal
level_order(fbt.nodes[0], layer=5)

打印结果

level order
  P  Q  R  S  T  U  V  W  X  Y  Z
    原文作者:查找算法
    原文地址: https://blog.csdn.net/Yellow_python/article/details/80524455
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞