1.概述
程序在计算机中运行,实际上就是数据的流动。简单的说就是从一个容器到另外一个容器,数据对应的两种操作存和取。所以对于数据结构的选择,我们最基本的要求就是能装的下,然后就是存取更加的方便。比如买菜就要用篮子,打水就要用水桶,给我们的数据选择合适的容器也是同等的重要。数据结构和算法可以称得上程序员之所以为程序员的东西,我尝试着尽量把这门数据结构说的容易一些,加油!奥利给。
2.时间复杂度
时间复杂度是对程序执行频度的简化表示,并不是严格意义上的时间,通常取最坏条件下的频度。这里采用大O表示法,其基本的步骤为:
1.计算频度函数T(n)
2.保留最高阶项、去掉系数
3.常数为1
常用的时间复杂度有:常数阶O(1)、对数阶O(logn)、线性阶O(n)、线性对数阶O(nlogn)、平方阶O(n^2)、立方阶O(n^3)、k方阶O(n^k)、指数阶O(2^n)
1.线性表
线性表是一种数据存储的概念,其核心的思想是把元素一个个的串起来,就好像排队一样。其可以是一块连续的内存空间(顺序存储结构),也可以是不连续 的内存空间(链式存储结构)
2.数组
数组是内存中一块连续的空间,空间大小一旦确定就不可以改变。可以看到,数组可以用来实现线性表的顺序存储结构。如下图,如果要从数组中取出一个元素,其复杂度是O(N)
3.链表
1.单链表
链表是一段不连续的存储空间,所以其大小是可以动态的变化的。那么如何让链表中的元素串起来呢?所以我们每个位置都必须包含两个变量,一个存储当前元素的值,一个存储下一个元素的地址。这样每一个节点伸手去够下一个节点,所有的节点就可以连成一个整体。链表灵活性高,并且存取元素复杂度为O(N/2)。下面使用python代码实现了单向列表,实现了基本的增删改查。
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
class SingleLinkList(object):
def __init__(self,node=None):
#双下划线开头表示私有成员,不可以直接访问,必须通过class进行访问
self.__head = None
#计算长度
def length(self):
cur = self.__head
count = 0
while cur.next != None:
cur = cur.next
count += 1
return count
#判断是否为空
def is_empty(self):
return self.__head == None
#头部添加,将链表的头部设置为该元素,元素的next为原来的头部
def add(self,item):
node = Node(item)
node.next = self.__head
self.__head = node
#遍历
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem,end=' ')
cur = cur.next
#尾部添加,直接将最后一个元素的next指向新的元素
def append(self,item):
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
#固定位置添加,找到插入的前一个位置元素
#将该元素next设置值为新元素 新元素的next设置为该元素原来的next
def inert(self,pos,item):
if pos<0:
self.add(item)
elif pos > self.length()-1:
self.append(item)
else:
per = self.__head
count = 0
while count < pos-1:
count += 1
per = per.next
node = Node(item)
node.next = per.next
per.next = node
#删除方法
#如果是头部,则删除,将头部指向下一个元素
#如果不是头部,删除,然后将上一个元素的next指向该元素的next
def remove(self,item):
cur = self.__head
per = None
while cur != None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
else:
per.next = cur.next
break
else:
per = cur
cur = cur.next
#查找方法
def search(self,item):
cur = self.__head
while cur:
if cur.elem == item:
return True
else:
cur = cur.next
return False
li = SingleLinkList()
li.append(3)
li.append(4)
li.append(5)
li.append(6)
li.append(7)
li.inert(2,100)
li.remove(5)
print(li.search(100))
li.travel()
2.循环链表
循环链表是对于单向列表的扩展,如果我们比喻单向列表是一队小朋友手拉手的,排队往前走的话。那么双向链表就是这队小朋友围成圈在做游戏。具体实现起来也很简单,我们给尾部元素的next属性指向链表的头部元素即可。
3.双向链表
双向链表顾名思义它有两个方向,也就是对于每一个元素来说,有两个指针。一个指向前面的元素,一个指向后面的元素。具体的实现,每个元素中有三个变量,一个记录前面的元素,一个记录后面的元素。
4.总结
这篇文章是我数据结构方面的开山之作,数据结构可以理解为数据的容器,对应数据在内存中的各种存储方式。我们介绍了线性表的概念,使用线性的结构来存储数据。一种是顺序线性存储方式,即数据使用的是一块连续的内存空间。一种是链式的线性存储方式,使用不连续的内存空间。这种存储方式更灵活,不需要预先知道占用空间的大小。最后我们介绍了链表,包括单向链表,双向链表,循环链表。这种线性的 存储方式是比较容易理解的,也比较简单。这是我的第一天,还不敢说自己已经领悟到了真谛。从道和术来论的话,现在还停留在学术的阶段。目前数据结构对于我来说,就好像是流淌在血管里的血液,是计算机的管道。他们协调调度,就好像舞蹈一样美丽的流动,让人兴奋不已!
5.废话
我很喜欢我的朋友,我也喜欢不确定的生活。每一种生活都有它们的迷人之处,或许开着跑车点的快乐我现在还无法想象。但是我知道的是,每一个人感受快乐的能力就那么一点点。每个人都得去向往那些得不到的,越不容易得到的就越令我们快乐。所以与其去走入那些无聊的快乐的死循环,不如直接扔掉它们。有人说不学习、不进步就是在浪费时间,但是无聊的学习才确实的在浪费我们的生命。你穷尽一生的时间,站在了某个领域的金字塔尖。回过头来还是会觉得不值,跟我们那些无价的青春年华比起来,这些破玩意儿又算得了什么呢?人生最悲惨的就是,我们拥有这天地万物精华之生命,能量之源,智慧之泉,却不知道拿它来做什么。如果颓废懒惰是掉入自己的陷阱,那么自律刻苦是不是掉进了天地的陷阱里呢?我坚信,总有一天我会找到那些配得上我生命的东西。只要我离它更近一步,我所做的就不是在浪费生命。
【MAD/燃向】海战场景燃向混剪 加勒比海盗主题曲 战舰世界宣传片剪辑