就是那个数据结构

少年的肩应担负起草长莺飞和清风明月,女孩的眼应藏下星辰大海和万丈光芒

晚安之后,有时候想你想得睡不着,有时候不想你睡不着


目录

数据结构的基本概念

线性表

顺序表

单链表

循环单链表

双向循环链表

顺序栈


数据结构的基本概念

待写。。。

线性表

顺序表

有n个元素的顺序表,第i个位置上插入一个元素需要移动表中n-i+1个数据元素,删除第i个文字上的数据元素需要移动表中n-i个元素

1.数据集合的描述

typedef struct
{
    DataType list[Maxsize];
    int size;
}SeqList;

2.初始化

void ListInitate(SeqList *L)
{
    L->size=0;
}

3.求当前数据元素个数

int ListLength(SeqList *L)
{
    return L->size;
}

4.插入数据元素

int ListInsert(SeqList *L,int i,Datatype x)
{
    int j;
    if(L->size==Maxsize)
        return 0;
    else if(i<0 || i>Maxsize)
        return 0;
    else{
        for(j=L->size-1;j>=i;j--)
            L->list[j+1]=L->list[j];
        L->list[i]=x;
        L->size+=1;      //元素个数加一不要忘记
        return 1;
    }
}

5.删除数据元素

int ListDelete(Sqlist *L,int i,DataType *x)
{
    int j;
    if(L->size==0)
        return 0;
    else if(i<0||i>Maxsize)
        return 0;
    else{
        *x=L->lisst[i]   //将被删除的元素保存到x中
        for(j=i;j<L->size;j++)
            L->list[j]=L->list[j+1];
        L->list[j]=NULL;
        L->size--;
        return 1;
    }
}

6.取出数据元素

int ListGet(SeqList L,int i,DataType *x)
{
    //此处省略对i不合法的判断
    *x=L->list[i];
    return 1;
}

向数据表中插入数据是,平均移动次数为n/2

删除一个元素平均移动次数为n-1/2

插入与删除操作时间复杂度均为O(n),其余均为O(1)

单链表

1.单链表结点

typedef struct Node
{
    DataType data;
    struct Node *next;
}SLNode;

2.初始化

void ListInitiate(SLNode **head)
{
    *head=(SLNode *)malloc(sizeof(SLNode));
    (*head)->next=NULL;
}

3.求当前数据元素的个数

int ListLength(SLNode *head)
{
    int size=0;
    SLNode *p=head;
    while(p)
    {
        size++;
        p=p->next;
    }
    return size;
}

4.在第i个数据元素前插入数据元素x

int ListInsert(SLNode *head,int i,DataType x)
{
    SLNode *p=head,*q;
    int j;
    while(p && j<=i-1)//找到i所在元素的前一个元素
    {
        p=p->next;
        j++;
    }
    if(j+1 !=i) //判断i是否合法
        return 0;
    q=(SLNode *)malloc(sizeof(SLNode));
    q->data=x;
    q->next=p->next;
    p->next=q;
    return 0
}

5.删除i位置的元素

int ListDelete(SLNode *head,int i,DataType *x)
{
    SLNode *p=head,*q;
    int j;
    //此处省略查找i元素之前的结点并判断i是否合法的代码
    *q=p->next
    *x=q->data;
    p->next=p->next->next;
    free(q); //释放空间不要忘记
    return 1;
}

6.取数据元素,过程同5

7.销毁单链表,while循环,调用free()即可;

循环单链表

初始化时 *head->next=head

遍历时 *p->next=*head结束遍历

双向循环链表

结构体定义中除了DataType data;还有前后指针struct Node *next;struct Node *prior;

初始化时head=(Node *)malloc(sizeof(Node));head->next=head;head->prior=head;

插入和删除就直接画出图形照着写就是

后进先出是LIFO,先进先出是FIFO

顺序栈

存储结构用数组

typedef struct
{
    DataType stack[MaxStackSize];
    int top;//栈顶位置
}SeqStack;

初始化就是将栈顶元素位置即s->top设置为0,注意此处为0,王道是-1

判断是否非空就是判断top是否小于等于0,是就是空,反之不空

入栈就是将数据元素存入数据顺序栈中,栈顶指针加一

s->stack[s->top]=x;
s->top++;
//或者合并写:
s->stack[s->top++]=x;

出栈就是将栈顶指针减一

