zoukankan      html  css  js  c++  java
  • 数组与链表

    数组就好像是一个军队,整齐,有序。
    数组对应的英文是array,是有限个相同类型的变量所组成的有序集合,数组中的每一个变量称为元素。
    数组在内存中是顺序存储的,可以很好的实现逻辑上的顺序表

    数组的基本操作

    def operate_list():
        '''
        数组适合读操作多,写操作少
        '''
        # 初始化列表
        my_list = [3, 1, 2, 5, 4, 9, 7, 2]
    
        # 读取元素O(1)
        print(my_list[2]) # 像这种根据下标读取元素的方式叫做随机读取
    
        # 更新元素算是数组中的Bug了,链表中没用索引更新么O(1)
        my_list[3] = 10
        print(my_list[3]) # 
    
        # 尾部插入元素 # 综合来说插入元素的操作是O(n)
        my_list.append(6)
        print(my_list)
    
        # 中间插入元素
        my_list.insert(5, 11)
        print(my_list)
    
        # 删除元素
        my_list.remove(6)
        print(my_list)
    
    
    operate_list()
    

    自己定义一个数组

    # 定义一个类
    class MyArray():
        def __init__(self,capacity): # 类的初始化
            self.array = [None] * capacity  # 定义具体的类变量
            self.size = capacity
            
        def insert(self,index,element):
            # 判断访问下标是否超出范围
            if index < 0 or index > self.size:
                raise Exception('超出数组实际元素范围!')
            # 从右向左循环,逐个元素向右挪一位
            for i in range(self.size-1,index-1,-1):
                self.array[i+1] = self.array[i]
            # 腾出的位置放入新元素
            self.array[index] = element
            self.size += 1
        def insert_v2(self,index,element):
            # 判断访问下标是否超出范围
            if index < 0 or index > self.size:
                raise Exception("超出数组实际元素范围")
            # 如果实际元素达到数组容量上限,数组扩容
            if self.size >= len(self.array):
                self.resize()
            # 从右向左循环,逐个元素向右挪一位
            for i in range(self.size-1,index-1,-1):
                self.array[i+1] = self.array[i]
            # 腾出的位置放入新元素
            self.array[index] = element
            self.size += 1
            print(self.size)
            print(self.array)
        def resize(self):
            array_new = [None] * len(self.array) *2 # 扩容2倍
            # 从旧数组拷贝到新数组
            for i in range(self.size):
                array_new[i] = self.array[i]
            self.array = array_new
        
        def remove(self,index):
            # 判断访问下标是否超出范围
            if index < 0 or index >= self.size:
                raise Exception("超出数组实际元素范围!")
            # 从左到右,逐个元素向左挪动一位
            for i in range(index,self.size-1):
                self.array[i] = self.array[i+1]
            self.size -= 1
        
        def output(self):
            for i in range(self.size):
                print(self.array[i])
    array = MyArray(4) # 4代表的是capacity这个变量的值
    array.insert_v2(0,10) # 0,10分别代表索引和传入的值
    

    链表

    相比于数组是正规军,链表就类似于地下党了,他们之间的联系是采用单线联络的方式。
    链表是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    单向链表的节点包含两部分,一部分是存放数据的变量data
    另一部分是指向下一个节点的指针next

    而双向链表除了拥有data和next指针外

    还拥有指向前置节点的prev指针

    链表的第一个节点称为头节点
    最后一个节点称为尾节点
    尾节点的next指针指向空
    链表寻找元素,只能根据前一个节点的next指针指向后一个节点

    from os import remove
    
    # 这个只是next来赋值变量给另外一个,有点复杂,头晕,变量太多了
    class Node:
        '''
        单向链表的节点包含两部分,一部分是存放数据的变量data
        另一部分是指向下一个节点的指针next
        '''
        def __init__(self,data):
            self.data = data
            self.next = None
    # 而双向链表除了拥有data和next指针外
    # 还拥有指向前置节点的prev指针    
    class LinkedList:
        '''
        链表的第一个节点称为头节点
        最后一个节点称为尾节点
        尾节点的next指针指向空
        链表寻找元素,只能根据前一个节点的next指针指向后一个节点
    
        '''
        def __init__(self):
            self.size = 0
            self.head = None
            self.last = None
    
        def get(self,index): # O(n)
            if index < 0 or index >= self.size:
                raise Exception("超出链表节点范围!")
            p = self.head
            for i in range(index):
                p = p.next
            return p
    
        def insert(self,data,index): #O(1)
            if index < 0 or index > self.size:
                raise Exception('超出链表节点范围!')
            node = Node(data)
            if self.size == 0:
                # 空链表
                self.head = node
                self.last = node
            elif index == 0:
                # 插入头部
                node.next = self.head
                self.head = node
            elif self.size == index:
                # 插入尾部
                self.last.next = node
                self.last = node
            else:
                # 插入中间
                prev_node = self.get(index-1)
                node.next = prev_node.next
                prev_node.next = node
            self.size  += 1
    
        def remove(self,index):# O(1)
            if index < 0 or index >= self.size:
                raise Exception('超出链表节点范围!')
            # 暂存被删除的节点,用于返回
            if index == 0:
                # 删除头节点
                remove_node = self.head
                self.head = self.head.next
                if self.size == 1:
                    self.last == Node
            elif index == self.size - 1:
                # 删除尾节点
                prev_node = self.get(index-1)
                remove_node = prev_node
                prev_node.next = None
                self.last = prev_node
            else:
                # 删除中间节点
                prev_node = self.get(index-1)
                next_node = prev_node.next.next
                remove_node = prev_node.next
                prev_node.next = next_node
            self.size -= 1
            return remove_node
    
        def output(self):
            p = self.head
            while p is not None:
                print(p.data)
                p = p.next
    
    linkedList = LinkedList()
    linkedList.insert(3,0)    
    linkedList.insert(4,0)    
    linkedList.insert(9,2)
    linkedList.insert(5,3)
    linkedList.insert(6,1)
    linkedList.remove(0)
    
    linkedList.output()
    
    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    WPF PasswordBox不支持绑定解决方法
    获取当前日期是第几个星期
    WPF 事件触发命令
    EntityFramework使用动态Lambda表达式筛选数据
    C#发邮件
    Entity Framework 多对多查询的写法
    获取WPF窗口句柄
    C#调整图片亮度和对比度
    oracle 批量修改数据
    react前端自动化测试: jest + enzyme
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15248445.html
Copyright © 2011-2022 走看看