zoukankan      html  css  js  c++  java
  • 数据结构和算法

    一 数据结构:

    常见的数据结构:

    ① 数组
    ② 链表
    ③ 树
    ④ 图

    数据结构:

    个体 + 个体的关系

    数据结构和算法的定义:

    我们如何把现实中大量而且非常复杂的问题以特定的数据类型(个体)和特定的存储结构(个体的关系)保存到相应的主存储(内存)中。

    以及在此基础上为实现某个功能而执行的相应操作,这个相应的操作也叫作算法。

    1 、连续存储:数组、列表

    ① 数组:申请一块连续的内存空间

    优点:存取速度快。(因为连续的不需要再进行查找)

    缺点:插入和删除效率低。(如果你从中间插入一个数据,那么这条数据之后的都要往后移,所以相应的效率就比较低)

    2 、离散存储:链表(单向,双向,环形)

    ① 链表:可以不连续,那么链表如何实现存储?

    解决了我们数组的插入和删除效率低的问题。

    那么对于链表我们如何查询呢?

    遍历的时候会增加一个cur变量,开始的时候cur等于我们的头结点。

    那么从下图我们可以看出,数据之间通过在上一个存储空间存有指向下一个存储空间的地址的方式。

     3 、链表操作:

      ① 单向链表操作:

    查、增、改、删

    class Hero(object):
        def __init__(self, no=None, nickname=None, name=None, pNext = None):
            self.no = no
            self.nickname = nickname
            self.name = name
            self.pNext = pNext
    
    #### 添加节点
    def addHero(head, pNew):
        cur = head
        # while cur.pNext != None:
        #     cur = cur.pNext
        #
        # cur.pNext = pNew
    
        while cur.pNext != None:
            if cur.pNext.no > pNew.no:
                break
    
            cur = cur.pNext
    
        pNew.pNext = cur.pNext
        cur.pNext = pNew
    
        
    #### 遍历节点
    def showHero(head):
        if isEmpty(head):
            return None
    
        cur = head
    
        while cur.pNext != None:
            print("英雄的编号是: %s, 外号是:%s, 姓名:%s" % (cur.pNext.no, cur.pNext.nickname, cur.pNext.name))
            cur = cur.pNext
    ### 判断是否为空
    def isEmpty(head):
        if head.pNext != None:
            return False
        return True
    
    ## 删除节点
    def delHero(head, no):
        cur = head
        while cur.pNext != None:
            if cur.pNext.no == no:
                # 开始删除
                cur.pNext = cur.pNext.pNext
                break
            cur = cur.pNext
        else:
            print('没有找到好汉')
    
    ### 链表的长度
    def getLength(head):
        length = 0
        cur = head
        while cur.pNext != None:
            cur = cur.pNext
            length = length + 1
    
        return length
    
    ### 更新链表
    def updateHero(head, no, name):
        cur = head
        while cur.pNext != None:
            if cur.pNext.no == no:
                cur.pNext.name = name
                break
            cur = cur.pNext
        else:
            print('没有找到好汉')
    
    
    # 头结点
    head = Hero()
    
    ## 首节点
    h1 = Hero(1, '及时雨', '宋江')
    h2 = Hero(2, '玉麒麟', '卢俊义')
    h3 = Hero(6, '豹子头', '林冲')
    h4 = Hero(4, '入云龙', '公孙胜')
    h5 = Hero(5, '行者', '武松')
    
    addHero(head, h1)
    addHero(head, h2)
    addHero(head, h3)
    addHero(head, h4)
    addHero(head, h5)
    
    showHero(head)
    print(getLength(head))
    单向链表的查、增、改、删

     ② 双向链表:

    表中每个节点有两个指针:一个指向后面节点、一个指向前面节点

    双链表.jpg

    class Node(object):
    def __init__(self, data=None):
    self.data = data
    self.next = None
    self.prior = None

    插入:

    p.next = curNode.next
    curNode.next.prior = p
    curNode.next = p
    p.prior = curNode

    删除:

    p = curNode.next
    curNode.next = p.next
    p.next.prior = curNode
    del p

    双链表的操作.png

     ③ 环形链表

    循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

     ④ 约瑟夫问题 

    编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,
    由此产生一个出队编号的序列
    class Child(object):
        first = None
    
        def __init__(self, no=None, pNext=None):
            self.no = no
            self.pNext = pNext
    
        def addChild(self, n):
            cur = None
            for i in range(n):
                child = Child(i + 1)
    
                if i == 0:
                    self.first = child
                    child.pNext = self.first
                    cur = self.first
                else:
                    cur.pNext = child
                    child.pNext = self.first
                    cur = cur.pNext
    
        def showChild(self):
            cur = self.first
    
            while cur.pNext != self.first:
                print("当前孩子的编号是:%s" % cur.no)
                cur = cur.pNext
    
            print("当前孩子的编号是:%s" % cur.no)
    
        def countChild(self, m, k):
            tail = self.first
    
            while tail.pNext != self.first:
                tail = tail.pNext
    
            #### 当退出循环的时候,tail已经是在first的后面了
    
            for i in range(k - 1):
                tail = tail.pNext
                self.first = self.first.pNext
    
            while tail != self.first:
                for i in range(1):
                    tail = tail.pNext
                    self.first = self.first.pNext
    
                self.first = self.first.pNext
                tail.pNext = self.first
    
            print("最终剩下的孩子的编号是: %s" % self.first.no)
    
    
    c = Child()
    c.addChild(1000)
    c.showChild()
    c.countChild(3, 2)
    约瑟夫问题
  • 相关阅读:
    基于RSA securID的Radius二次验证java实现(PAP验证方式)
    一些指令 & 一些知识 (Linux Spring log4j...)
    RSA, ACS5.X 集成配置
    Python中的动态属性与描述符
    设计模式(一):单例模式
    JavaWeb
    动态规划_背包问题
    动态规划_最长上升子序列
    MySQL复习
    动态规划_数字三角形
  • 原文地址:https://www.cnblogs.com/zhangsanfeng/p/9581086.html
Copyright © 2011-2022 走看看