24/07/09数据结构(3.1206)数组OJ单链表实现

先做几个练习回顾一下前两个博的 顺序表:

1.给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度.不需要使用额外的数组空间,你必须在原地修改数组并使用O(1)额外空间的条件下完成.

给定 nums = [0, 0, 1, 1 ,1, 2, 2, 3, 3, 4],函数应该返回新的长度5,并且原数组 nums 的前5个元素被修改为0, 1, 2, 3, 4

    int removeDuplicates(int* nums, int numSize){
        if (numsSize <= 1)
            return numsSize;
        int i = 0, j = 1, idx = 0;
        while (j < numsSize){
            nums[idx++] = nums[i];
            
            if (num[i] == nums[j]){
                //找到非重复元素的第一个位置
                while (j < numsSize && nums[i] == nums[j])
                    ++j;

                i = j;
                ++j;
            }
            else{
                ++i;
                ++j;
            }
        }
        if (i < numsSize)
            nums[idx++] = num[i];
        return idx;
    }

2.合并两个有序数组,给你两个有序整数数组nums1和nums2,请你将nums2合并到nums1中,使nums1成为一个有序数组.

说明:初始化nums1和nums2的元素数量分别为 m 和 n.

        你可以假设nums1有足够的空间(空间大于或等于 m+n)来保存nums2中的元素

 实例:nums1 = [1, 2, 3, 0, 0], m = 3

        nums2 = [2, 5, 6],        n = 3 输出[1, 2, 2, 3, 5, 6]

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int* nums3 = (int*)malloc(sizeof(int)* (m + n));
    int i = 0, j = 0, idx = 0;
    //同时遍历
    while (i < m && j < n){
        if (nums1[i] <= nums2[j]){
            nums3[idx++] = nums1[i++];
        }
        else{
            nums3[idx++] = nums2[j++];
        }
    }
    //判断 是否有剩余元素
    if (i < m)
        memcpy(nums3 + idx, nums1 + i, sizeof(int)* (m - i));
    
    if (j < n)
        memcpy(nums3 + idx, nums2 + j, sizeof(int)* (n - j));

    memcpy(nums1, nums3, sizeof(int)* (m + n));
    free(nums3);
}

换一种方法(插入):

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int i = m - 1, j = n - 1, idx = m + n - 1;
    while (i >= 0 && j >= 0){
        if (nums1[i] > nums2[j])
            nums1[idx--] = nums1[i--];
        else
            nums1[idx--] = nums2[j--];
    }
    //判断nums2中是否有剩余元素
    if (j >= 0){
        memcpy(nums1, nums2, sizeof(int)* (j + 1));
    }

3.旋转数组 给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数

示例: 输入:[1, 2, 3, 4, 5, 6, 7] 和 k = 3

        输出:[5, 6, 7, 1, 2, 3, 4]

void reverse(int* num, int start, int end){
    while (start < end){
        int tmp = num[start];
        num[start] = num[end];
        num[end] = tmp;
        ++start;
        --end;
    }
}
void rotate(int* nums, int numsSize, int k){
    k %= numsSize;
    reverse(nums, 0, numsSize - k - 1);
    reverse(nums, numsSize - k, numsSize - 1);
    reverse(nums, 0, numsSize - 1);
}
 

4.数组形式的整数加法

对于非负整数X而言,X的数组形式是每位数字按照从左到右的顺序形成的数组.例如,如果X = 1231,那么其数组形式为[1, 2, 3, 1]

给定非负整数X的数组形式A,返回整数X+K的数组形式

示例:输入:A = [1, 2, 0, 0], k = 34

        输出:[1,2,3,4]

        解释:1200 + 34 = 1234

int* addToArrayForm(int* A, int ASize, int k, int* returnSize){
    //获取数字K的长度
    int len = 0;
    int tmp = k;
    while (tmp){
        ++len;
        tmp /= 10;
    }
    //获取结果的最大长度
    int arrLen = len > ASize ? len + 1 : ASize + 1;
    int* ret = (int*)malloc(sizeof(int)* arrLen);

    //从个位开始相加
    int end = ASize - 1;
    //上一步进位
    int step = 0;
    int idx = 0;
    while (end >= 0 || k > 0){
        //每一位的结果包含了进位 + 对应位的值
        //首先加进位值
        int curRet = step;
        if (end >= 0)
            curRet += A[end];
        if (k > 0)
            curRet += k % 10;
        //处理进位
        if (curRet > 9){
            step = 1;
            curRet -= 10;
        }

else

        step = 0;
        //保存当前位的结果:逆序存放
        ret[idx++] = curRet;
        //累加高位的值
        --end;
        k /= 10;
    }
    //判断最高位是否拥有进位
    if (step == 1)
        ret[idx++] = 1;
    //逆转
    int start = 0;
    end = idx - 1;
    while (start < end){
        int tmp = ret[start];
        ret[start] = ret[end];
        ret[end] = tmp;
        ++start;
        -- end;
    }
    //返回结果的长度
    *returnSize = idx;
    return ret;
}

