zoukankan      html  css  js  c++  java
  • 数据结构 链表

    一、单向循环链表

    1、链表是一种数据结构,链表的基本组成单元是节点(Node)。节点(Node)包含了:节点数据(val/element)、后一个节点的引用(next)、前一个节点的引用(pre)

    2、链表在内存中存储空间是不连续的,每一个节点都包含后一个节点的引用(next)和前一个节点的引用(pre),通过next和pre可以获取在不连续空间存储的节点

    3、时间复杂度分析:一、添加和删除的操作:链表的时间复杂度则变成了O(1);二、遍历查找需要的数据::链表的时间复杂度则变成了O(n)

    4、链表还是很多算法中有运用,哈希表就是基于链表来解决哈希冲突

    5、链表实现:初始化(__init__)、元素的插入和删除(add、append、insert、remove)、链表的遍历(travel)、获取链表长度(length)、元素的查询(search)、链表的逆序、判断链表是否有环(链表是否有环:链表不存在一个结点的next指针是 null-hash表set.add(head)存储节点的引用和快慢指针)

    6、while判断,head是否为none,适用于head=head.next;head.next是否为none,适于与head=head.next.next

    7、以下python实现代码中 def insert(self, pos, item) 插入链表使用数字索引表示位置,操作时间是O(n),因为不能数字索引不能描述链表内部的位置,只能从链表的开始位置或结束位置逐个遍历从而结算目标元素的位置!优化:存储节点的引用表示位置,能够实现列表的任意位置的插入和删除操作时间复杂度是O(1)

    class Node(object):
        """定义节点类"""
        def __init__(self, elem):
            self.elem = elem
            self.next = None
    
    
    class SingleLinkList(object):
        """定义单链表类"""
    
        def __init__(self, node=None):
            self.__head = node
    
        def is_empty(self):
            """判断链表是否为空"""
            return self.__head is None
    
        def length(self):
            """判断链表长度"""
            cur = self.__head  # cur游标,遍历链表
            count = 0
            while cur is not None:
                count += 1
                cur = cur.next
            return count
    
        def travel(self):
            """遍历整个链表"""
            cur = self.__head
            while cur is not None:
                print(cur.elem, end=' ')
                cur = cur.next
            print("")
    
        def add(self, item):
            """添加元素,头部添加元素item"""
            node = Node(item)
            node.next = self.__head
            self.__head = node
    
        def append(self, item):
            """在链表的尾部添加元素"""
            node = Node(item)
            cur = self.__head
            if self.is_empty():
                self.__head = node
            else:
                while cur.next is not None:
                    cur = cur.next           # 找到链表的尾部
                cur.next = node
    
        def insert(self, pos, item):
            """在链表中插入元素,pos为插入的位置,item为元素"""
            if pos <= 0:
                self.add(item)
            elif pos > (self.length() - 1):
                self.append(item)
            else:
                pre = self.__head
                count = 0
                while count < (pos - 1):
                    count += 1
                    pre = pre.next
                # 循环退出时pre停留在pos-1的位置
                node = Node(item)
                node.next = pre.next
                pre.next = node
    
        def remove(self, item):
            """删除节点"""
            pre = None
            cur = self.__head
            while cur is not None:
                if cur.elem == item:
                    if cur == self.__head:
                        self.__head = cur.next
                    else:
                        pre.next = cur.next
                    break
                else:
                    # 游标移动
                    pre = cur
                    cur = cur.next
    
        def search(self, item):
            """判断元素是否存在"""
            cur = self.__head
            while cur is not None:
                if cur.elem == item:
                    return True
                else:
                    cur = cur.next
            return False
    
    
    if __name__ == '__main__':
    View Code

    二、双向循环链表

    1、

  • 相关阅读:
    对象关系一对多转换为一对一的方案——中介者模式总结
    接口转换的利器——适配器模式总结
    多线程场景设计利器:分离方法的调用和执行——命令模式总结
    对比总结三个工厂模式(简单工厂,工厂方法,抽象工厂)
    创建多个“产品”的方式——工厂方法模式总结
    Java反射+简单工厂模式总结
    最简单的设计模式——单例模式的演进和推荐写法(Java 版)
    对复合(协作)算法/策略的封装方法——装饰模式总结
    Java对象序列化全面总结
    创建产品族的方式——抽象工厂模式
  • 原文地址:https://www.cnblogs.com/yinminbo/p/11480315.html
Copyright © 2011-2022 走看看