码迷,mamicode.com
首页 > 其他好文 > 详细

疯狂/缓慢补数据结构1

时间:2018-07-22 20:54:40      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:分块   最短路   常见   输出   最好   递归   集合   第一个   广度   

串,表,队,栈,KMP。

二叉树,遍历,哈夫曼。

图,DFS,BFS。

最短路径,最小生成树,拓扑排序。

树表的查找,散列表的查找。

线性表查找

排序,内部,外部。、

next为1加前面后缀个数

(1)二叉树性质

1.节点总数为叶子加度为2加度为1

2.叶子为度2加1

 

 

(1)基本知识

1.储存结构

【1】邻接矩阵

一个二维数组,连通就记为1.

【2】邻接表

对于每个节点,把相邻的节点接成一个表。

(2)遍历

1,深度优先

2,广度优先

(3)应用

1.普利姆

先随便挑一个点,然后找一下最短的路,把目的计入集合。然后再次对集合进行相同操作,找过的点记为无限大。n方

2.克鲁斯卡尔

先记下一个边的状态数组,a[x]=x;表示他们都不联通,如果联通了就把顶点改成一样的。

记下边的信息,9=(权,顶点),然后排列好,从开头检查边是否联通,没联通就改成联通,要不就跳过。

一般求稀疏,时间为elog2e

3.迪杰斯特拉

从一个原点开始,检测他到周围点的路程,并标在点上。然后选取距离最短的那个点,检测他周围的点的距离,并把从原点经过他到周围点的总路程记录在周围的点上,然后选取联通线路旁最近的点,以此类推。n方

(4)拓扑排序

1.AOV网

输出没有前驱的点,然后在图里删除他,不断这么循环

如果还剩点,那就是图中有环。

2AOE网

最短时间是最长路径长度,叫关键路径,关键路径上的所有活动都是关键活动,最早开始时间是最长路径,

查找。

(1)分块查找

(2)二叉排序树

每个节点的左面都比他小,右面都比他大。

找的时候比他小去左面,比他大去右面。

1插入:存在了的话就不插了

先把这个值的孩子赋为空。

如果向下没有了的话,比上一个小就插到左面,大就插到右面。

如果有的话递归调用自己,大就接右面的,小就接左面的。

2删除:叶子就直接删除

缺个子树的就上移子树

要不就用他的左子树的最右下子树替换。

3.平衡二叉树

平衡因子是左右子树的深度之差,绝对值大于2就不平衡

左左:中间当轴右旋。

左右:把中间按下去的左旋,然后中间当轴的右旋。

右边相反。

(3)散列表

最常见是项数除一个数然后取余。

处理冲突的方法:

1.尝试从1开始不断加数再取余,或加上增量的平方取余。

2.用链表,直接插入。

 

一.内部排序

(1)插入排序

1.直接插入排序

就是读的时候直接比较然后插入。下面是从小到大排列,函数传入一个头部为空的顺序表。

从后面开始,比一个移一位。

#include<stdio.h>
void b(int lenth,int *a);
int main (void)
{
    int a[6]={0,2,3,6,5,4};int cou1=0;
    b(6,a);
    for(cou1=0;cou1<6;cou1++)
        printf("%d",a[cou1]);
    return 0;
}
void b(int lenth,int *a)
{
    int cou1=0,cou2=0;
    for(cou1=2;cou1<lenth;cou1++)//从2开始
    {
        if(a[cou1-1]>a[cou1])//如果他的上一个大于他的话
        {
            a[0]=a[cou1];//在0存下他
            for(cou2=cou1;a[0]<a[cou2-1];cou2--)//当他小于他的下一个时,把他的下一个移后一位。
            {
                a[cou2]=a[cou2-1];
            }
            a[cou2]=a[0];
        }
    }
}

  稳定,时间o(n方),空间o(1)。

2.折半插入排序

就是把插入排序的顺序查找部分改为2分法查找。

#include<stdio.h>
void b(int lenth,int *a);
int main (void)
{
    int a[6]={0,2,3,6,5,4};int cou1=0;
    b(6,a);
    for(cou1=0;cou1<6;cou1++)
        printf("%d",a[cou1]);
    return 0;
}
void b(int lenth,int *a)
{
    int cou1=0,cou2=0;
    int low,high,m;
    for(cou1=2;cou1<lenth;cou1++)//这是从小到大
    {
        if(a[cou1-1]>a[cou1])
        {
            a[0]=a[cou1];
             low=1;high=cou1-1;//确定查找范围
            while(low<=high)//不断缩小范围直到下限大于上限,说明a[m]大于他而a[m-1]小于他。
            {
                m=(low+high)/2;//m为向下取整,所以是前面表的表尾,在从小到大排中,为小表表尾,如果大了则上限取小表倒数第二项,因为m比过了。如果小了则下线取大表第一个,为m+1;
                if(a[0]<a[m])//这个元素比他大,就把上限减一半再减一
                    high=m-1;
                else
                    low=m+1;//要不就提高下限
            }
                 //最后一次一定是high大于他,low小于她,然后由于惯性他们互换。 for(cou2=cou1-1;cou2>=low;--cou2)//最后low为插入位置 a[cou2+1]=a[cou2]; a[low]=a[0]; } }

  稳定,时间n方,空间1;

  3希尔排序

选个间隔数,把数据分为多组,分别使用插入排序。然后选更小的间隔分组,插入排序。最后取间隔为1;

不稳定。

(2)交换排序

1.冒泡排序

稳定,为n方。

2.快速排序。

随便选个数,然后比他小的放左边,比他大的放右边,对两个新表递归重复这一过程。

 不稳定,时间最好nlog2n,最坏n方。空间最好log2n,最坏n。

(3)选择排序

1。树形选择排序

兄弟之间两两比较,胜者的兄弟之间再两两比较。最后选出第一名,然后把第一名赋最差的值,重复这过程选第二名。

2.堆排序

堆是二叉树线性化,第个i值的父节点为(i – 1) / 2,它的左右子结点下标分别为2 * i + 1和2 * i + 2。

这样就把一个数列转化为多个子数列。然后对子数列进行选择排序。

插入:把元素插入到数组最后一项,然后对他所在的数列进行选择排序。

删除:只能删除第一个。就是把这个整个数列最末尾的数放到第一个的位置上,然后进行选择排序。要判断节点的子节点哪个是最好的,然后与他交换。

堆化数组:叶子节点不用排,所以我们要从最后一个不是叶子节点的节点(n/2向小取整)开始向上直到0的堆排序。

不稳定,最坏nlog2n。1

(3)归并排序

有点像逆希尔。就是将数列的元素分为越来越大的有序表。

两个表合并是申请一个两个表那么大的数组,然后在两个数组里选着往里放。

传入左右端点low,high

(如果表的low等于high,返回)

求出中间值

对右表递归

对左表递归

合并两个表

稳定,nlog2n。n.

 

疯狂/缓慢补数据结构1

标签:分块   最短路   常见   输出   最好   递归   集合   第一个   广度   

原文地址:https://www.cnblogs.com/pornhub/p/9245418.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!