首先说下线性表,线性表是一种最基本,最简单的数据结构,通俗点讲就是一维的存储数据的结构。node
线性表分为顺序表和连接表:python
顺序表是用一段连续的存储单元依次存储数据元素,查找元素是很方便的,可是若是要向其中添加删除元素就不那么简单了。由于添加删除元素要先找到那个位置,因为顺序表内部是经过地址的连续才使他成为一个表,当删掉元素时,要把后面的元素所有向前移,填补上空出来的地址空间;添加元素也是同样,须要先把该位置后面的元素向后移去,才能在这块地址上添加元素。数组
以C语言为例:顺序表能够经过一个数组来表示,每建立一个数组就对应给他分配一块内存。固然除了静态分配空间,还能够动态扩展。后续的操做要在这块内存上进行,通常都须要移动数组元素,复杂度会很高。数据结构
在python中,顺序表还有两种表示方式:app
这里的一体和分离是指表中的元素集合,和为实现正确操做而需记录的信息,这两部分是在同一块空间仍是在旁边的一块新的空间中。学习
python中的tuple和list就是采用了顺序表的实现技术,不过tuple是不可变的,不支持对内部的操做。而list是一个元素个数可变的线性表,支持添加删除等操做。list的思想实际上是和C语言中同样的,只是对其中的功能进行了一些封装,也就是list的那些属性。spa
链表,顾名思义,相邻结点是经过链来链接的,那么什么是链呢。咱们知道,C语言中有指针,指针经过地址来找到他的目标。如此说来,一个节点不只仅有他的元素,还须要有一个他下一个元素的地址。指针
那么,这里须要指针和地址。python中的指针是什么呢?下面先把这个放一下,先去理解一下python里面变量标识的实质。code
先看一下这个,为何a和b的id是同样的呢?那我再问一个问题:python中交换两个变量的值时怎样来实现的?blog
1 a = 10 2 b = 20 3 a,b = b,a
为何python能够这样来赋值呢?下面我再画一幅图。
如今是否能理解了呢,变量自己就是存储的一个地址,交换他们的值就是把本身的指向更改一下。那么如今知道了标识的含义,咱们的指针域该怎么写呢,是否是直接用变量等于下一个结点啊。这样看来就不复杂了,接下来的内容就和通常的链表同样了。我在这里说这些就是为了弄清楚python是怎么创建连接的。
那么下面就经过一个类来实现一个节点,节点当中包括数据域和连接域,代码中实现了一些经常使用的功能,好比插入,查找等等。今天主要是说一下单链表是如何运用到python中的,因为我以前没有了解过这些。学习了以后,用本身以前的知识,就能够很方便的运用链表了。后面的代码就不过多解释了,本身仔细琢磨一下。有什么不理解的能够留言,我会尽可能详细的回复。
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @Date : 2018-06-12 11:23:21 4 # @Author : yudanqu (943775910@qq.com) 5 # @Link : https://www.cnblogs.com/yudanqu/ 6 # @Version : $Id$ 7 8 9 class Node(object): 10 """节点""" 11 12 def __init__(self, elem): 13 self.elem = elem 14 self.next = None # 初始设置下一节点为空 15 16 ''' 17 上面定义了一个节点的类,固然也能够直接使用python的一些结构。好比经过元组(elem, None) 18 ''' 19 20 21 # 下面建立单链表,并实现其应有的功能 22 23 24 class SingleLinkList(object): 25 """单链表""" 26 27 def __init__(self, node=None): # 使用一个默认参数,在传入头结点时则接收,在没有传入时,就默认头结点为空 28 self.__head = node 29 30 def is_empty(self): 31 '''链表是否为空''' 32 return self.__head == None 33 34 def length(self): 35 '''链表长度''' 36 # cur游标,用来移动遍历节点 37 cur = self.__head 38 # count记录数量 39 count = 0 40 while cur != None: 41 count += 1 42 cur = cur.next 43 return count 44 45 def travel(self): 46 '''遍历整个列表''' 47 cur = self.__head 48 while cur != None: 49 print(cur.elem, end=' ') 50 cur = cur.next 51 print("\n") 52 53 def add(self, item): 54 '''链表头部添加元素''' 55 node = Node(item) 56 node.next = self.__head 57 self.__head = node 58 59 def append(self, item): 60 '''链表尾部添加元素''' 61 node = Node(item) 62 # 因为特殊状况当链表为空时没有next,因此在前面要作个判断 63 if self.is_empty(): 64 self.__head = node 65 else: 66 cur = self.__head 67 while cur.next != None: 68 cur = cur.next 69 cur.next = node 70 71 def insert(self, pos, item): 72 '''指定位置添加元素''' 73 if pos <= 0: 74 # 若是pos位置在0或者之前,那么都当作头插法来作 75 self.add(item) 76 elif pos > self.length() - 1: 77 # 若是pos位置比原链表长,那么都当作尾插法来作 78 self.append(item) 79 else: 80 per = self.__head 81 count = 0 82 while count < pos - 1: 83 count += 1 84 per = per.next 85 # 当循环退出后,pre指向pos-1位置 86 node = Node(item) 87 node.next = per.next 88 per.next = node 89 90 def remove(self, item): 91 '''删除节点''' 92 cur = self.__head 93 pre = None 94 while cur != None: 95 if cur.elem == item: 96 # 先判断该节点是不是头结点 97 if cur == self.__head: 98 self.__head = cur.next 99 else: 100 pre.next = cur.next 101 break 102 else: 103 pre = cur 104 cur = cur.next 105 106 def search(self, item): 107 '''查找节点是否存在''' 108 cur = self.__head 109 while not cur: 110 if cur.elem == item: 111 return True 112 else: 113 cur = cur.next 114 return False 115 116 117 if __name__ == "__main__": 118 119 # node = Node(100) # 先建立一个节点传进去 120 121 ll = SingleLinkList() 122 print(ll.is_empty()) 123 print(ll.length()) 124 125 ll.append(3) 126 ll.add(999) 127 ll.insert(-3, 110) 128 ll.insert(99, 111) 129 print(ll.is_empty()) 130 print(ll.length()) 131 ll.travel() 132 ll.remove(111) 133 ll.travel()
与单链表相关联的,还有单向循环链表和双向链表:
单向循环链表:在单链表的基础上,再多一个由尾节点指向首节点的连接,首节点是指链表的第一个存数据的结点,而头结点是指指向第一个存数据的结点的那个东西,仅有个连接域,而不是真正存储内容的链表结点。须要注意的是,循环链表中,一些功能的建立是和单链表不同的,好比判空、判满,它是循环的该怎么判断呢?这些内容能够在上面给出的单链表的实现中进行修改得到,能够试一下。
双向链表:与单链表相比,这个新增的特性就是双向。能够从前面向后面传递,也能够从后面向前面传递,这个前面和后面是咱们本身定义的,认为从一端到另外一端是正向,那么倒过来则相反。这个双向链表的实现和单链表也是基本上同样的。单向链表是除了数据域再添加一个连接域,来指向下一个结点。那么一样的道理,双向链表就再添加一个指向前一个结点的连接不就行了。这个时候再建立链表的时候就要把每一个节点与前驱结点以及后继结点的连接创建好。
双向链表的插入和删除等等操做,都要注意,不要把存储的地址信息丢了,仔细考虑好两边的指向,先把谁连接上去,再连接谁。
今天原本只想说说前面那一点点内容的,写的写的,后面感受不得不说一下,不过也没有写的比较完整。你们捡有用的东西来看。