Datawhale|编程第6期-Test5

1、实现一个二叉查找树,并且支持插入、删除、查找操作、4种遍历

class Node():
    def __init__(self, data):
    	# 每个节点包含值、左子树、右子树
        self.data = data
        self.lchild = None
        self.rchild = None
 
class BST():
    def __init__(self, node_list):
    	# 以第一个数为根节点,剩下数插入到树中
        self.root = Node(node_list[0])
        for data in node_list[1:]:
            self.insert(data)
 
    # 搜索
    def search(self, node, parent, data):
        # 找到要插入或删除的根节点
        if node is None:
            return False, node, parent
        if node.data == data:
            return True, node, parent
        if node.data > data:
            return self.search(node.lchild, node, data)
        else:
            return self.search(node.rchild, node, data)
 
    # 插入
    def insert(self, data):
        flag, n, p = self.search(self.root, self.root, data)
        if not flag:
            # 值相同就不加
            new_node = Node(data)
            if data > p.data:
                p.rchild = new_node
            else:
                p.lchild = new_node
 
    # 删除
    def delete(self, root, data):
        flag, n, p = self.search(root, root, data)
        if flag is False:
            print("无该关键字,删除失败")
        else:
            if n.lchild is None:
                if n == p.lchild:
                    p.lchild = n.rchild
                else:
                    p.rchild = n.rchild
                del p
            elif n.rchild is None:
                if n == p.lchild:
                    p.lchild = n.lchild
                else:
                    p.rchild = n.lchild
                del p
            else:  # 左右子树均不为空
                pre = n.rchild
                if pre.lchild is None:
                    n.data = pre.data
                    n.rchild = pre.rchild
                    del pre
                else:
                    next = pre.lchild
                    while next.lchild is not None:
                        pre = next
                        next = next.lchild
                    n.data = next.data
                    pre.lchild = next.rchild
                    del p
 
 
    # 先序遍历
    def preOrderTraverse(self, node):
        if node is not None:
            print(node.data)
            self.preOrderTraverse(node.lchild)
            self.preOrderTraverse(node.rchild)
 
    # 中序遍历
    def inOrderTraverse(self, node):
        if node is not None:
            self.inOrderTraverse(node.lchild)
            print(node.data)
            self.inOrderTraverse(node.rchild)

 
    # 后序遍历
    def postOrderTraverse(self, node):
        if node is not None:
            self.postOrderTraverse(node.lchild)
            self.postOrderTraverse(node.rchild)
            print(node.data)
    # 前驱和后继
    def find_for_and_back(self,node,data):
    	#利用中序遍历找到前驱和后继
        list1 = self.inOrderTraverse(node)
        for i in range(len(list1)):
        	if list1[i] == data:
        		return list1[i-1],list1[i+1]
    # 层序遍历
    def PrintFromTopToBottom(self, root):
        if not root:
            return []
        currentStack = [root]
        outList = np.zeros((10,10))
        i = 0
        while currentStack:
            nextStack = []
            j = 0
            for point in currentStack:
                if point.lchild: 
                    nextStack.append(point.lchild)
                if point.rchild: 
                    nextStack.append(point.rchild)
                # outList.append(point.data)
                outList[i][j] = point.data
                j+=1
            currentStack = nextStack
            i+=1
        return outList
 

if __name__ == '__main__': 	
	a = [49, 38, 65, 97, 60, 76, 13, 27, 5, 1]
	bst = BST(a)   
	print("begin")                               # 创建二叉查找树
	bst.inOrderTraverse(bst.root)                # 中序遍历
	print("end")
	print(bst.find_for_and_back(bst.root,60))    # (49,65)
	outList = bst.PrintFromTopToBottom(bst.root)
	print(outList)                               # 输出一个10*10的矩阵,每一行代表一层
	print(bst.delete(bst.root, 49))              # 删除根节点 
	bst.inOrderTraverse(bst.root)

2、实现一个小顶堆、大顶堆、优先级队列

最大堆

class MaxHeap(object):
 
    def __init__(self):
        self._data = []
        self._count = len(self._data)
 
    def size(self):
        return self._count
 
    def isEmpty(self):
        return self._count == 0
 
    def add(self, item):
        # 插入元素入堆
        self._data.append(item)
        self._count += 1
        self._shiftup(self._count-1)
 
    def pop(self):
        # 出堆
        if self._count > 0:
            ret = self._data[0]
            self._data[0] = self._data[self._count-1]
            self._count -= 1
            self._shiftDown(0)
            return ret
        
    def _shiftup(self, index):
        # 上移self._data[index],以使它不大于父节点
        # (index - 1 )//2
        parent = (index-1)>>1
        print(index,parent)
        while index > 0 and self._data[parent] < self._data[index]:
            # swap
            self._data[parent], self._data[index] = self._data[index], self._data[parent]
            index = parent
            parent = (index-1)>>1

 
    def _shiftDown(self, index):
        # 上移self._data[index],以使它不小于子节点
        # index*2 + 1
        j = (index << 1) + 1
        while j < self._count :
            # 有子节点
            if j+1 < self._count and self._data[j+1] > self._data[j]:
                # 有右子节点,并且右子节点较大
                j += 1
            if self._data[index] >= self._data[j]:
                # 堆的索引位置已经大于两个子节点,不需要交换了
                break
            self._data[index], self._data[j] = self._data[j], self._data[index]
            index = j
            j = (index << 1) + 1
    def merge(self,*list1):   #动态合并K个数组
    	for item in list1:
    		for i in item:
    			self.add(i)


oMaxHeap = MaxHeap()
allData = [1, 4, 3, 2, 5, 7, 6]
for i in allData:
    oMaxHeap.add(i)
print('oMaxHeap.size:', oMaxHeap.size())
print(oMaxHeap._data)
oMaxHeap.merge([9,3,1],[10,34,5])
print(oMaxHeap._data)
while oMaxHeap.size()>0:
    print('pop:', oMaxHeap.pop())

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值