数据结构(从basic --> common 的旅程)

我们有的basic:① 基本数据类型:int,float,str,bool  (python 多装了 list,tuple, set, dict ,且str 也与C++ 中不同,但大作用上无差别)

②三种控制流语句(顺序,多条件分支,迭代) #组织语句作用,本身并不实施处理(:计算和存储)

③赋值语句:求一个表达式的值(计算)并赋给一个变量(存储)

④ 自定义 class 和  function

复杂度:

存储空间来衡量空间复杂度的难点:问题本身描述(自身数据规模) +算法占用

算法运行速度 ≠ 时间复杂性

算法运行速度还与数据规模、运行环境、使用的程序语言等因素有关

ADT(抽象资料类型):利用基本组件,构建的特定类别的资料组装结构(数学模型)

        接口:函数名,参数,return值


stack:mystack.push(item),mystack.pop() ,mystack.peek()

queue:

双头:


链构成的列表:

1.UnorderedList:

class UnorderedList:
    '''
    无序链表插入和删除速度快,保留原有的物理顺序,更符合日常离散的需要

    '''

    def __init__(self):
        self.head =None#head是指地址

    def add(self,item):
       '''add 是加在开头'''
       temp =Node(item)
       temp.setNext(self.head)#原来的头(地址)现在是第二个
       self.head =temp

    def size(self):
        '''从链条头head开始遍历到表尾同时用变量累加经过的节点个数。 复杂度O(n)'''
        current = self.head
        count = 0
        while current != None:
            count = count +1
            current = current.getNext()

        return count

    def search(self,item):
        '''O(n)'''
        current =self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found = True
            else:
                current =current.getNext()
        return found

    def remove(self,item):
        '''because we are a single list'''
        current =self.head
        previous = None
        found = False
        while  not found:
            if current.getData() == item:
                found = True
            else:
                previous =current
                current = current.getNext()

        if previous == None:
            self.head =current.getNext()
        else:
            previous.setNext(current.getNext())

class Node:
    '''
    这是链表的基准:节点
    '''
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self,newdata):
        self.data =newdata

    def setNext(self,newnext):
        self.next = newnext
    

查找:比较对比次数


  • 无序表的 sequentialSearch function(alist,item)
  • 有序表的 binarySearch function(alist,item)
  • 散列 (hashtable): hashfunction 求余数, rehash 防冲突
    • 但散列不能因为构造它(存储)而太耗时间,所以根据不同的数据类型,有不同的求余数前的准备活动
    • 应对冲突主要是:开放定址--需要大量的空间资源 和 链法
0.先验知识:
    无序表:O(n) 找到item ,avg:n/2, wrong: n, best:1
                找不到item , n
    有序表:O(logn) # finding or not finding 
           but + 排序的开销

    散列: 1.size(决定槽数) 2.slot--存key值。 3.为了防止rehash , 可以用开放定址 or 链来存储


1.选择原则: 
    有序表or无序表:如果一次排序后可以进行多次查找,那么排序的开销就可以摊薄。但如果数据集经常变动,查找次数相对较少,那么可能还是直接用无序表加上顺序查找更快
    hash:如果散列函数设计太过复杂,去花费大量的计算资源计算槽号(还不如简单地进行顺序查找或者二分查找)。
    散列函数不能成为存储过程和查找过程的计算负担


2.代码

def sequentialSearch(alist, item):
    """
    无序表的顺序查找法
    O(n)  找到:avg:n/2 ,wrong:n  , 找不到:n
    :param alist:
    :param item:
    :return: bool found
    """
    pos = 0
    found = False

    while pos <len(alist) and not found:
        if alist[pos] == item: #值相等
            found = True
        else:
            pos +=1

    return found



def binarySearch(alist,item):#递归版本

    if len(alist) == 0: #这里不用1是因为最后剩偶数列
        return False
  
    midpoint = len(alist)//2
    if alist[midpoint] == item:
        return True
    else:
        if alist[midpoint] < item:
            binarySearch(alist[0:midpoint], item)  # midpoint 不用包含
        else:  # 再右半个区间
            binarySearch(alist[midpoint + 1::], item)




class Node:
    """
    这是链表的基准:节点
    """

    def __init__(self, initdata=None):  
        self.data = initdata
        self.next = None


class HashtableNode:  
    """
    核心板块:取余数(各种hashfunciton,rehash....因为是链所以之后有空在补吧)
    size:素数
    因为本章用的是链所以负载因子....后面有空完善这章时再补吧。 
    

    """


    def __init__(self, size=None):  # 这里size 如果怕忘了设成个默认值素数也是可以的。
        # 创建空列表作为哈希表,列表每个元素都是node类型
        self.size = size
        self.slots = [Node()] * size  

     
    def hash_function(self, key):
        return key % self.size
    
    def hash_function_folding(self, tell_num):
        """针对手机号,ID Card 这种
        默认(input:数字)是直接当做key 
        """


        key = list(map(int, str(tell_num)))
        temp = [sum(key[0:3]), sum(key[3:7]), sum(key[7:11])]  # list[]切片 取左不取右
        newkey = sum(temp)
        # self.hash_function(self, newkey)
        return newkey % self.size

    
    def hash_function_str(self,astring):  # 针对字符串
        sum =0
        for pos in range(len(astring)):
            sum = sum + ord(astring[pos])

        return sum % self.size
    
    def hashfunction_flx(astring, tablesize):  # 针对回文词
        total = 0
        for pos in range(len(astring)):
            total = total + ord(astring[pos]) * (pos + 1)  # pos+1 权重因子 因pos 从0开始取

        return total % tablesize
    

  
    def put(self, key):
        """
        如果slot 1 还没有就直接做链条头,
        如果有找到下个空位扔进去 
        """
        
        hash_value = self.hash_function(key)  # 先求余数 
        
        if self.slots[hash_value].data is None: #这里Node of size=3 的起点为none的话
            self.slots[hash_value].data = key   #余数3 的第一个数为 (key =36:tiger)
        # 如果已被占据,就在以【哈希表中下标为哈希值的位置 size=3】为起点的链表中顺次检查,直到检查到空位置
        else:
           
            temp = Node(key) #  (key =14:dog)
            p = self.slots[hash_value]
            # 向后逐个检查
            while p.next is not None:  #  slot 3号槽的链 ,36,47,25
                p = p.next  
                # p=36,true ,p=47,true, p=25 false ,不执行了 ,p.next 现在是接着25的none
            
            p.next = temp

   
    def get(self, key):

        hash_value = self.hash_function(key) #把36翻译成 size = 3, 看slot 3 的Node中有没有36
       
        if self.slots[hash_value].data == key: #先看链的起点是不是,不是顺着链爬一遍
            return True
        else:
            p = self.slots[hash_value]  # p存储链表头,爬链吧
            while p is not None and p.data is not key:
                p = p.next
            # 退出了上方循环后,还没有到链表的末尾,说明已找到
            if p != None and p.data == key:
                return True
        # 整个链表都未找到,说明整个哈希表里没有存储key的节点
        return False

排序:比较交换次数


  • 冒泡、搜索
  • 插入、谢尔
  • (递归)归并,快速
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值