顺序表与链表

内存

  • 计算机的作用

    • 存储和运算二进制数据
  • 计算机如何实现1+1=?的操作

    • 将1加载到内存中,然后基于计算机的加法寄存器对指定内存中存储的数据进行加法运算。
  • 变量

    • 本质讲,变量指的就是计算机中的某一块内存空间
    • 内存空间有两个固有属性
      • 地址
        • 使用16进制数表示
        • 作用:方便cpu寻址(门牌号)
      • 大小
        • bit,byte,kb,mb,gb,tb
        • 决定该块内存存储的数值的范围
        • 相同类型的数据,开辟固有大小的内存空间
          • 整形数据:4byte
          • 浮点型:4byte(单精度),8byte(双精度)
          • 字符型:1byte
  • 引用和指向

    • 引用:就是变量。通常讲,变量表示的就是一块内存空间的地址。
    • 指向:如果一个变量或引用存储和表示了一块内存空间的地址,则该变量或引用指向了该块内存空间。

 顺序表

  • 概念

    • 将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
  • 顺序表的结构可以分为两种形式:

    • 单数据类型(如数组)
      • 数据元素本身连续存储,每个元素所占的存储单元大小固定相同,元素的下标是其逻辑地址,而元素存储的物理地址(实际内存地址)可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)与存储单元大小(c)的乘积计算而得,即:Loc(ei) = Loc(e0) + c*i
      • 故,访问指定元素时无需从头遍历,通过计算便可获得对应地址,其时间复杂度为O(1)。
    • 多数据类型(如元组和列表)
      • 元素的大小不统一,则需要采用元素外置的形式,将实际数据元素另行存储,而顺序表中各单元位置保存对应元素的地址信息(即链接)。由于每个链接所需的存储量相同,这个量通常很小,顺着链接找到实际存储的数据元素
      • 这样的顺序表也被称为对实际数据的索引,这是最简单的索引结构。
  • 弊端

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

链表

  • 定义

    • 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)
  • 优点

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

    • 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
  • 单链表操作

    • is_empty() :链表是否为空
    • length() :链表长度
    • travel() :遍历整个链表
    • add(item) :链表头部添加元素
    • append(item) :链表尾部添加元素
    • insert(pos, item) :指定位置添加元素
    • remove(item) :删除节点
    • search(item) :查找节点是否存在
  • 单链表实现:

    # coding:utf-8
    
    class Node:
        '''单链表的节点'''
        def __init__(self,item):
            self.item = item
            self.next = None
    
    class Link_list:
        def __init__(self):
            self._head = None
    
        def is_empty(self):
            '''判空'''
            return self._head == None
    
        def add(self,item):
            '''头部添加'''
            node = Node(item)
            node.next = self._head
            self._head = node
    
        def append(self,item):
            '''尾部添加'''
            node = Node(item)
            #先判空,若为空链表,则_head指向新节点
            if self.is_empty():
                self._head = node
            #不为空,则找到尾节点,然后尾节点的next指向新节点
            else:
                cur = self._head
                while cur.next:
                    cur = cur.next
                cur.next = node
    
        def length(self):
            '''链表长度'''
            if self.is_empty():
                return 0
            count = 1
            cur = self._head
            while cur.next:
                count += 1
                cur = cur.next
            return count
    
        def travel(self):
            '''遍历'''
            cur = self._head
            while cur:
                print(cur.item)
                cur = cur.next
    
        def search(self,item):
            '''查找节点是否存在'''
            cur = self._head
            while cur:
                if cur.item == item:
                    return True
                cur = cur.next
            return False
    
        def insert(self,pos,item):
            '''指定位置插入节点'''
            node = Node(item)
            #判断插入位置,如果为0,则从头部插入
            if pos == 0:
                self.add(node)
                return
            #其它位置,需要找到插入点前面一个节点pre和后面一个节点cur
            pre = None
            cur = self._head
            for i in range(pos):
                pre = cur
                cur = cur.next
            pre.next = node
            node.next = cur
    
        def remove(self,item):
            '''删除节点'''
            pre = None
            cur = self._head
            while cur:
                if cur.item == item:
                    if not pre:
                        self._head = cur.next
                    else:
                        pre.next = cur.next
                    break
                pre = cur
                cur = cur.next
    
    if __name__ == '__main__':
        link = Link_list()
        print(link.is_empty())
        link.add(1)
        print(link.is_empty())
        link.add(2)
        link.append(3)
        link.insert(1,2.5)
        print(link.search(4))
        link.travel()
  • 实现单链表倒置

    def reverse(self):
        '''链表倒置'''
        pre = None #前一个节点
        cur = self._head #当前节点
        post = cur.next #后一个节点
        while post:
            #每循环一次,就修改当前节点的next指向前一个节点,然后每个节点后移一位
            #循环退出时,cur指向最后一个节点
            cur.next = pre
            pre = cur
            cur = post
            post = post.next
        #修改最后一个节点next指向前一个节点
        cur.next = pre
        #修改_head指向最后一个节点
        self._head = cur

     

 

posted @ 2021-08-19 18:20  eliwang  阅读(58)  评论(0编辑  收藏  举报