大话数据结构(程杰)

数据结构绪论

数据结构学科定义:是一门研究非数值计算的程序设计中的操作对象,它们之间的关系和操作等相关问题的数据学科。

数据组成

数据元素:组成数据的基本单位。
数据项:数据元素可以优若干个数据项构成,数据不可分割的最小单位。
数据对象:数据相同的元素组成的集合,是数据的子集合。
example:
[类数据:人类, 元素:{张三, 李四,...}, 数据项:{眼睛,鼻子,...}, 数据对象(眼睛):{张三的眼睛, 李四的眼睛...}]

单独说说数据结构
不同的元素的数据元素之间不是相互独立的,而是存在关系的,这种关系称之为结构。

逻辑结构:集合、线性、树形、拓扑图
物理结构:数据的逻辑结构在计算机中的存储形式

顺序存储结构:数据存储在对地址连续的存储单元,逻辑关系与物理关系一致。
连式存储结构:数据元素位置任意,需要指针存放数据元素的地址信息。

算法

时间复杂度

这里仅仅记录下几个重要的定义:
算法的时间复杂度:T(n),随着n的变化,执行次数的变化,仅仅关注T(n)的最高阶。O(1):常数阶、O(n):线性阶、O($ n^2 $)平方阶 。下面分别给出不同等差数列求和为例:

# 1+2...+n
# O(1)
def sum_1(n):
    return int((1 + n) * n / 2)

# n
def sum_2(n):
    count = 0
    for i in range(1, n+1):
        count += i
    return count

# n*n
def sum_3(n):
    count = 0
    for i in range(1, n+1):
        for j in range(i):
            count += 1
    return count

常用的算法复杂度比较:
$$ O(1) < O(n) < O(logn) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) $$
最坏复杂度和平均复杂度:n个数顺序存储,现在需要插入某个元素,最好的情况1, 最坏的情况n+1,那么平均复杂度是多少了?,搜寻任意x的期望值(n+2)/2。一般没有特殊说明,复杂度都是指最坏的情况。

空间复杂度

定义和时间复杂度类似,重要的是我们可以通过空间复杂度来换取时间。
example:设计一个算法,复杂度为O($n^2$), 这里把算法的结果顺序存储下来,复杂度O(1)。

线性表

最大的确点插入和删除:算法时间复杂度大。为了解决这个问题就得牺牲下空间---连式存储

  • 连式存储
    每个数据储存叫节点Node,Node由数域和指针域,前者存储数值后者存储后继的地址信息。存在头指针,每次必须从头指针开始,最后一个指针域为空。

  • 搜寻
    想得到某个指定地址数据,每次必须从头开始,往下搜寻下去找到即停止,否者直到指针域为空停止说明数据不存在。时间复杂度O(n).

  • 插入
    p节点后插入s节点,s->next=p->next, p-next=s,p的后继赋值给s后继,p后继改为s

  • 删除
    p->next = p->next->next
    ps:静态链表,循环链表,双向链表

想象下弹夹

  1. 是线性单链表
  2. 仅仅允许在链表尾部,即栈顶进行插入和删除操作
  3. 1-n数依次进栈(仅仅是进去的顺序),出站顺序必须满足任意想编号x后面的编号小于x的必须倒序排列。
  4. 两个站共享内存,从中间某个位置作为两个栈顶, 两端为栈为。如果容积为n当两个站的顶部地址差为1时代表栈满。
  5. 链栈不存在栈满的情况???
  6. 栈的递归运用,斐波那契数列数列为例,每次递归到最底层就把数据压入栈的底部,慢慢向上回溯到顶部得到最后顶部值。
# 方法1
def Fib():
    a = 1
    yield a
    b = a
    yield b
    while 1:
        c = a + b
        yield c
        a = b
        b = c

# 这里采用递归的方法解决,稍微改变下需求,求第i个fib数列
def Fib_i(i):
    if i <= 2:
        return 1
    else:
        return Fib_i(i-1) + Fib_i(i-2)

串(string)

  • 朴素的模式匹配方法
    001 匹配000000001,从第一个起点index=0开始001,发现前两个00能匹配到第1个不行,然后index=1,直到尾部,如果两个长度分别为m, n (n >= m),则算法复杂度为(n - m + 1)* m。

  • KMP模式匹配
    abcd和abcabcd进行匹配

