【数据结构】期中考试一把梭(通宵版上)

简介: 【数据结构】期中考试一把梭(通宵版上)

前言


红中(Hong_zhong)
CSDN内容合伙人、2023年新星计划web安全方向导师、
吉林师范大学网安大一的一名普通学生、摸鱼拿过大挑校二、
华为MindSpore截至目前最年轻的优秀开发者、IK&N战队队长、
阿里云专家博主、华为网络安全云享专家、腾讯云自媒体分享计划博主、


链表


链表的初步印象


链表,即链式存储结构。

DATA是咱自定义的数据类型,NEXT为指向下一个链表的指针。当我们访问NEXT时,被引导到链表下一个节点的位置。


抽象点就类似于火车车厢

一节车厢前面是节点,后面是指针,中间连接即指针指向的位置。


链表与数组的差别


那这玩意相较于数组,插入删除等操作变得更加容易。


为啥这么说捏?


打个比方,现在有这样一个数组:


[1,2,3,4,5,6,7,8]


我想在“1”之后插入一个”9“,那就意味着”1“之后的所有元素都需要向后挪一位,然后再整一块新的内存空间,把”9“塞里。麻烦死


但如果是链表,先抽象说说,想在火车车厢间加一节,只需要把车厢之间的链子解开,后面的先挂到新车厢上,前面再挂,完事了。


不需要整体/大部分数据去调整,改变指针所指向的DATA就行了,确实方便。


不过这玩意占用相较于数组大了不只一点


链表常见类型


单链表、双链表、循环单链表

图片来源:一口气搞懂「链表」,就靠这20+张图了 - 知乎


单链表


单链表概念的代码表述:

typedef struct Node{//定义单链表的结点类型
    int data;//数据域,随便写哪种类型都可以
    struct Node *next;//指针域
    }Node,*LinkList;//Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型


链表的初始化


LinkedList listinit(){
    Node *L;
    L=(Node*)malloc(sizeof(Node));//申请开辟空间
    if(L==NULL){
        printf("申请失败");//判断是否开辟成功
    }
    L->next=NULL;//指针指向NULL
}

申请开辟空间那块咱也不到是啥,背下来就完了。


头插法


这玩意其实挺好理解的

这是一个节点,头插即从头插。假设我再来一个节点,即可以把新节点的指针指向原节点的DATA处。原节点始终排在后面,即到最后整条链表的顺序为倒序。


代码实现:

LinkedList LinkedListCreate(){
    Node *L;
    L=(Node *)malloc(sizeof(Node));
    L->next=NULL;
    int x;//x为链表中的数据
    while (scanf("%d",&x!=EOF)){
        Node *p;//定义p的指针域
        p=(Node *)malloc(sizeof(Node));//申请空间
        p->data=x;//将x赋给p节点的数据域
        p->next = L->next;//将头指针所指向的下一个结点的地址,赋给新创建结点的next 
        L->next = p;//将新创建的结点的地址赋给头指针的下一个结点
       }
    return L;
}


尾插法


尾插法同样的理解,原节点的指针指向新节点的DATA域。


不解释,直接写代码:

LinkedList LinkedListCreate(){
    Node *L;//申请指针域
    L=(Node *)malloc(sizeof(Node));//申请头节点空间
    L->next=NULL;//初始化一个空链表
    Node *r;
    r=L;//r始终指向尾节点,开始时指向头节点
    int x;//x为链表DATA中的数据
    while (scanf("%d",&x)!=EOF){
        Node *p;//申请指针域
        p=(Node *)malloc(sizeof(Node));//申请新的节点
        p->data=x;
        r->next=p;
        r=p;//r始终指向尾节点
    }
    r=next=NULL;
    return L;
}


修改


LinkedList LinkedListReplace(LinkedList L,int a,int b) {
    Node *p=L->next;//定义指针域指向节点指针指向
    int i=0;
    while(p){
        if(p->data==a){//如果p节点数据域中的值等于a
            p->data=b;//将p节点数据域中的值a改成b
        }
        p=p->next;//节点指针依旧指向后面
    }
    return L;
}


插入


