24/07/11数据结构(6.1215)双链表实现-栈实现

像写单链表的一些功能接口一样,先来写一些双链表的接口熟悉一下它的主体框架:

#include<stdio.h>
#include<stdlib.h>

typedef int LDataType;

//双向带头循环链表的节点
typedef struct ListNode{
    LDataType _data;
    //指向下一个节点的起始位置
    struct ListNode* _next;
    //指向上一个节点的起始位置
    struct LIst* _prev;
}ListNode;

//双向带头循环链表
typedef struct List{
    struct ListNode* _head;
}List;

struct ListNode* createListNode(LDataType val){
    struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
    node->_data = val;
    node->_next = NULL;
    node->_prev = NULL;
}

void ListInit(List* lst){
    //空链表
    lst->_head = createListNode(0);
    lst->_head->_next = lst->_head->_prev = lst->_head;

}
//尾插 O(1) //给头的前面插一个数据ListInsert(lst, lst->_head, val);
void ListpushBack(List* lst, LDataType val){
    if (lst == NULL){
        return;
        struct ListNode* last = lst->_head->_prev;
        struct ListNode* newNode = createListNode(val);
        //_head ... last newNode
        last->_next = newNode;
        newNode->_prev = last;

        newNode->_next = lst->_head;
        lst->_head->_prev = newNode;
    }
}

//尾删://删除头的前一个节点 ListErase(lst, lst->_head->_prev);
void ListPopBack(List* lst){
    if (lst == NULL)
        return;
    //判断是否空链表
    if (lst->_head->_next == lst->_head)
        return;
    struct ListNode* last = lst->_head->_prev;
    struct ListNode* prev = last->_prev;

    free(last);

    lst->_head->_prev = prev;
    prev->_next = lst->_head;
}

void printList(List* lst){
    struct ListNode* cur = lst->_head->_next;
    while (cur != lst->_head){
        printf("%d", cur->_data);
        cur = cur->_next;
    }
    printf("\n");
}

//头插//ListInsert(lst,lst->_head->_next,val);
void ListPushFront(List* lst, LDataType val){
    if (lst == NULL)
        return;
    struct ListNode* next = lst->_head->_next;
    struct ListNode* newNode = createListNode(val);

    //_head, newNode, next
    lst->_head->_next = newNode;
    newNode->_prev = lst->_head;

    newNode->_next = next;
    next->_prev = newNode;
}

//头删//ListErase(lst,lst->_head->_next);
void ListPopFront(List* lst){
    if (lst == NULL || lst->_head  == lst->_head)
        return;
    struct ListNode* next = lst->_head->_next;
    struct ListNode* nextnext = next->_next;
    
    nextnext->_prev = next->_next;
    lst->_head->_next = nextnext;

    free(next);
    
}

void ListErase(List* lst, struct ListNode* node){
    //不能删除head节点
    if (lst == NULL || lst->_head == node)
        return;
    //prev, node, next
    struct ListNode* prev = node->_prev;
    struct ListNode* next = node->_next;

    prev->_next = next;
    next->_prev = prev;

    free(node);

}

void ListInsert(List* lst, struct ListNode* node, LDataType val){
    if (lst == NULL)
        return;
    struct ListNode* prev = node->_prev;
    struct ListNode* newNode = createListNode(val);

    //prev newNode node
    prev->_next = newNode;
    newNode->_prev = prev;

    newNode->_next = node;
    node->_prev = newNode;
}

//销毁
ListDestoty(List* lst){
    if (lst){
        if (lst->_head){
            struct ListNode* cur = lst->_head->_next;
            while (cur != lst->_head){
                struct ListNode* next = cut->_next;
                free(cur);
                cur = next;
            }

            free(lst->_head);
        }
    }
}

void test(){
    List lst;
    ListInit(&lst);
    ListPushFront(&lst, 5);
    printList(&lst);
    ListPushFront(&lst, 1);
    printList(&lst);
    ListPushFront(&lst, 2);
    printList(&lst);
    ListPushFront(&lst, 3);
    printList(&lst);
    ListPushFront(&lst, 4);
    printList(&lst);
    ListPopFront(&lst);
    printList(&lst);
    ListPopFront(&lst);
    printList(&lst);
    ListPopFront(&lst);
    printList(&lst);

    /*ListPopBack(&lst);
    printList(&lst);
    ListPopBack(&lst);
    printList(&lst);
    ListPopBack(&lst);
    printList(&lst);
    ListPopBack(&lst);
    printList(&lst);*/
}

int main(){

    test();
    system("pause");
    return 0;
}

顺序表和链表的区别和联系:

顺序表优劣:优:空间连续,支持随机访问,空间利用率高不容易造成内存碎片,尾插尾删效率高.

                   劣:1.中间或前面部分插入删除时间复杂度O(N) 2.增容的代价比较大:申请 拷贝 释放

链表的优劣(带头双向随机链表)

                优:1.任意位置插入删除时间复杂度O(1) 2.没有增容问题,插入一个开辟一个空间,任意位置插入删除效率高

                劣:以节点为单位存储,不支持随机访问,空间利用率低容易造成内存碎片