step1:
abcabcd
abcd
index=3时不匹配
step2
abcabcd
`abcd
index=1终止
step3
abcabcd
``abcd
index=2终止
!!!!!!其实上面step2 step3都是无效
因为在step1时a=a,向后一个个平移到abcabcd第二个a时才可以进一步可能,因此step2可以直接跳到下面
abcabcd
···abcd

二叉树

  • 二叉树的性质
  1. 第i层节点数最多可能:$2^{i-1}$
  2. 深度为n的二叉树至多:$2^{n}-1$个节点
  3. 叶节点为$n_{leaf}$,度为2 的节点数$n_{node2}$,则$n_{leaf}=n_{node2}+1$
  4. n个节点完全二叉树的深度$[log_2(n)] + 1$,[]为取整运算
  5. 把完全二叉树n个节点按层进行编号。如果i=1则为root,i>1这这个节点的父节点为$[i/2]$;如果节点$2i > n$就没有左孩子,否则左孩子为$2i$;如果$2 * i +1 > n$则无孩子,否则其有孩子为$2 * i +1$.
  • 满树

n个节点,除了每个叶节点,每个节点都有左右左右子树,并且所有的叶节点都在最底层,层次m与节点n存在 $2^m - 1=n$关系。

  • 完全二叉树

对应一个二叉树按层次对所以节点编号包括叶节点,如果所有节点编号与同样深度的满二叉树编号结果一致,那么该树为满二叉树。
性质、属性:

  1. 叶节点只能在最下面2层,倒数第二层存在叶节点则,一定集中在树右侧且连续,二最下面一层则集中在左侧且连续。
  2. 同样节点数的树,完全二叉树深度最小

满树是完全二叉树的子集

  • 二叉树的遍历
  1. 前序:根节点左孩子右孩子
  2. 中序:左孩子根节点右孩子
  3. 后续:左孩子右孩子根节点
  4. 层次遍历:顾名思义吧

单独成文

查找

单独成文

排序

内排序:与下相反
外排序:需要辅助空间

排序方法:
1.冒泡排序:两两比较,不符合则交换,复杂度$O(n^2)$。
下面看看这两者的时间对比:# out:0.34375643730163574; 0.10623884201049805

def buddleSort(L):
    n = len(L)
    for i in range(n):
        count = 0
        for j in range(n - 1):
            if L[j] > L[j + 1]:
                c = L[j]
                L[j] = L[j + 1]
                L[j + 1] = c
                count = 1
            else:
                pass
        if count == 0:
            # 如果序列不在发生改变跳出循环
            break
    return L


print(buddleSort([4, 3, 1, 2]))

# 升级算法:比如:
# 3, 2, 1, 4, 5   初始状态
# 2, 1, 3, 4, 5   第一个外层循环后,内层在j=2时后面的顺序不在改变
# 1, 2, 3, 4, 5   在第二外层,j=2和后面都不要在遍历了,前面一个外层已经知道
def buddleSort2(L):
    n = len(L)
    m = n
    for i in range(n):
        count = 1
        # print('m', m, i)
        flag = None
        for j in range(m - 1):
            if L[j] > L[j + 1]:
                c = L[j]
                L[j] = L[j + 1]
                L[j + 1] = c
                count = 0
                flag = j + 1
            else:
                pass
        # print('flag:', flag)
        m = flag
        if count:
            # 如果序列不在发生改变跳出循环
            break
    return L


Z = [1, 4, 3, 2] + list(range(10, 1000000))
print(Z[:7])
s = time.time()
res = buddleSort(Z)
cost = time.time() - s
print(Z[:7])    # 行数调用的时候吧Z顺序已经改变了,fuck

Z = [1, 4, 3, 2] + list(range(10, 1000000))
s = time.time()
res2 = buddleSort2(Z)
cost2 = time.time() - s
print(cost, cost2)
print(res2[:7])
  1. 简单排序法:找到最小的排在第一位,在剩下的元素中在找最小的排在第二位。。。。。复杂度$O(n^2)$

  2. 直接插入排序:(利用链式存储)复杂度$O(n^2)$。参考
    (http://bubkoo.com/2014/01/15/sort-algorithm/shell-sort/)

def insert(i, j, L):
    # i < j
    c = L[j]
    for z in range(j, i - 1, -1):
        L[z] = L[z - 1]
    L[i] = c
    return L
x = [1, 2, 4, 5]
print(insert(0, 3, x))

def InsertSort(L):
    n = len(L)
    if L[0] > L[1]:
        L = insert(0, 1, L)
    for i in range(2, n):
        for z in range(i - 1, -1, -1):
            if (L[i] < L[z]) and (L[i] >= L[z-1]):
                L = insert(z, i, L)
    return L

x = [1, 4, 1, 3, 4, 6, 2]
print(InsertSort(x))
  1. 希尔排序:将数据分为d组,然后组内进行插入排序,d递减步长为1直到循环到1即停止,复杂度$O(n^{3/2})$。[参考]
  2. 堆排序:将数据编号按层次构建完全二叉树,利用满二叉树性质,从叶节点从树的下面向上寻,吧大的数给父节点,最后root就为最大的数,如此反复,就会得到序列。复杂度$O(nlog_2n)$
  3. 归并排序:分而治之复杂度$O(nlog_2n)$
  4. 快速排序:参考**复杂度$O(nlog_2n)$
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容