取栈顶元素就是数组取值操作,这里需要注意,top代表的是数据元素的个数,取值时要记得减一

*x=s->stack[s->top-1];

链式堆栈

链式堆栈的插入和删除操作都在链表表头进行的,且是带有头结点的链表

栈顶元素就是head->next所指向的元素

算术表达式求值

后缀表达式的求法

x1表示当前栈顶元素,x2表示当前扫描到的元素

比较优先级:

x1>x2:x1出栈并加入后缀表达式,将x1变为新的栈顶元素,继续比较

x1<x2:x2进栈并读取下一个元素

x1=x2且x1=="(",x2==")":将x1出栈继续读取下一个元素

x1=x2="#":算法结束

优先级的规则:

不同级别:"(" >乘除>加减> ")"

同一级别:栈顶>扫描到的元素

串的下标是从0开始的,比如插入或者删除等操作中从第i个字符开始,i字符数组的下标

字符串比较比的是ascii

BF算法

设主串长为n子串长为m,最好情况下时间复杂度为O(m),最坏情况下时间复杂度为O(mn)

int BFIndex(DString S,int start,Dstring T)//查找成功则返回子串在主串中的位置
{
    int s=start;s,t=0,pos;
    while(s<S->length && t<T->length)
    {
        if(S->str[s]==T->str[t])
        {
            s++;
            t++;
        }else{
            s=s-t+1;
            t=0;
        }
    }
    if(t==T->length)
        pos=s=T->length;
    else
        pos=-1;
    return pos;
}

KMP算法

计算next[j]

void GetNext(DString T,int next[])
{
    int j=1,k=0;
    next[0]=-1;
    next[1]=0;
    while(j<T->length-1)
    {
        if(T->str[j]==T->str[k])
        {
            next[j+1]=k+1;
            j++;
            k++;
        }
        else if(k==0)
        {
            next[j+1]=0;
            j++;
        }
        else
            k=next[k];
    }
}

数组

无向图中有n个顶点e条边,则对应邻接表中有n个表头结点和2e个表结点

有向图中有n个顶点e条边,则对应邻接表中有n个表头结点和e个表结点

连通图是指无向图中任意一对顶点都存在路径。

设某连通图中有n个顶点则该连通图中至少n-1条边

强连通图是指有向图中任意一对顶点都存在路径

设某强连通图中有n个顶点则该强连通图中至少n条边

B_树

m阶B_树就是m阶平衡m叉树

特点

1.树中每个结点至多有m个孩子结点,除根节点之外,其他结点至少有 m/2(向上取整) 个孩子结点

2.每个节点中至多有m-1个关键字,非根结点至少m/2(向上取整) -1个关键字,根结点可以有一个关键字

2.若根节点不是叶子结点则根节点至少有两个孩子结点

3.所有叶子结点都在同一层上

比如3阶B_树,每个结点最多3个孩子结点,每个结点中最多个3-1=2关键字,除根节点为至少3/2=1个结点

插入

每个节点中至多有m-1个关键字

情况1:待插结点中关键字满足n<m-1  

     操作:直接插入

情况2:待插结点中有m-1个关键字

     操作:分裂结点:以中间关键字为界,把结点分成两个结点并把中间元素的关键字向上插入到双亲结点上,若双亲结点已满,则继续分裂双亲结点

删除、

每个节点中至多有m-1个关键字,非根结点至少 m/2-1 个关键字

一、删除叶子结点

情况1:待删结点的关键字个数n>=m/2

操作:直接删除

情况2:待删结点关键字个数n=m/2-1,并且左兄弟或右兄弟关键字大于m/2-1

操作:问左兄弟或右兄弟借

以左兄弟为例:将待删结点的左兄弟中最大的关键字移动到双亲中,同时把双亲中大于上移关键字的关键字下移到待删元素的结点中,将待删元素给删除

情况3:待删结点关键字个数n=m/2-1,并且左兄弟或右兄弟关键字等于m/2-1

操作:合并结点

把待删结点与其左(右)兄弟结点以及双亲结点上分割二者的元素合并成一个结点,然后再把待删元素删除

二、删除非叶子结点

操作:找、复制、删

1.找到右指针所指的子树中最小的关键字

2.将最小的关键字的值复制到待删元素上

3.以右指针所指结点为根节点,删除关键字等于最小关键字的数据元素

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值