栈和队列

栈:一种特殊的线性表,其只允许固定在一端进行插入和删除元素操作.进行数据插入和删除操作的一端叫做栈顶,另一端称为栈底.栈中的数据遵守后进先出LIFO(last in first out)原则

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈,出数据也在栈顶

压栈操作的实现push--->从栈顶存入元素

        顺序表:可以把它看成是一个尾插操作

        链表:(双向带头循环链表)表头看做栈顶就是头插,表尾看做栈顶就是尾插

出栈操作pop--->从栈顶取出元素

        顺序表:表尾看做栈顶,把它看成尾删操作        

        链表:(双向带头循环链表)表头看做栈顶就是头删,表尾看做栈顶就是尾删

#include<stdio.h>
#include<stdlib.h>

typedef int STDataType;
//顺序表实现一个栈
typedef struct stack{
    STDataType* _data;
    int _size;
    int _capacity;
}stack;

void stackInit(stack* st){
    if (st == NULL)
        return;
    st->_data = NULL;
    st->_size = st->_capacity = 0;
}

void checkCapcacity(stack* st){
    if (st->_size == st->_capacity){
        int newCapcacity = st->_capacity == 0 ? 1 : 2 * st->_capacity;
        st->_data = (STDataType*)realloc(st->_data, sizeof(STDataType)* newCapcacity);
        st->_capacity = newCapcacity;
    }

}

//入栈
void stackPush(stack* st, STDataType val){
    if (st == NULL)
        return;
    checkCapacity(st);
    //尾插
    st->_data[st->_size++] = val;

}

//出栈
void stackPop(stack* st){
    if (st == NULL)
        return;
    if (st->_size > 0)
        st->_size--;
}

STDataType stackTop(stack* st){
    return st->_data[st->_size - 1];
}

int stackSize(stack* st){
    if (st == NULL)
        return 0;
    return st->_size;
}

void test(){
    stack st;
    stackInit(&st);
    stackPush(&st, 1);
    stackPush(&st, 2);
    stackPush(&st, 3);
    stackPush(&st, 4);
    for (int i = 0; i < 4; ++i){
        printg("%d", stackTop(&st));
        stackPop(&st);
    }
    printf("\n");
}

