제 기본적인 데이터 구조 - 서열 목록 테이블
A. 메모리
- 컴퓨터의 역할 : 데이터 저장 및 계산. 첫째, 우리는 우리가 현재 컴퓨터가 이진 컴퓨터입니다 사용할 것을 알 필요가, 당신은 단지 컴퓨터 저장 및 이진 데이터를 계산하는 것을 생각할 수있다. 예를 들어 영화를 다운로드 한 경우, 동영상이 영화의 바이너리 데이터를 기반으로 컴퓨터에 저장, 컴퓨터에 저장할 수 있습니다, 우리는 관련 비디오 플레이어 소프트웨어에 의해 영화로 관련 하드웨어 바이너리 데이터를 산술 연산과 관련 될 수있다 결과는 우리가 영화 스크린을보고 오디오 사운드를들을 수있는에 의해 생성.
- 질문 : 정교한 컴퓨터 계산 1 + 2?
- 정책 : 1 우선, 이해하기 간단하고 2 컴퓨터에 입력 될 수 있고, 그 컴퓨터 (1) 및 (2)는 데이터 저장하고 가산기에 의해 두 개의 이진 값을 계산하고 결과를 반환 바이너리 데이터로 변환한다.
- 분석 : 위에서 언급 한에 기재된 컴퓨터는 첫 번째 두 값 1 및 2를 저장해야 컴퓨터가 어떻게 데이터를 저장하는 방법? 이어서 컴퓨터 데이터를 메모리에 직접 저장 될 수 있다는 것은 의심 할 여지가 없다.
- 변수 : 우리가 프로그래밍 세계에서, 직접 변수에 값을 할당 할 수 있지만 최종 값은 컴퓨터의 메모리에 저장됩니다, 그래서 우리는 이해할 수있다, 그것은 조각에 저장된 변수 데이터의 컴퓨터 표현이다 메모리.
- 컴퓨터의 메모리를 시각화하는 방법을 이해?
- 예 : 실제 생활에서 우리에게 컴퓨터의 메모리 공간을 매핑 한 후 메모리가 실제 3 차원 공간에서 우리와 같은 것입니다. 베이징의 북부 드리프트 생활, 거의 모두가 독립적 인 아파트에 거주하거나 한 방에 몇 침실에 공유 한 후 드리프트 북쪽 갑옷 데이터 같고, 그 다음 살고있는 방은 데이터를 저장하는 메모리입니다 공간.
- 분석 : 위의 예에서, 우리는 방 드리프트 북쪽 살아있는 방 공간의 크기 중 하나는 두 가지 기본 속성을 가질 것을 볼 수 있고, 두 번째는 로케이터 방 (집 번호)입니다. 메모리 주소 공간과 메모리 공간 : 그런 다음 컴퓨터의 메모리 공간에 저장된 데이터는 두 가지 기본 특성을 가지고 있습니다. 크기 범위 일 수있는 메모리 공간의 어드레스 공간의 크기를 나타낼 수 어드레싱에 의해 (16 진수 표현)의 데이터 값을 저장하는 메모리를 찾아 메모리 공간에 저장된 데이터 값을 질의하기 위해 사용될 수있다.
- 방법을 이해하기 = 10이 할당 해당하는 메모리 맵은 무엇입니까?
- 인용구 : 변수가 메모리 공간의 조각의 주소에 저장 될 때, 당신은 메모리 공간이 변수에 대한 참조가 될 수 있습니다. A = 10 (A)는 10의 메모리 공간에 대한 참조이다.
- 포인트 : 변수가 메모리 어드레스 공간에 저장 될 때, 그 메모리에 변수 (참조) 점이라고.
- 데이터 점유 된 메모리 공간의 크기의 종류 : 정형 (4 바이트), 부동 소수점 (8 바이트), 문자 (1 바이트)
두 시퀀스 테이블 : 컬렉션의 요소를 순차적으로 저장됩니다. 하나의 데이터 유형 및 여러 데이터 유형 시퀀스에 나타난 구조의 두 가지 형태로 나눌 수있다.
- 단일 데이터 형식 : 10,20,30 어떻게 메모리에 저장하기 위해, 각각의 데이터를 INT의 가치를 어떻게 얻을 = A?
- 여러 데이터 형식 : 방법 = 메모리 리 10를 저장하기 위해, 'A', 96.5, 어떻게 얻을 각각의 데이터는 가치?
- 의료 과실 순서 표 : 주문 테이블 구조, 데이터의 크기가 연속 저장 공간을 적용하기 위해 사전에 시간을 알 필요가 데이터의 재배치시 확장 될 필요가있다.
- 파이썬 목록에 튜플 및 구현 기술 순서 테이블의 두 가지 유형을 사용합니다.
세 목록 : 주문 목록에 관하여,리스트 구조는 컴퓨터 메모리, 플렉시블 동적 메모리 관리의 이점을 취할 수있다.
-리스트 (링크 된리스트) 시퀀스 테이블과 공통 기본적인 데이터 구조는 선형 테이블이지만 데이터를 계속 저장 아니지만, 각 노드 (데이터 기억 수단)은 다음 정보의 노드에 저장된 (즉, 주소) :
- 1, 단방향 연결리스트
또한 단일 연결리스트 단일 연결리스트로 알려진, 테이블은 각 노드가 두 필드 정보 필드 (field 요소) 및 링크 필드를 포함하는 것이 가장 간단한 형태이다. 마지막 노드에 링크 된 목록의 다음 노드 및 링크 필드 지점에 대한 링크 포인트는 null 값입니다.
- 요소가 특정 데이터를 저장하는데 사용 ELEM 테이블.
- 다음 노드의 저장을위한 다음 링크 필드.
- 노드의리스트의 헤드 노드 (제 노드) 및 P 출발 위치하는 변수 P 점은 표에서 찾아 볼 수있다.
- 추상 데이터 유형 정의의 단방향 연결리스트 :
. Is_empty는 () : 목록이 비어 있습니다
. 길이 () 사슬 길이
. 여행 () : 전체 목록 트래버스
. add(item):链表头部添加元素
. append(item):链表尾部添加元素
. insert(pos, item):指定位置添加元素
. remove(item):删除节点
. search(item):查找节点是否存在
- 代码实现:
class Node(): def __init__(self,item): self.item = item self.next = None def __str__(self): return str(self.item) class Link(): def __init__(self): #永远指向链表中第一个节点 self._head = None def isEmpty(self): return self._head is None def add(self,item): node = Node(item) node.next = self._head self._head = node def length(self): count = 0 if self.isEmpty(): return count else: cur = self._head 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) cur = cur.next def append(self,item): node = Node(item) cur = self._head if self.isEmpty(): self._head = node else: while cur is not None: #因为循环遍历结束后cur会指向空并非最后一个节点 pre_cur = cur cur = cur.next pre_cur.next = node def search(self,item): ex = False cur = self._head while cur is not None: if cur.item == item: ex = True break cur = cur.next return ex def insertTo(self,item,index): cur = self._head ex = 0 node = Node(item) #插入到第一个节点位置 if index <= 0: self.add(item) #插入到最后一个节点位置 elif index >= self.length(): self.append(item) else: while cur is not None: pre = cur cur = cur.next #此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1 if ex == index-1: node.next = cur pre.next = node break ex += 1 def remove(self,item): pre = None cur = self._head #删除的是第一个节点 if cur.item == item: self._head = cur.next else: while cur is not None: pre = cur cur = cur.next if cur.item == item: pre.next = cur.next cur.next = None cur = cur.next #测试代码 link = Link() link.add('bobo') link.add('jay') link.add('tom') link.add('jerry') # print(link.search('tom')) # link.insertTo('haha',1) link.remove('bobo') link.travel()
- 2.单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头结点。
- 基本操作和单链表基本一样,实现代码如下:
# coding=utf-8 # 单向循环链表 class Node: """节点""" def __init__(self, item): self.item = item self.next = None def __str__(self): return str(self.item) class SinCycLinkedList: """单向循环链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head is None def length(self): """链表长度""" if self.is_empty(): return 0 count = 1 cur = self._head while cur.next != self._head: # print("cur", cur.item) count += 1 cur = cur.next return count def travel(self): """遍历""" if self.is_empty(): return cur = self._head print(cur.item) while cur.next != self._head: cur = cur.next print(cur.item) def add(self, item): """在头部添加一个节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: node.next = self._head cur = self._head while cur.next != self._head: cur = cur.next cur.next = node self._head = node def append(self, item): """在尾部添加一个节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: cur = self._head # print(type(cur), cur.item, cur.next) while cur.next != self._head: cur = cur.next # print(cur.item) cur.next = node node.next = self._head def insert(self, pos, item): """指定位置pos添加节点""" if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) cur = self._head cur_pos = 0 while cur.next != self._head: if (pos - 1) == cur_pos: node.next = cur.next cur.next = node break cur_pos += 1 cur = cur.next def remove(self, item): """删除一个节点""" if self.is_empty(): return pre = self._head # 删除首节点 if pre.item == item: cur = pre while cur.next != self._head: cur = cur.next cur.next = pre.next # 删除首节点(跳过该节点) self._head = pre.next # 重新指定首节点 # 删除其他的节点 else: cur = pre while cur.next != self._head: if cur.next.item == item: cur.next = cur.next.next cur = cur.next def search(self, item): """查找节点是否存在""" if self.is_empty(): return -1 cur_pos = 0 cur = self._head if cur.item == item: return cur_pos while cur.next != self._head: if cur.item == item: return cur_pos cur_pos += 1 cur = cur.next if cur_pos == self.length() - 1: return -1 if __name__ == "__main__": ll = SinCycLinkedList() ll.add(1) # 1 ll.add(2) # 2 1 # ll.travel() ll.append(3) # 2 1 3 ll.insert(2, 4) # 2 1 4 3 ll.insert(4, 5) # 2 1 4 3 5 ll.insert(0, 6) # 6 2 1 4 3 5 print("length:", ll.length()) # 6 ll.travel() # 6 2 1 4 3 5 print("search(3)", ll.search(3)) # 4 print("search(7)", ll.search(7)) # -1 print("search(6)", ll.search(6)) # 0 print("remove(1)") ll.remove(1) print("length:", ll.length()) # 6 2 4 3 5 print("remove(6)") ll.remove(6) ll.travel()
3.双向链表:一种更复杂的链表是 "双向链表" 或 "双面链表"。每个节点有两个链接:一个指向前一个节点,当次节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
- 代码实现:
# coding=utf-8 # 双向链表 class Node: """节点""" def __init__(self, item): self.item = item self.prev = None self.next = None class DLinkList: """双向链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head is None def length(self): """获取链表长度""" if self.is_empty(): return 0 else: cur = self._head count = 1 while cur.next is not None: count += 1 cur = cur.next return count def travel(self): """遍历链表""" print("↓↓" * 10) if self.is_empty(): print("") else: cur = self._head print(cur.item) while cur.next is not None: cur = cur.next print(cur.item) print("↑↑" * 10) def add(self, item): """链表头部添加节点""" node = Node(item) if self.is_empty(): self._head = node else: cur = self._head node.next = cur cur.prev = node self._head = node def append(self, item): """链表尾部添加节点""" node = Node(item) if self.is_empty(): self._head = node else: cur = self._head # 遍历找到最后一个节点 while cur.next is not None: cur = cur.next # 在尾节点添加新的节点 cur.next = node node.prev = cur def insert(self, pos, item): """指定位置添加""" # 头部添加 if pos <= 0: self.add(item) # 尾部添加 elif pos > (self.length() - 1): self.append(item) # 其他位置添加 else: node = Node(item) cur = self._head cur_pos = 0 while cur.next is not None: if cur_pos == (pos - 1): # 与下一个节点互相指向 node.next = cur.next cur.next.prev = node # 与上一个节点互相指向 cur.next = node node.prev = cur cur_pos += 1 cur = cur.next def remove(self, item): """删除节点""" if self.is_empty(): return else: cur = self._head # 删除首节点 if cur.item == item: self._head = cur.next cur.next.prev = None # 删除其他节点 else: while cur.next is not None: if cur.item == item: # 删除之前:1 ←→ [2] ←→ 3 # 删除之后:1 ←→ 3 cur.prev.next = cur.next cur.next.prev = cur.prev cur = cur.next # 删除尾节点 if cur.item == item: cur.prev.next = None def search(self, item): """查找节点是否存在""" if self.is_empty(): return -1 else: cur = self._head cur_pos = 0 while cur.next is not None: if cur.item == item: return cur_pos cur_pos += 1 cur = cur.next if cur_pos == (self.length() - 1): return -1 if __name__ == "__main__": ll = DLinkList() ll.add(1) # 1 ll.add(2) # 2 1 ll.append(3) # 2 1 3 ll.insert(2, 4) # 2 1 4 3 ll.insert(4, 5) # 2 1 4 3 5 ll.insert(0, 6) # 6 2 1 4 3 5 print("length:", ll.length()) # 6 ll.travel() # 6 2 1 4 3 5 print("search(3)", ll.search(3)) print("search(4)", ll.search(4)) print("search(10)", ll.search(10)) ll.remove(1) print("length:", ll.length()) ll.travel() print("删除首节点 remove(6):") ll.remove(6) ll.travel() print("删除尾节点 remove(5):") ll.remove(5) ll.travel()
一.内存
- 计算机的作用:对数据进行存储和运算。首先我们需要知道我们目前使用的计算机都是二进制的计算机,就以为着计算机只可以存储和运算二进制的数据。例如下载好的一部电影,该电影可以存储到计算机中,计算机中存储的是基于二进制的电影数据,然后我们可以通过相关的视频播放软件结合相关的硬件对电影的二进制数据进行相关的运算操作,所产生的结果就是我们可以看到电影的画面和听到音频的声音。
- 问题:阐述计算机如何计算1+2的结果?
- 阐述:简单理解为,首先可以将1和2输入到计算机中,然后计算机会将1和2转换成二进制的数据进行数据存储,然后通过加法器进行两个二进制数值的计算并返回结果。
- 分析:上述的阐述中提到,计算机首先需要存储1和2这两个数值,那么计算机如何进行数据的存储呢?那么毫无疑问,计算机可以将数据直接存储到内存中。
- 变量:我们在编程世界中,可以将某个数值直接赋值给一个变量,但是最终数值会被存储到计算机的内存中,因此我们可以理解为,变量表示的就是计算机中进行数据存储的某一块内存。
- 如何形象化的理解计算机的内存?
- 举例:将计算机的内存空间映射到我们现实生活中的话,内存就好比是我们在现实生活中三维立体的空间。生活在北京的北漂们,几乎都居住的是一个独立的公寓或者合租在一个几居室的某一个房间中,那么北漂甲就好比是数据,而他所居住的房间则就是存储数据的一块内存空间。
- 分析:从上述案例中,我们可以得知北漂甲居住的房间会有两个基本的属性,其一就是房间空间的大小,其二就是房间的一个位置标识(门牌号)。那么计算机中存储数据的内存空间也会有这两个最基本的属性:内存空间大小和内存空间的地址。内存空间的大小可以表示该空间可以存储数据值的大小范围,内存空间的地址(用十六进制数值表示)可以用来通过寻址定位、查找到该内存空间中所存储的数据值。
- 如何理解 a = 10 这条赋值语句对应的内存图呢?
- 引用:当一个变量中存储的是某一块内存空间的地址,则该变量即可成为那块内存空间的引用。a=10,a就是10所在内存空间的一个引用。
- 指向:当一个变量中存储了一块内存空间的地址,则称该变量(引用)指向了那块内存。
- 不同类型数据占用内存空间的大小:整形(4字节),浮点型(8字节),字符型(1字节)
二.顺序表:集合中存储的元素是有顺序的。顺序表的结构可以分为两种形式:单数据类型和多数据类型。
- 单数据类型:在内存中如何存储 int a = 10,20,30,如何取得每一个数据值呢?
- 多数据类型:在内存中如何存储 li = 10,'a',96.5,如何获取每一个数据值呢?
- 顺序表的弊端:顺序表的结构需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁。
- Python中的 list 和 tuple 两种类型采用了顺序表的实现技术。
三.链表:相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
- 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是每一个结点(数据存储单元)里存放下一个结点的信息(即地址):
- 1、单向链表
单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
- 表中元素elem用来存放具体的数据。
- 链接域next用来存放下一个节点的位置。
- 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。
- 单向链表的抽象数据类型定义:
. is_empty():链表是否为空
. length():链表长度
. travel():遍历整个链表
. add(item):链表头部添加元素
. append(item):链表尾部添加元素
. insert(pos, item):指定位置添加元素
. remove(item):删除节点
. search(item):查找节点是否存在
- 代码实现:
class Node(): def __init__(self,item): self.item = item self.next = None def __str__(self): return str(self.item) class Link(): def __init__(self): #永远指向链表中第一个节点 self._head = None def isEmpty(self): return self._head is None def add(self,item): node = Node(item) node.next = self._head self._head = node def length(self): count = 0 if self.isEmpty(): return count else: cur = self._head 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) cur = cur.next def append(self,item): node = Node(item) cur = self._head if self.isEmpty(): self._head = node else: while cur is not None: #因为循环遍历结束后cur会指向空并非最后一个节点 pre_cur = cur cur = cur.next pre_cur.next = node def search(self,item): ex = False cur = self._head while cur is not None: if cur.item == item: ex = True break cur = cur.next return ex def insertTo(self,item,index): cur = self._head ex = 0 node = Node(item) #插入到第一个节点位置 if index <= 0: self.add(item) #插入到最后一个节点位置 elif index >= self.length(): self.append(item) else: while cur is not None: pre = cur cur = cur.next #此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1 if ex == index-1: node.next = cur pre.next = node break ex += 1 def remove(self,item): pre = None cur = self._head #删除的是第一个节点 if cur.item == item: self._head = cur.next else: while cur is not None: pre = cur cur = cur.next if cur.item == item: pre.next = cur.next cur.next = None cur = cur.next #测试代码 link = Link() link.add('bobo') link.add('jay') link.add('tom') link.add('jerry') # print(link.search('tom')) # link.insertTo('haha',1) link.remove('bobo') link.travel()
- 2.单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头结点。
- 基本操作和单链表基本一样,实现代码如下:
# coding=utf-8 # 单向循环链表 class Node: """节点""" def __init__(self, item): self.item = item self.next = None def __str__(self): return str(self.item) class SinCycLinkedList: """单向循环链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head is None def length(self): """链表长度""" if self.is_empty(): return 0 count = 1 cur = self._head while cur.next != self._head: # print("cur", cur.item) count += 1 cur = cur.next return count def travel(self): """遍历""" if self.is_empty(): return cur = self._head print(cur.item) while cur.next != self._head: cur = cur.next print(cur.item) def add(self, item): """在头部添加一个节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: node.next = self._head cur = self._head while cur.next != self._head: cur = cur.next cur.next = node self._head = node def append(self, item): """在尾部添加一个节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: cur = self._head # print(type(cur), cur.item, cur.next) while cur.next != self._head: cur = cur.next # print(cur.item) cur.next = node node.next = self._head def insert(self, pos, item): """指定位置pos添加节点""" if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) cur = self._head cur_pos = 0 while cur.next != self._head: if (pos - 1) == cur_pos: node.next = cur.next cur.next = node break cur_pos += 1 cur = cur.next def remove(self, item): """删除一个节点""" if self.is_empty(): return pre = self._head # 删除首节点 if pre.item == item: cur = pre while cur.next != self._head: cur = cur.next cur.next = pre.next # 删除首节点(跳过该节点) self._head = pre.next # 重新指定首节点 # 删除其他的节点 else: cur = pre while cur.next != self._head: if cur.next.item == item: cur.next = cur.next.next cur = cur.next def search(self, item): """查找节点是否存在""" if self.is_empty(): return -1 cur_pos = 0 cur = self._head if cur.item == item: return cur_pos while cur.next != self._head: if cur.item == item: return cur_pos cur_pos += 1 cur = cur.next if cur_pos == self.length() - 1: return -1 if __name__ == "__main__": ll = SinCycLinkedList() ll.add(1) # 1 ll.add(2) # 2 1 # ll.travel() ll.append(3) # 2 1 3 ll.insert(2, 4) # 2 1 4 3 ll.insert(4, 5) # 2 1 4 3 5 ll.insert(0, 6) # 6 2 1 4 3 5 print("length:", ll.length()) # 6 ll.travel() # 6 2 1 4 3 5 print("search(3)", ll.search(3)) # 4 print("search(7)", ll.search(7)) # -1 print("search(6)", ll.search(6)) # 0 print("remove(1)") ll.remove(1) print("length:", ll.length()) # 6 2 4 3 5 print("remove(6)") ll.remove(6) ll.travel()
3.双向链表:一种更复杂的链表是 "双向链表" 或 "双面链表"。每个节点有两个链接:一个指向前一个节点,当次节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
- 代码实现:
# coding=utf-8 # 双向链表 class Node: """节点""" def __init__(self, item): self.item = item self.prev = None self.next = None class DLinkList: """双向链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head is None def length(self): """获取链表长度""" if self.is_empty(): return 0 else: cur = self._head count = 1 while cur.next is not None: count += 1 cur = cur.next return count def travel(self): """遍历链表""" print("↓↓" * 10) if self.is_empty(): print("") else: cur = self._head print(cur.item) while cur.next is not None: cur = cur.next print(cur.item) print("↑↑" * 10) def add(self, item): """链表头部添加节点""" node = Node(item) if self.is_empty(): self._head = node else: cur = self._head node.next = cur cur.prev = node self._head = node def append(self, item): """链表尾部添加节点""" node = Node(item) if self.is_empty(): self._head = node else: cur = self._head # 遍历找到最后一个节点 while cur.next is not None: cur = cur.next # 在尾节点添加新的节点 cur.next = node node.prev = cur def insert(self, pos, item): """指定位置添加""" # 头部添加 if pos <= 0: self.add(item) # 尾部添加 elif pos > (self.length() - 1): self.append(item) # 其他位置添加 else: node = Node(item) cur = self._head cur_pos = 0 while cur.next is not None: if cur_pos == (pos - 1): # 与下一个节点互相指向 node.next = cur.next cur.next.prev = node # 与上一个节点互相指向 cur.next = node node.prev = cur cur_pos += 1 cur = cur.next def remove(self, item): """删除节点""" if self.is_empty(): return else: cur = self._head # 删除首节点 if cur.item == item: self._head = cur.next cur.next.prev = None # 删除其他节点 else: while cur.next is not None: if cur.item == item: # 删除之前:1 ←→ [2] ←→ 3 # 删除之后:1 ←→ 3 cur.prev.next = cur.next cur.next.prev = cur.prev cur = cur.next # 删除尾节点 if cur.item == item: cur.prev.next = None def search(self, item): """查找节点是否存在""" if self.is_empty(): return -1 else: cur = self._head cur_pos = 0 while cur.next is not None: if cur.item == item: return cur_pos cur_pos += 1 cur = cur.next if cur_pos == (self.length() - 1): return -1 if __name__ == "__main__": ll = DLinkList() ll.add(1) # 1 ll.add(2) # 2 1 ll.append(3) # 2 1 3 ll.insert(2, 4) # 2 1 4 3 ll.insert(4, 5) # 2 1 4 3 5 ll.insert (0, 6) # 6 1 2 3 4 5 print("length:", ll.length()) # 6 ll.travel () # 6 1 2 3 4 5 인쇄 (ll.search (3) "(3) 검색") 인쇄 ( "(4) 검색", ll.search (4)) 인쇄 ( "(10 검색 ) "ll.search (10)) ll.remove (1) 인쇄 ("길이 "ll.length ()) ll.travel () 인쇄 ("删除首节点제거 (6) ") ll.remove (6) ll.travel () 인쇄 ( "删除尾节点제거 (5) :") ll.remove (5) ll.travel ()