zoukankan      html  css  js  c++  java
  • python数据结构基础(单链表,多链表,二叉树,栈,队列)

    python数据结构基础(单链表,多链表,二叉树)

    数据结构指数据对象中数据元素之间的关系

    Python 给我们提供了很多现成的数据结构类型,这些系统自己定义好的,不需要我们自己去定义的数据结构叫做 Python 的内置数据结构,比如列表、元组、字典。而有些数据组织方式,Python 系统里面没有直接定义,需要我们自己去定义实现这些数据的组织方式,这些数据组织方式称之为 Python 的扩展数据结构,比如栈,队列等.

    线性表:一组序列元素的组织形式,我们可以将其抽象为线性表。一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。线性表是最基本的数据结构之一。

    根据线性表的实际存储方式,分为两种实现模型:顺序表和链表。Python 中的 list 和 tuple 两种类型采用了顺序表的实现技术。

    顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活

    链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理,常见的有单向链表和双向链表。

    在 Python 的官方实现中,list 实现采用了如下的策略:在建立空表(或者很小的表)时,系统分配一块能容纳 8 个元素的存储区;在执行插入操作(insert 或 append)时,如果元素存储区满就换一块 4 倍大的存储区。但如果此时的表已经很大(目前的阀值为 50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。

    单链表:


    class Node():
       '''单链表节点类'''
       def __init__(self,elem):
           self.elem = elem
           self.next = None

    class SLink():
       def __init__(self,node=None):
           if node is None:
               self.__head = node
           else:
               self.__head = Node(node)

       def is_empty(self):
           return self.__head==None

       def length(self):
           count = 0
           curNode = self.__head
           while curNode != None:
               count+=1
               # self.__head = curNode.next
               curNode = curNode.next
           return count
       #遍历
       def travel(self):
           curNode = self.__head
           while curNode !=None:
               print(curNode.elem,end=' ')
               curNode= curNode.next
           print()

       #查找
       def find(self,item):
           node = Node(item)
           curNode = self.__head
           while curNode !=None:
               if curNode.elem == node.elem:
                   return True
               self.__head = curNode.next
               curNode = curNode.next
           return False


       #头部添加
       def add(self,item):
           node = Node(item)
           if self.__head == None:
               self.__head=node
           else:
               curNode = self.__head
               self.__head = node
               node.next = curNode
       #尾部插入
       def append(self,item):
           node = Node(item)
           if self.__head == None:
               self.__head = node
           else:
               curNode = self.__head
               while curNode.next is not None:
                   curNode = curNode.next
               curNode.next = node

       #指定位置插入
       def insert(self,num,item):
           node = Node(item)
           if self.__head ==None:
               self.__head = node
           else:
               if num>self.length():
                   self.append(item)
                   return
               if num<=0:
                   self.add(item)
                   return
               curNode = self.__head
               count = 1
               p = None
               while curNode is not None:
                   if count == num:
                       node.next = curNode
                       p.next = node
                       break
                   count+=1
                   p=curNode
                   curNode = curNode.next
       #删除节点
       def delete(self,item):
           curNode = self.__head
           preNode = None
           while curNode is not None:
               if curNode.elem == item:
                   #判断是不是头
                   if preNode == None:
                       self.__head = curNode.next
                   else:
                       preNode.next = curNode.next
                   return
               else:
                   preNode = curNode
                   curNode = curNode.next




    if __name__ == '__main__':
       a = SLink(10)
       print(a.is_empty())
       print(a.length())
       print(a.find(101))
       a.add(1)
       a.add(2)
       a.add(3)
       a.add(4)
       a.append(5)
       a.append(6)
       a.append(7)
       a.append(8)
       a.travel()
       a.insert(0,7)
       a.insert(100, 7)
       a.insert(4,100)
       a.travel()
       a.delete(100)
       a.travel()

    双链表


    class Node():
       def __init__(self,elem=None):
           self.elem = elem
           self.pre = None
           self.next = None

    class Dlink():
       def __init__(self,elem=None):
           if elem == None:
               self.__head = None
           else:
               self.__head = Node(elem)

       def length(self):
           count = 0
           curNode = self.__head
           while curNode is not None:
               count += 1
               curNode = curNode.next
           return count

       def is_empty(self):

           return self.__head == None

       def travel(self):
           if self.is_empty():
               return None
           curNode = self.__head
           while curNode != None:
               print(curNode.elem,end=' ')
               curNode = curNode.next
           print()

       #头部添加
       def add(self,item):
           node = Node(item)
           if self.is_empty():
               self.__head=node
           else:
               curNode = self.__head
               curNode.pre= node
               node.next = curNode
               self.__head= node

       #尾部添加
       def append(self,item):
           node = Node(item)
           if self.is_empty():
               self.__head=node
           else:
               curNode = self.__head
               while curNode.next is not None:
                   curNode = curNode.next
               curNode.next = node
               node.pre = curNode
       #制定位置插入
       def insert(self,num,item):
           if num <= 0:
               self.add(item)
           elif num > self.length()-1:
               self.append(item)
           else:
               node = Node(item)
               curNode = self.__head
               count = 0
               while count < num-1:
                   count += 1
                   curNode = curNode.next
               #这里需要注意顺序,指向会变得
               node.pre = curNode
               node.next = curNode.next
               curNode.next.pre = node
               curNode.next = node


       def delete(self, item):
           '''删除节点'''
           curNode = self.__head
           while curNode is not None:
               if curNode.elem == item:
                   if curNode == self.__head:
                       self.__head = curNode.next
                       if curNode.next:
                           curNode.next.pre = None
                   else:
                       curNode.pre.next = curNode.next
                       if curNode.next:
                           curNode.next.pre = curNode.pre
                   break
               else:
                   curNode = curNode.next




    if __name__ == '__main__':
       b = Dlink(10)
       # print(b.length())
       b.add(1)
       b.add(2)
       b.add(3)
       b.add(4)
       b.travel()
       b.delete(3)
       b.travel()
       b.append(11)
       b.append(22)
       b.append(33)
       b.append(44)
       b.travel()
       b.insert(0,100)
       # b.travel()
       b.insert(1, 200)
       b.insert(100,300)
       b.travel()
       #删除节点
       print('删除节点1')
       b.delete(1)
       b.travel()
       print('删除节点200')
       b.delete(200)
       b.travel()
       print('删除节点4')
       b.delete(4)
       b.travel()

    栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,确定了一种默认的访问顺序。 由于栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

    队列

    队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。 队列是一种先进先出的(First In First Out)的线性表,简称 FIFO。允许插入的一端为队尾,允许删除的一端为队头。队列不允许在中间部位进行操作.



    class Stack():
       '''栈的实现后进先出'''
       def __init__(self,):
           self.__list = []
       
       #压栈
       def push(self,item):
           self.__list.append(item)
           
       #弹出元素  
       def pop(self,item):    
           return self.__list.pop()
       
       #返回栈顶元素
       def peek(self):
           return self.__list[len(self.__list)-1]
       
       #返回栈的大小
       def size(self):
           return len(self.__list)
       
       def is_empty(self):
           return self.__list==[]
           
           
           
    class Queue():
       '''队列的实现先进先出'''

       def __init__(self):
           self.__list=[]
           
       def push(self,item):
           self.__list.insert(0,item)
           #self.list.append(item)

       def pop(self):
           return self.__list.pop()
           #return self.__list.pop(0)

       def is_empty(self):
           return self.__list==[]
           
       def size(self):
           return len(self.__list)

    树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由 n(n>=1)个有限节点组成一个具有层次关系的集合

    树的术语:

    (1) 节点的度:一个节点含有的子树的个数称为该节点的度; (2) 树的度:一棵树中,最大的节点的度称为树的度; (3) 叶节点或终端节点:度为零的节点; (4) 父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; (5) 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; (6) 兄弟节点:具有相同父节点的节点互称为兄弟节点; (7) 节点的层次:从根开始定义起,根为第 1 层,根的子节点为第 2 层,以此类推; (8) 树的高度或深度:树中节点的最大层次; (9) 堂兄弟节点:父节点在同一层的节点互为堂兄弟; (10)节点的祖先:从根到该节点所经分支上的所有节点; (11)子孙:以某节点为根的子树中任一节点都称为该节点的子孙。 (12)森林:由 m(m>=0)棵互不相交的树的集合称为森林;

    树的种类
    • 无序树: :树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;

    • 有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;

      • 二叉树:每个节点最多含有两个子树的树称为二叉树;

        • 完全二叉树:对于一颗二叉树,假设其深度为 d(d>1)。除了第 d 层外,其它各层的节点数目均已达最大值,且第 d 层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树,其中 满二 叉树的定义是所有叶节点都在最底层的完全二叉树;

        • 平衡二叉树(AVL 树):当且仅当任何节点的两棵子树的高度差不大于 1 的二叉树;

        • 排序二叉树(二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树);

        • 霍夫曼树(用于信息编码):带权路径最短的二叉树称为哈夫曼树或最优二叉树;

        • B 树 :一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多余两个子树;

          mysql数据库的索引方式之一(还有一种是hash);

    二叉树:

    性质 1: 在二叉树的第 i 层上至多有 2^(i-1)个节点(i>0) 性质 2: 深度为 k 的二叉树至多有 2^k - 1 个节点(k>0) 性质 3: 对于任意一棵二叉树,如果其叶节点数为 N0,而度数为 2 的结点总数为 N2,则 N0=N2+1; 性质 4:具有 n 个节点的完全二叉树的深度必为 log2(n+1) 性质 5:对完全二叉树,若从上至下、从左至右编号,则编号为 i 的结点,其左孩子编号必为 2i,其右孩子号必为 2i+1;其双亲的编号必为 i/2(i=1 时为根,除外)

    (1)完全二叉树——若设二叉树的高度为 h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

    (2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。

    二叉树的节点及树的创建


    #树结构

    class Node():
       '''二叉树的节点类'''
       def __init__(self,elem):
           self.elem = elem
           self.lchild = None
           self.rchild = None


    #广度遍历,层次遍历 A,B,C,D,E,F,...
    #判断A 的左节点,右节点
    #判断b 的左节点,右节点
    #...
    class Tree():
       def __init__(self):
           self.root = None
           
       def add(self,elem):
           node = Node(elem)
           #判断根节点是否存在
           if self.root == None:
               self.root =node
           else:
               queue = [self.root]
               while queue:
                   curNode = queue.pop(0)
                   if curNode.lchild==None:
                       curNode.lchild=node
                       return
                   else:
                       queue.append(curNode.lchild)
                       
                   if curNode.rchild==None:
                       curNode.rchild=node
                       return
                   else:
                       queue.append(curNode.rchild)
       #广度优先遍历
       def travel(self):
           queue = []
           #判断root节点是否存在
           if self.root is None:
               return
           else:
               queue.append(self.root)
           while queue:
               curNode = queue.pop(0)
               print(curNode.elem,end=' ')
               if curNode.lchild is not None:
                   queue.append(curNode.lchild)
               if curNode.rchild is not None:
                   queue.append(curNode.rchild)
           print()
       #深度优先遍历
       #先序遍历 根 左 右
       def preOrder(self,root):
           if root is None:
               return
           else:
               print(root.elem,end=' ')
               self.preOrder(root.lchild)
               self.preOrder(root.rchild)
       #中序遍历 左 根 右
       def inOrder(self,root):
           if root is None:
               return
           else:
               self.inOrder(root.lchild)
               print(root.elem,end=' ')
               self.inOrder(root.rchild)
       #后续遍历 左 右 根
       def nextOrder(self,root):
           if root is None:
               return
           else:
               self.nextOrder(root.lchild)
               self.nextOrder(root.rchild)
               print(root.elem,end=' ')

    if __name__=='__main__':
       tree = Tree()
       tree.add(0)
       tree.add(1)
       tree.add(2)
       tree.add(3)
       tree.add(4)
       tree.add(5)
       tree.add(6)
       tree.add(7)
       tree.add(8)
       tree.add(9)
       print('广度优先')
       tree.travel()
       print('先序')
       tree.preOrder(tree.root)
       print()
       print('中序')
       tree.inOrder(tree.root)
       print()
       print('后序')
       tree.nextOrder(tree.root)

     

  • 相关阅读:
    后台数值往前台传值,能获取到值,页面显示不出来的问题
    总结jquery中对select和option的基本操作
    使用<input type="image" src="...">标签会引发页面刷新的问题
    用java来实现验证码功能。
    用java来实现验证码功能(本帖为转载贴),作为个人学习收藏用
    使用java实现发送邮件的功能
    java中的中文参数存到数据库乱码问题
    模糊查询时,页面没有数据,数据库编辑器里可以正常显示数据
    c# 无法加载 DLL xxxxxxxx找不到指定的模块。 (异常来自HRESULT:0x8007007E)。的一个解决方法
    关于C#调用C++ 的DLL传送字符串显示乱码的解决
  • 原文地址:https://www.cnblogs.com/robot-python/p/11843187.html
Copyright © 2011-2022 走看看