链表

链表的结构非常多样,以下情况组合起来就有八种链表结构:

1.单向,双向

2.带头,不带头

3.循环,非循环

虽然有这么多的链表结构,但我们实际最常用的还是两种结构:

1.无头单向非循环链表:结构简单,一般不会单独存数据.实际中更多是作为其他数据结构的子结构,如哈希桶,图的邻接表等.笔试面试中出现较多.

2.带头双向循环链表

写单链表的一些接口(和上一博一样写头插头删尾插尾删查找销毁等...只不过上个是顺序表这个是单链表)

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

typedef int LDataType;
typedef struct listNode{
    LDataType _data;
    struct listNode* _next;
}listNode;

typedef struct list{
    //存放第一个节点的地址
    listNode* _head;
}list;

void listInit(list* lst){
    //初始化为空的链表
    if (lst == NULL)
        return;
    lst->_head = NULL;
}

listNode* creatNode(LDataType val){
    listNode* node = (listNode*)malloc(sizeof(listNode));
    node->_data = val;
    node->_next = NULL;
    return node;
}
//尾插
void listPushBack(list* lst,LDataType val){
    if (lst == NULL)
        return;
    //第一种 空链表插入第一个数据
    if (lst->_head == NULL){
        //创建节点
        lst->_head = creatNode(val);
    }
    else{
        //遍历,找到最后一个节点
        listNode* tail = lst->_head;
        while (tail->_next != NULL){
            tail = tail->_next;
        }
        //插入
        tail->_next = creatNode(val);
    }

}
//尾删
void listPopBack(list* lst){
    
    if (lst == NULL || lst->_head == NULL)
        return;

    struct listNode* tail = lst->_head;
    struct listNode* prev = NULL;
    //遍历 找到最后一个节点
    while (tail->_next != NULL){
        prev = tail;
        tail = tail->_next;
    }
    //删除节点
    free(tail);
    //修改指向
    if (prev = NULL) //删除的是头结点,更新头结点
        lst->_head = NULL;
    else
    prev->_next = NULL;
}

//头插
void listPushFront(list* lst, LDataType val){
    if (lst == NULL)
        return;
    //空的链表,插入第一个数据
    if (lst->_head == NULL)
        lst->_head = creatNode(val);
    else{
        listNode* node = creatNode(val);
        listNode* next = lst->_head;
        //head,node,next
        lst->_head = node;
        node->_next = next;
    }
}

//头删
void listPopFront(list* lst){
    if (lst == NULL || lst->_head == NULL)
        return;
    struct listNode* next = lst->_head->_next;
    //释放头结点
    free(lst->_head);
    lst->_head = next;
}

//中间位置的插入
void listInsertAfter(listNode* cur, LDataType val){
    listNode* node = creatNode(val);
    listNode* next = cur->_next;
    //cur node next
    cur->_next = node;
    node->_next = next;

}

//删除cur节点的下一个节点
void listEraseAfter(listNode* cur){
    //cur next next->next
    listNode* next = cur->_next;
    if (next == NULL)
        return;
    listNode* nextnext = cur->_next;
    free(next);
    cur->_next = nextnext;
}

listNode* listFind(list* lst, LDataType val){
        if (lst == NULL || lst->_head == NULL)
            return NULL;
        //从第一个节点开始遍历
        listNode* cur = lst->_head;
        while (cur){
            if (cur->_data == val)
                return cur;

            cur = cur->_next;
        }
        return NULL;
    }

void listDestory(list* lst){
    if (lst == NULL || lst->_head)
        return;
    //从第一个节点释放
    listNode* cur = lst->_head;
    while (cur){
        listNode* next = cur->_next;
        //释放节点
        free(cur);
        cur = next;
    }
    lst->_head = NULL;
}

