zoukankan      html  css  js  c++  java
  • 单链表,双向链表,循环链表

    数据结构:
        
        定义:
            特定的数据类型(个体)和特定的存储结构(个体的关系)
            数据如何存储在内存中
        分类:
            
            线性结构:
            数据元素之间存在一对一的线性关系。线性结构拥有两种不同的存储结构,即顺序存储结构和链式存储结构。
            
                数组与列表:顺序存储结构
                    
                    相同点:
                        需要申请一块连续的内存空间
    
                    不同点:
                        列表或者数组中的元素是如何存储的,以及两者的区别?
                            在其他语言中(C/C++)数组申请的内存空间是一定的, 比如申请10M的内存空间,如果数据超过10M会溢出,需要手动申请和释放
                            在python中不会出现溢出报错这种问题,底层做了处理会自动扩展,不需要手动申请和释放
                            
                            python:                            
                                li = [1,2,3,4,54,56,56,67,77]
                            C/C++:
                                malloc()         申请                
                                free()            释放
                            
                        列表提供了哪些最基本的操作?
                            append(), insert(), pop()等
                         
                        这些操作的时间复杂度是多少?
                            插入时间复杂度:O(n)   因为数组是连续存放的,后面的数据会后移
                            查找时间复杂度: O(1)      按照索引运算查找即可
                            
                        为啥数组(列表)的索引或者下标是从0开始?
                            减少运算的压力 查找内存位置的时候直接按照索引算即可,如果从1开始还要减一
                        
                    关于数组(列表)的优缺点:
                        优点:
                            查找快
                        
                        缺点:
                            插入慢
                            要求一块 连续 的内存空间 ***
                
                    
                链表:链式存储结构
                    插入时间复杂度:O(1)        
                    查找时间复杂度: O(n)
                    
                    链表的优点:
                        1、不需要一块连续内存空间
                        2、相对于数组来说,插入较简单
                    
                    单链表
                    双链表
                    循环链表 约瑟夫问题
                    
                    链表算法:增删改查以及总长度
                
                应用:
                    栈
                    
                    队列
                
                
            非线性结构: 
                树作为一种应用广泛的一对多非线性数据结构,不仅有数据间的指向关系,还有层级关系
                如何在内存中表示呢?
                
                树                
                
                图
                    图论
    介绍
    ###########################
    # 单链表:水浒英雄排序
    # 双向链表多一个pre
    
    class Hero:
        def __init__(self,name=None,no=None,nickname=None,pNext=None):
            self.name = name
            self.no = no
            self.nickname = nickname
            self.pNext = pNext
    
    # 直接添加到尾部
    def add(head,pnew):
        cur = head
        while cur.pNext != None:
            cur = cur.pNext
        cur.pNext = pnew
    
    # 指定位置进行添加
    def insert(head,pnew):
        cur = head
        while cur.pNext != None:
            if cur.pNext.no > pnew.no:
                break
            cur = cur.pNext
        pnew.pNext = cur.pNext
        cur.pNext = pnew
    
    # 根据no删除某个节点(英雄)
    def delHero(head,no):
        cur = head
        while cur.pNext != None:
            if cur.pNext.no == no:
                break
            cur = cur.pNext
        else:
            print("没有此元素")
        cur.pNext = cur.pNext.pNext
    
    # 查看单链表是否为空
    def is_empty(head):
        if head.pNext == None:
            return True
        else:
            return False
    
    # 计算单链表长度
    def length(head):
        cnt = 0
        cur = head
        while cur.pNext != None:
            cur = cur.pNext
            cnt += 1
        return cnt
    
    # 打印所有的单链表数据
    def getAll(head):
        cur = head
        while cur.pNext != None:
            cur = cur.pNext
            print('编号是:%s,姓名是:%s,外号:%s' %(cur.no,cur.name,cur.nickname))
    
    head = Hero()
    
    h1 = Hero('宋江',1,'及时雨')
    add(head,h1)
    
    h2 = Hero('卢俊义',2,'玉麒麟')
    add(head,h2)
    
    h3 = Hero('吴用',3,'智多星')
    add(head,h3)
    
    h4 = Hero('马波',5,'波神')
    add(head,h4)
    
    h5 = Hero('波老师',4,'波波')
    add(head,h5)
    
    print(length(head))
    getAll(head)
    ###########################
    单链表
    ###########################
    # 循环链表:解决约瑟夫问题
    # 设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,
    # 数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列
    
    class Child:
        first = None
        def __init__(self,data = None,pNext = None):
            self.data = data
            self.pNext = pNext
    # 生成n个小朋友,构成循环链表
        def add(self,num):
            cur = None
            for i in range(num):
                child = Child(i+1)
                if i == 0: # 当i=0时,构成一个循环链表,指向自己,目的是:后面的好加入
                    self.first = child #first指向第一个孩子对象
                    self.first.pNext = self.first #第一个孩子的指针指向自己构成循环链表
                    cur = self.first
                else:
                    cur.pNext = child
                    child.pNext = self.first
                    cur = cur.pNext
    # 展示所有的小孩
        def showAll(self):
            cur = self.first #第一个孩子节点
            while cur.pNext != self.first: #只有末尾的节点指针指向第一个节点
                print('小孩的编号是:%s' %cur.data)
                cur=cur.pNext
            print('小孩的编号是:%s' %cur.data) #打印末尾节点的编号
    
    # 解决约瑟夫问题
        def countChild(self,m,k):
            tail = self.first #第一个孩子节点,
    
            while tail.pNext != self.first: #除了最后一个节点外,都是True
                tail = tail.pNext
            # 退出循环的话,已经到了最后一个小朋友,就在first后面
    
            # tail是用来出列之后修复循环链表,永远在first后面,执行完上面的代码就在first后面了
    
            # 从哪里开始数,first移动到报数位置,tail在first后面
            for i in range(k-1):
                self.first = self.first.pNext
                tail = tail.pNext
    
            while tail != self.first: # 退出循环的时候,圈子里面只剩一个人
                # 数2下,first、tail前移1下
                # 数3下,first、tail前移2下
                # 数m下,first、tail前移m-1下
                for i in range(m - 1):
                    self.first = self.first.pNext
                    tail = tail.pNext
                # 修复循环链表
                self.first = self.first.pNext
                tail.pNext = self.first
            print('留在圈子里面的小孩编号:%s' %tail.data)
    
    child = Child() #生成对象
    child.add(1000)  #添加100个小孩
    # child.showAll() #打印100个小孩的编号
    child.countChild(1000,300) #从编号为3的人开始,数到80的人出列
    ###########################
    循环链表
  • 相关阅读:
    五、Java对象和类
    四、JavaString字符串
    三、Java语句
    二、Java基本数据类型
    一、Java主类结构
    bat常用命令
    iOS 如何获得app的版本和系统的版本
    英语----时态---将来时态的四种对比
    英语----时态---将来时态的
    英语----时态---现在进行时与过去进行时
  • 原文地址:https://www.cnblogs.com/xujinjin18/p/9972746.html
Copyright © 2011-2022 走看看