LinkedList LinkedListInsert(LinkedList L,int i,int x) {
    Node *pre;                      //pre为前驱结点
    pre = L;
    int tempi = 0;
    for (tempi = 1; tempi < i; tempi++) {
        pre = pre->next;                 //查找第i个位置的前驱结点
    }
    Node *p;                                //插入的结点为p
    p = (Node *)malloc(sizeof(Node));
    p->data = x;//给p赋个值
    p->next = pre->next;//将前驱节点之前指向的地址赋给插入节点并让其指向
    pre->next = p;//将前驱节点指针指向引导到新节点头上
    return L;
}


删除


LinkedList LinkedListDelete(LinkedList L,int x) {
    Node *p,*pre; //pre为前驱结点,p为查找的结点。
    p = L->next;
    while(p->data != x) {//查找值为x的元素
        pre = p;
        p = p->next;
    }
    pre->next = p->next;//删除操作,将其前驱next指向其后继。
    free(p);//free函数释放掉
    return L;
}


习题


第一题、第二题:随便举几个推值代数。


第三题直接带。第四题看图嘛

第五题:涉及概念


存储密度,在计算机中是指结点数据本身所占的存储量和整个结点结构所占的存储量之比,计算公式:存储密度 = (结点数据本身所占的存储量)/(结点结构所占的存储总量)


第六题:顺序表简单了解下

第十/十一题:带头单链表就是指针域指向空,不带头就自己是空。


感觉没啥好讲的,直接填空看看

简单过过知识点,没啥难点



原理/概念


之前学过Python的栈,简单聊聊原理,看看代码实现,做点题就过了。


刚开始书架是空的,我们放里面一本《母猪的产后护理》,好,栈内已经有一本书了


现在我们再往里放一本《我是如何因为CTF毁掉自己人生的》,现在栈内有两本书

栈这个东西类似于一个桶形书架。


如果我们想看《母猪的产后护理》,又不能直接从栈底抽出来,就只能先把《我是如何因为CTF毁掉自己人生的》拿出来,再得到我们想要的书。


那这里的顺序就是一个栈的特性:先进后出


反正我就记得这一个,再说也说不了啥了,看代码实现。


代码实现


不难


置空栈


void InitStack(SeqStack *S){
    S->top=-1;
}


判定栈空否


int EmptyStack(SeqStack * S){
    if (S->top<0)
        return 1;//为空栈
    else
        return 0;//不为空栈
}


进栈


int Push(SeqStack * S,DataType x){
    if (S->top>=MAXSIZE-1)//
    {    printf("栈满不能进栈");
         return 0;
    }
    S->top++;//移动栈顶指针
    S->data[S->top]=x;//元素x进栈
    return (1);
}


出栈


和入栈差不多嘛

int Push(SeqStack * S){
    if (S->top《=MAXSIZE-1)//
    {    printf("栈空不能出栈");
         exit(0);
    }
    x=S->data[S->top]//将栈顶值保存至x
    S->top--;//移动栈顶指针
    return (x);
}


读取栈顶元素


DataType GetTop(LinkStack * Top)
{
    if (Top == NULL)
        printf("\n栈空");
    else
        return Top->data;
}

完整代码及示例:

#include<bits/stdc++.h>
using namespace std;
#define MaxSize 100 //定义栈中元素的最大个数
typedef struct SqStack{
    int data[MaxSize]; //存放栈中的元素
    int top; //栈顶指针
}SqStack;
//初始化
void InitStack(SqStack &S){
    S.top = -1;
}
//判栈空
bool Empty(SqStack S){
    if(S.top == -1){
        return true;
    }else{
        return false;
    }
}
//入栈
void Push(SqStack &S, int x){
    if(S.top == MaxSize-1){
        cout<<"栈满"<<endl;
        return;
    }
    S.data[++S.top] = x;
}
//出栈
void Pop(SqStack &S, int &x){
    if(S.top == -1){
        cout<<"栈空"<<endl;
        return;
    }
    x = S.data[S.top--];
}
//读栈顶元素
int GetTop(SqStack S){
    if(S.top == -1){
        cout<<"栈空"<<endl;
        return -1;
    }else{
        return S.data[S.top];
    }
}
//遍历栈
void PrintStack(SqStack S){
    while(S.top != -1){
        cout<<S.data[S.top--]<<" ";
    }
    cout<<endl;
}
//销毁栈
void DestroyStack(SqStack &S){
    S.top = -1;
}
int main(){
    SqStack S;
    InitStack(S);
    Push(S,1);//入栈
    Push(S,2);
    Push(S,3);
    Push(S,4);
    cout<<"栈顶元素为:"<<GetTop(S)<<endl;
    cout<<"出栈顺序为:";
    PrintStack(S);
    int x;
    Pop(S,x);
    cout<<x<<"出栈"<<endl;
    cout<<"栈中剩余元素:";
    PrintStack(S);
    Pop(S,x);
    cout<<x<<"出栈"<<endl;
    cout<<"栈中剩余元素:";
    PrintStack(S);
    if(!Empty(S)){
        cout<<"当前栈不为空"<<endl;
    }else{
        cout<<"当前栈为空"<<endl;
    }
    return 0;
}

