数据结构部分内容总结

1.快速排序:O(N*log2N)
(1)随机选择一个基准数,比如选择第一个数。
(2)从左边开始遍历,找比基准数大的数;从右边开始遍历,找比基准数小的数。
(3)找到后交换这两个数,然后继续遍历。
(4)如果左右两边走到一起,即遍历到了同一个数,将这个数与基准数交换。
(5)此时基准数落位正确,对于基准数左边和右边的数,重新开始上述过程。
2.冒泡排序:O(N2)
在这里插入图片描述
(1)比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。
(3)针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。
(4)持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。
*以上两种属于交换排序
3.选择排序(直接选择):O(N2)
在这里插入图片描述
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在这个待排序序列(每次的长度都减1)的起始位置,直到全部待排序的数据元素排完。选择排序就是对数组中的元素进行比较选择,然后直接放置在排序后的位置。
4.插入排序:O(N2)
要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。
(1)直接插入
1)待排序的数在最后一位。
2)将待排序的数存入一个临时变量中,然后向前遍历,如果前一位大于待排序的数,则这个数向后移一位。

在这里插入图片描述

(2)二分插入排序
1)二分法查找
A.从数组中间元素开始搜索,若该元素为目标元素,则结束,否则执行下一步。
B.若目标大于/小于中间元素,则在相应的区域内查找,然后重复A。
C.若某一步数组为空,则表示找不到该元素。
2)排序
经过二分法查找找到该数所在位置,然后将该数插入这个位置。
(3)希尔排序:O(N^1.25)不稳定
在这里插入图片描述
希尔排序意在减少直接排序中的数字移动次数,通过设置一个间隔,每次进行比较的都是间隔的数字。
比如说如图:
第一次的间隔是5,则可以将数字分为5组,每一组两个数字,将这两个数字进行比较,逆序就交换。这样我们第一次排序就完成了。
这时候的数组肯定还是存在许多的逆序对,所以我们需要将间隔缩小,在进行比较。如图,这时候间隔变成了3,也就是可以将4个数字分为一组比较,这时候可以使用直接插入排序的思想,在组内进行直接插入排序比较。只是跨度为间隔数而不是1了。
之后以此类推,直到间隔为1的时候,这时候就直接是直接选择排序了。
这里的稳定性意思是,拿选择排序举例子。选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
在这里插入图片描述
5.堆排序:
 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。(根节点的值是最大的)如下图:
在这里插入图片描述
同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子
在这里插入图片描述
该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] (最大堆)
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] (最小堆)
ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤:
堆排序基本思想及步骤
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
a.假设给定无序序列结构如下
在这里插入图片描述
2.此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。
在这里插入图片描述
3.找到第二个非叶节点4,由于[4,9,8]中9元素最大,4和9交换。
在这里插入图片描述
这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。
在这里插入图片描述
此时,我们就将一个无需序列构造成了一个大顶堆。
步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。
a.将堆顶元素9和末尾元素4进行交换
在这里插入图片描述
b.重新调整结构,使其继续满足堆定义
在这里插入图片描述
c.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8.
在这里插入图片描述
后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
在这里插入图片描述
再简单总结下堆排序的基本思路:
  a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;升序大顶堆,降序小顶堆。
  b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
  c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
https://www.cnblogs.com/chengxiao/p/6129630.html
6.二叉树:
(1)自由树
自由树是一个连通的,无回路的无向图。
令G=(V,E)为一个无向图。下面的表述是等价的。

  1.    G是自由树。
    
  2.    G中任意两个顶点由唯一一条简单路径得到。
    
  3.    G是连通的,但从E中去掉任何边后得到的图都是非连通的。
    
  4.    G是无回路的,且|E|=|V|-1。
    
  5.    G是连通的,且|E|=|V|-1。
    
  6.    G是无回路的,但添加任何边到E中得到的图包含回路。
    

(2)二叉树
在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
二叉树的第i层至多有2^(i-1)个结点;
深度为k的二叉树至多有2k-1个结点;(等比数列1+2+4+…+2(k-1) = 2^k-1)。
对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。
树和二叉树的三个主要差别:

  1. 树的结点个数至少为1,而二叉树的结点个数可以为0;
  2. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;(结点的度:结点拥有的子树数目)
  3. 树的结点无左、右之分,而二叉树的结点有左、右之分。
    (3)满二叉树
    一棵深度为k,且有2^k-1个节点的树是满二叉树。
    另一种定义:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
    这两种定义是等价的。
    从树的外形来看,满二叉树是严格三角形的,大家记住下面的图,它就是满二叉树的标准形态:
    在这里插入图片描述
    性质:
  4.    如果一颗树深度为h,最大层数为k,且深度与最大层数相同,即k=h;
    
  5.    它的叶子数是: 2^(h-1)
    
  6.    第k层的结点数是: 2^(k-1)
    
  7.    总结点数是: 2^k-1 (2的k次方减一)
    
  8.    总节点数一定是奇数。
    
  9.    树高:h=log2(n+1)。
    

(4)完全二叉树
完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h 层所有的结点都连续集中在最左边,这就是完全二叉树。
(大家好好理解一下上面两个定义,是等价的~~)
满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
下面是完全二叉树的基本形态:
在这里插入图片描述
完全二叉树的性质:

  1.    深度为k的完全二叉树,至少有2^(k-1)个节点,至多有2^k-1个节点。
    
  2.    树高h=log2n + 1。
    

在这里插入图片描述
7.数组和链表的区别
数组:顺序存储结构,访问方便,根据索引即可,删除添加元素难。
链表:链式存储结构,相互指向,删除添加元素容易,访问难。
从逻辑结构上来看,数组必须实现定于固定的长度,不能适应数据动态增减的情况,即数组的大小一旦定义就不能改变。当数据增加时,可能超过原先定义的元素的个数;当数据减少时,造成内存浪费;链表动态进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。
从内存存储的角度看;数组从栈中分配空间(用new则在堆上创建),对程序员方便快速,但是自由度小;链表从堆中分配空间,自由度大但是申请管理比较麻烦。
从访问方式类看,数组在内存中是连续的存储,因此可以利用下标索引进行访问;链表是链式存储结构,在访问元素时候只能够通过线性方式由前到后顺序的访问,所以访问效率比数组要低。
8.栈与队列
栈:先进后出的访问方式的存储空间,提供push和pop指令来操作栈段的数据。
队列:只允许在表的前端(队头)进行删除操作,在表的后端进行插入操作。先进先出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值