void test(){
    list lst;
    listInit(&lst);
    listPushFront(&lst, 5);
    listPushFront(&lst, 4);
    listPushFront(&lst, 3);
    listPushFront(&lst, 2);
    listPushFront(&lst, 1);

    listNode* cur = listFind(&lst, 3);
    listInsertAfter(cur, 33);

    cur = listFind(&lst, 2);
    listEraseAfter(cur);
}

void listDestory(list* lst){

}
//void test(){
//    list lst;
//    listInit(&lst);
//    listPushBack(&lst, 1);
//    listPushBack(&lst, 2);
//    listPushBack(&lst, 3);
//    listPushBack(&lst, 4);
//    listPushBack(&lst, 5);
//
//    listPopBack(&lst);
//    listPopBack(&lst);
//    listPopBack(&lst);
//    listPopBack(&lst);
//    listPopBack(&lst);
//
//    listPushFront(&lst, 5);
//    listPushFront(&lst, 4);
//    listPushFront(&lst, 3);
//    listPushFront(&lst, 2);
//    listPushFront(&lst, 1);
//
//    listPopFront(&lst);
//    listPopFront(&lst);
//    listPopFront(&lst);
//    listPopFront(&lst);
//    listPopFront(&lst);
//}

int main(){

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

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

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

相关文章

ctfshow-web入门-文件上传(web161、web162、web163)远程包含

目录 1、web161 2、web162 3、web163 1、web161 先传配置文件&#xff0c;可以上传成功 因为我前面给的 .user.ini 都是带了图片头 GIF89a 的&#xff0c;前面的题这个图片头可以去掉&#xff0c;但是在这里如果去掉是不行的。 因此后面上传的东西我们都带上这个图片头&…

FPGA程序设计

在设计FPGA时&#xff0c;多运用模块化的思想取设计模块&#xff0c;将某一功能设计成module。 设计之前要先画一下模块设计图&#xff0c;列出输入输出接口&#xff0c;再进一步设计内部功能。 状态机要画图&#xff0c;确定每个状态和状态之间怎么切换。状态用localparam定…

宏碁F5-572G-59K3笔记本笔记本电脑拆机清灰教程(详解)

1. 前言 我的笔记本开机比较慢&#xff0c;没有固态&#xff0c;听说最近固态比较便宜&#xff0c;就想入手一个&#xff0c;于是拆笔记本看一下有没有可以安的装位置。&#xff08;友情提示&#xff0c;在拆机之前记得洗手并擦干&#xff0c;以防静电损坏电源器件&#xff09…

视频版权音乐处理☞AI分离人声、音效、背景音乐的需求和进展-2024

随着互联网的普及和短视频的兴起&#xff0c;视频内容的全球各大平台分发越来越普遍。然而&#xff0c;不同国家和地区的音乐版权、不同社媒平台拥有的版权和处理政策都存在差异&#xff0c;因此同一个视频在多渠道分发的时候就会产生版权侵权风险。如何既能满足全球多渠道、多…

【UE5】调用ASR接口,录制系统输出。录制音频采样率不匹配

暂时测出window能用。阿里的ASR接口当前仅支持8000和16000。UE默认采样44100。

开源项目的机遇与挑战

随着全球经济和科技环境的快速变化&#xff0c;开源软件项目的蓬勃发展成为了开发者社区的热门话题。越来越多的开发者和企业选择参与开源项目&#xff0c;以推动技术创新和实现协作共赢。本文将从开源项目的发展趋势、参与开源的经验分享&#xff0c;以及开源项目的挑战三个方…

补码一位乘法原理(布斯编码详讲)

最近在看补码乘法的时候&#xff0c;感觉到很奇怪的一点&#xff0c;那就是补码的一位乘法&#xff0c;就是上网查了大量的资料都没有理解到它真正的原理&#xff0c;总感觉还是不会。那么&#xff0c;补码乘法的原理到底是什么呢&#xff1f;而让我们一直困惑的点是哪里呢&…

MySQL 常用语句

创建数据库 CREATE DATABASE database_name; 删除数据库 DROP DATABASE database_name; 选择数据库 USE database_name; 创建表 CREATE TABLE table_name ( column1 datatype constraints, column2 datatype constraints, column3 datatype constraints, .... ); …

ROI 接口便捷修改

传入的图片截取ROI后再进入识别接口 &#xff08;识别接口比ROI接口的函数参数少一个传入的ROI&#xff09; 无点只有点集 返回双点集 //平直冷侧翅片 bool ImageProcessingTest::straightColdSideFin_ROI(cv::Mat img, cv::Rect ROI, std::vector<cv::Point>& topL…

9.3 栅格图层符号化单波段伪彩色渲染

文章目录 前言单波段伪彩色QGis设置为单波段伪彩色二次开发代码实现单波段伪彩色 总结 前言 介绍栅格图层数据渲染之单波段伪彩色渲染说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 单波段伪彩色 使用单波段假彩色渲染栅格图层能够使用配色方案&#xff…

昇思25天学习打卡营第22天 | Shufflenet图像分类

ShuffleNet图像分类 当前案例不支持在GPU设备上静态图模式运行&#xff0c;其他模式运行皆支持。 ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有…

【Linux】进程(9):进程控制3(进程程序替换)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解Linux进程&#xff08;9&#xff09;进程控制1&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 &#xff08;A&#xff09;什么是进程程序替换&#xf…

js实现图片放大镜功能,简单明了

写购物项目的时候&#xff0c;需要放大图片&#xff0c;这里用js写了一个方法&#xff0c;鼠标悬浮的时候放大当前图片 这个是class写法 <!--* Descripttion: * Author: 苍狼一啸八荒惊* LastEditTime: 2024-07-10 09:41:34* LastEditors: 夜空苍狼啸 --><!DOCTYPE …

7.10号小项目部分说明

总体说明 糖锅小助手 我这次主要对上次糖锅小助手界面添加了一个侧边栏&#xff08;侧边输入框放置了三个按钮&#xff0c;可以跳转到其他ai聊天界面&#xff0c;还可以退出聊天界面回到登录界面&#xff09;和一个日期输入框&#xff08;日期输入框获取时间&#xff0c;根据时…

Ubuntu固定虚拟机的ip地址

1、由于虚拟机网络是桥接&#xff0c;所以ip地址会不停地变化&#xff0c;接下来我们就讲述ip如何固定 2、如果apt安装时报错W: Target CNF (multiverse/cnf/Commands-all) is configured multiple times in /etc/apt/sources.list:10&#xff0c; 检查 /etc/apt/sources.list…

分类模型的算法性能评价

一、概述 分类模型是机器学习中一种最常见的问题模型&#xff0c;在许多问题场景中有着广泛的运用&#xff0c;是模式识别问题中一种主要的实现手段。分类问题概况起来就是&#xff0c;对一堆高度抽象了的样本&#xff0c;由经验标定了每个样本所属的实际类别&#xff0c;由特定…

Type-C/DP1.4到HDMI2.0替代龙讯LT8711HE,集睿智远CS5262

NCS8622是一款高性能低功耗的Type-C/DP1.4到HDMI2.0转换器&#xff0c;设计为连接USB Type-C源或DP1.4源到HDMI2.0。 NCS8622集成了符合DP1.4标准的接收器&#xff0c;以及符合HDMI2.0标准的发射器。此外&#xff0c;CC控制器用于将CC通信到实现DP Alt模式。DP接收器集成了HDCP…

什么是数据同步服务RSYNC?

大家好呀&#xff01;这里是码农后端。今天来介绍一下数据同步服务RSYNC&#xff0c;作为Linux/Unix系统中远程或本地复制同步&#xff08;复制&#xff09;文件和目录最常用的命令&#xff0c;相比于scp命令&#xff0c;其具有增量备份、数据同步时保持文件的原有属性等优点。…

在Linux上安装和配置RocketMQ:保姆级教程

感谢您阅读本文&#xff0c;欢迎“一键三连”。作者定会不负众望&#xff0c;按时按量创作出更优质的内容。 ❤️ 1. 毕业设计专栏&#xff0c;毕业季咱们不慌&#xff0c;上千款毕业设计等你来选。 当安装RocketMQ时&#xff0c;确保遵循以下步骤&#xff1a; 步骤概述 安装 …

flask模块化、封装使用缓存cache(flask_caching)

1.安装flask_caching库 pip install flask_caching 2.创建utils Python 软件包以及cache_helper.py 2.1cache_helper.py代码 from flask_caching import Cachecache Cache()class CacheHelper:def __init__(self, app, config):cache.init_app(app, config)staticmethoddef…