来自栈——栈的定义及基本操作(初始化、判空、进栈、出栈、遍历栈、销毁栈等)_薛定谔的猫ovo的博客-CSDN博客w


习题


第一题特性,第二题栈顶。


链栈虽然没说,但是通过链表的学习也差不多了。


第三题有点问题,第四题先把值保存在x里,然后改指针域。

目录
相关文章
|
3月前
|
算法 开发者 计算机视觉
燃爆全场!Python并查集:数据结构界的网红,让你的代码炫酷无比!
在编程的世界里,总有一些数据结构以其独特的魅力和高效的性能脱颖而出,成为众多开发者追捧的“网红”。今天,我们要介绍的这位明星,就是Python中的并查集(Union-Find)——它不仅在解决特定问题上大放异彩,更以其优雅的设计和强大的功能,让你的代码炫酷无比,燃爆全场!
45 0
|
6月前
|
存储 算法 程序员
庆祝吧!掌握Python并查集,数据结构难题将不再是你的拦路虎!
【7月更文挑战第17天】并查集,一种数据结构,用于不相交集合的合并与查询,尤其适合解决图的连通性问题。通过Python实现,使用列表存储元素的父节点以判断集合关系。基本操作包括查找(确定元素集合)和合并(组合集合)。示例展示了如何用并查集配合Kruskal算法构建最小生成树。掌握并查集能高效处理复杂问题,优化后的查找和合并操作接近O(1)复杂度,是解决算法挑战的利器。
47 4
|
8月前
|
算法
重拾数据结构和算法——脑图
重拾数据结构和算法——脑图
118 0
24张图,九大数据结构安排得明明白白
数据结构想必大家都不会陌生,对于一个成熟的程序员而言,熟悉和掌握数据结构和算法也是基本功之一。数据结构本身其实不过是数据按照特点关系进行存储或者组织的集合,特殊的结构在不同的应用场景中往往会带来不一样的处理效率。
|
机器学习/深度学习 算法 C++
数据结构刷题:第四天
数据结构刷题:第四天
100 0
数据结构刷题:第四天
|
存储 机器学习/深度学习 数据可视化
一篇文章讲清python开发必懂的8种数据结构
一篇文章讲清python开发必懂的8种数据结构
115 0
一篇文章讲清python开发必懂的8种数据结构
|
存储 算法 小程序
深度剖析数据在内存中的存储(修炼内功~吊打面试官)
深度剖析数据在内存中的存储(修炼内功~吊打面试官)
154 0
深度剖析数据在内存中的存储(修炼内功~吊打面试官)
数据结构上机实践第二周项目2- 程序的多文件组织
数据结构上机实践第二周项目2- 程序的多文件组织
114 0
数据结构上机实践第二周项目2- 程序的多文件组织
|
存储 算法 Serverless
97. 一网打尽面试中常被问及的8种数据结构(二)
97. 一网打尽面试中常被问及的8种数据结构(二)
95 0
97. 一网打尽面试中常被问及的8种数据结构(二)
|
存储 算法 搜索推荐
97. 一网打尽面试中常被问及的8种数据结构(三)
97. 一网打尽面试中常被问及的8种数据结构(三)
135 0
97. 一网打尽面试中常被问及的8种数据结构(三)

热门文章

最新文章

相关实验场景

更多