int main(){
    test();
    system("pause");
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/46362.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kylin系列(九)与 Hadoop 集成:Kylin 如何在 Hadoop 生态中运作

目录 1. Kylin概述 2. Hadoop概述 3. Kylin与Hadoop集成的架构 4. 实现Kylin与Hadoop的集成 4.1 安装和配置Hadoop 4.2 安装和配置Hive 4.3 安装和配置Kylin 4.4 构建多维数据立方体 4.5 实现实时数据处理 5. Kylin与Hadoop集成的优势 6. 总结 在大数据时代&#xf…

项目部署笔记

1、安全组需开放&#xff08;如果不开放配置nginx也访问不到&#xff09; 2、域名解析配置IP(子域名也需配置IP&#xff0c;IP地址可以不同) 3、如果出现图片获其他的文件找不到的情况请仔细检查一下路径是否正确 4、服务器nginx配置SSL证书后启动报错&#xff1a; nginx: […

巧用 VScode 网页版 IDE 搭建个人笔记知识库!

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 巧用 VScode 网页版 IDE 搭建个人笔记知识库! 描述&#xff1a;最近自己在腾讯云轻量云服务器中部署了一个使用在线 VScode 搭建部署的个人Markdown在线笔记&#xff0c;考虑到在线 VScode 支持终…

Python 数据清洗与预处理

Python 数据清洗与预处理 在数据科学和机器学习的项目中&#xff0c;数据清洗与预处理是至关重要的一步。无论数据来源如何&#xff0c;原始数据通常都是不完整、不一致、含有噪声的&#xff0c;甚至可能包含错误。为了从这些原始数据中提取有价值的信息&#xff0c;并进行有效…

Day05-filebeat常用的输出组件,logstash的输入输出组件及date,grok,geoip过滤插件实战案例

Day05-filebeat常用的输出组件&#xff0c;logstash的输入输出组件及date&#xff0c;grok&#xff0c;geoip过滤插件实战案例 1、使用filebeat采集docker日志2、filebeat的input类型之filestream实战案例2.1 课堂练习案例2.2 将数据写入到本地文件案例2.3 写入数据到ES集群2.4…

Windows Server 2012 R2 Update 出现错误 80072EFE

解决方案一 错误代码 80072EFE 表示与服务器的连接异常终止。请确保没有防火墙规则或代理阻止 Microsoft 下载 URL。 您还可以尝试以下操作&#xff1a; 单击“开始”&#xff0c;然后单击“运行”。 在“打开”框中键入 cmd 在命令提示符下键入“net stop wuauserv”&#…

《昇思25天学习打卡营第04天|qingyun201003》

日期 心得 从中认识到什么是数据转换&#xff0c;如何进行数据转换&#xff1b;对于数据转换应该如何理解。同时对于数据转换的代码有了深层次的理解。对于数据增强、转换、归一化有了明确的认知。 昇思MindSpore 基础入门学习 数据转换 (AI 代码解析) 数据变换 Transforms …

使用Python和MediaPipe实现手势控制音量(Win/Mac)

1. 依赖库介绍 OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它包含了数百个计算机视觉算法。 MediaPipe MediaPipe是一个跨平台的机器学习解决方案库&#xff0c;可以用于实时人类姿势估计、手势识…

EXSI 实用指南 2024 -编译环境 Ubuntu 安装篇(二)

1. 引言 在当今的虚拟化领域&#xff0c;VMware ESXi 是备受推崇的虚拟化平台&#xff0c;广泛应用于企业和个人用户中。它以卓越的性能、稳定的运行环境和丰富的功能&#xff0c;为用户提供了高效的硬件资源管理和简化的 IT 基础设施维护。然而&#xff0c;如何在不同操作系统…

LeetCode Day8|● 344.反转字符串(原地) ● 541. 反转字符串II(i可以大步跨越) ● 卡码网:54.替换数字(ACM模式多熟悉熟悉)

字符串part01 day8-1 ● 344.反转字符串整体思路代码实现总结 day8-2 ● 541. 反转字符串II整体思路代码实现总结 day8-3 ● 卡码网&#xff1a;54.替换数字题目解题思路代码实现总结 day8-1 ● 344.反转字符串 整体思路 字符串和数组的思路差不多 原地操作 代码实现 class…

非常好的新版网盘系统,是一款PHP网盘与外链分享程序,支持文件预览

这是一款PHP网盘与外链分享程序&#xff0c;支持所有格式文件的上传&#xff0c; 可以生成文件外链、图片外链、音乐视频外链&#xff0c;生成外链同时自动生成相应的UBB代码和HTML代码&#xff0c; 还可支持文本、图片、音乐、视频在线预览&#xff0c;这不仅仅是一个网盘&a…

算法思想总结:字符串

一、最长公共前缀 . - 力扣&#xff08;LeetCode&#xff09; 思路1&#xff1a;两两比较 时间复杂度mn 实现findcomon返回两两比较后的公共前缀 class Solution { public:string longestCommonPrefix(vector<string>& strs) {//两两比较 string retstrs[0];size…

MySQL里的累计求和

在MySQL中&#xff0c;你可以使用SUM()函数来进行累计求和。如果你想要对一个列进行累计求和&#xff0c;可以使用OVER()子句与ORDER BY子句结合&#xff0c;进行窗口函数的操作。 以下是一个简单的例子&#xff0c;假设我们有一个名为sales的表&#xff0c;它有两个列&#x…

Python接口自动化测试框架(工具篇)-- 接口测试工具RobotFramework

文章目录 一、前言二、[robotframework](https://robotframework.org/)为什么要选择使用RF框架环境搭建测试用例编写我的第一个接口测试用例小结一、前言 这篇文章是后面临时加的戏码,原本计划是将一个个能做接口测试的工具,全都给梳理一遍,但是题主有疑问,光一篇文章能让…

Android之间互传消息之ServerSocket,Android服务端接收Socket发送的TCP

Android之间在在局域网下互传消息&#xff0c;咱就不用走云服务器了吧&#xff0c;让俩安卓设备&#xff0c;自己传呗 方式1 通过在安卓设备上搭建Web服务器接收数据&#xff0c;可参考 Android使用AndServer在安卓设备上搭建服务端(Java)(Kotlin)两种写法 方式2 本文章&…

Open3d入门 点云中的重要概念

点云是由一组三维空间中的点组成的数据结构&#xff0c;常用于计算机视觉、3D建模和地形图生成等领域。每个点包含空间坐标&#xff08;x, y, z&#xff09;以及其他属性&#xff08;如颜色、密度等&#xff09;。以下是一些重要的点云概念&#xff1a; 1. 体素 (Voxel) 体素…

容器安全最佳实践和工具

容器安全最佳实践和工具 什么是容器安全 容器安全是指保护容器化应用程序和基础设施免受潜在威胁和攻击的措施和策略。容器化技术&#xff08;如Docker、Kubernetes&#xff09;使得应用程序能够在隔离的环境中运行&#xff0c;这既提供了灵活性&#xff0c;也引入了新的安全…

Vue3+Vite+TS+Axios整合详细教程

1. Vite 简介 Vite是新一代的前端构建工具&#xff0c;在尤雨溪开发Vue3.0的时候诞生。类似于Webpack Webpack-dev-server。其主要利用浏览器ESM特性导入组织代码&#xff0c;在服务器端按需编译返回&#xff0c;完全跳过了打包这个概念&#xff0c;服务器随起随用。生产中利用…

【java深入学习第6章】深入解析Spring事件监听机制

在Spring框架中&#xff0c;事件监听机制是一个强大且灵活的功能&#xff0c;允许我们在应用程序中发布和监听事件。这种机制可以帮助我们实现松耦合的设计&#xff0c;使得不同模块之间的通信更加灵活和可维护。本文将详细介绍Spring的事件监听机制&#xff0c;并通过代码示例…