【数据结构与算法篇】动态顺序表及相关OJ算法题

【数据结构与算法篇】动态顺序表及相关OJ算法题

🥕个人主页:开敲🍉

🔥所属专栏:数据结构与算法🍅

目录

【数据结构与算法篇】动态顺序表及相关OJ算法题

1. 动态顺序表的实现

    1.1 SeqList.h 头文件声明

      1.2 SeqList.c 源文件定义

    1.3 Test.c 源文件测试

2. OJ算法题

     1. 27. 移除元素 - 力扣(LeetCode)

      2. 88. 合并两个有序数组 - 力扣(LeetCode)

1. 动态顺序表的实现

    1.1 SeqList.h 头文件声明

//SeqList.h

#pragma once

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


typedef int SQDataType;

typedef struct
{
    SQDataType* arr;
    int size;
    int capacity;
}SL;

SL sl;


//初始化
void SeqListInit(SL* sl);

//打印
void SeqListPrint(SL* sl);


//增  删  查  改

//尾插
void SeqListPushBack(SL* sl);

//头插
void SeqListPushHead(SL* sl);

//随机插入
void SeqListPushRand(SL* sl);

//尾删
void SeqListPopBack(SL* sl);

//头删
void SeqListPopHead(SL* sl);

//随机删除
void SeqListPopRand(SL* sl);


//查找
void SeqListFind(SL* sl);


//更改
void SeqListChange(SL* sl);

      1.2 SeqList.c 源文件定义

#define _CRT_SECURE_NO_WARNINGS 1


#include "SeqList.h"

//初始化
void SeqListInit(SL* sl)
{
    sl->arr = sl->arr = (SQDataType*)malloc(sizeof(SQDataType));
    sl->size = 0;
    sl->capacity = 1;
}

//打印
void SeqListPrint(SL* sl)
{
    int i = 0;
    for (i = 0; i < sl->size; i++)
    {
        printf("%d ", sl->arr[i]);
    }
    printf("\n");
}

//尾插
void SeqListPushBack(SL* sl,int n)
{
    //扩容
    while (sl->size >= sl->capacity)
    {
        SQDataType* ptr = (SQDataType*)realloc(sl->arr, sizeof(SQDataType) * (sl->capacity) * 2);
        if (ptr == NULL)
        {
            perror("realloc");
            return;
        }
        else
        {
            sl->arr = ptr;
        }
        sl->capacity *= 2;
    }
    sl->arr[sl->size] = n;
    sl->size++;
}


//头插
void SeqListPushHead(SL* sl)
{
    int num = sl->size;
    int input = 0;
    printf("请输入要插入的数据: ");
    scanf("%d", &input);
    //扩容
    while (sl->size >= sl->capacity)
    {
        SQDataType* ptr = (SQDataType*)realloc(sl->arr, sizeof(SQDataType) * (sl->capacity) * 2);
        if (ptr == NULL)
        {
            perror("realloc");
            return;
        }
        else
        {
            sl->arr = ptr;
        }
        sl->capacity *= 2;
    }
    while (num)
    {
        sl->arr[num] = sl->arr[num - 1];
        num--;
    }
    sl->arr[0] = input;
    sl->size++;
}

//随机插入
void SeqListPushRand(SL* sl)
{
    int input = 0;
    int flag = 0;
    printf("请输入要插入的数据:");
    scanf("%d", &input);
    printf("请输入要插入的位置:");
    scanf("%d", &flag);
    //扩容
    while (sl->size >= sl->capacity)
    {
        SQDataType* ptr = (SQDataType*)realloc(sl->arr, sizeof(SQDataType) * (sl->capacity) * 2);
        if (ptr == NULL)
        {
            perror("realloc");
            return;
        }
        else
        {
            sl->arr = ptr;
        }
        sl->capacity *= 2;
    }
    SQDataType* pf = &(sl->arr[flag - 1]);
    SQDataType* pf1 = &(sl->arr[sl->size - 1]);
    while (pf1 >= pf)
    {
        *(pf1 + 1) = *pf1;
        pf1--;
    }
    *pf = input;
    sl->size++;
}

//尾删
void SeqListPopBack(SL* sl)
{
    sl->size--;
}


//头删
void SeqListPopHead(SL* sl)
{
    if (sl->size)
    {
        int num = 0;
        while (num < sl->size)
        {
            sl->arr[num] = sl->arr[num + 1];
            num++;
        }
    }
}

//随机删除
void SeqListPopRand(SL* sl)
{
    int del = 0;
    printf("请输入要删除的位置:");
    scanf("%d", &del);
    while (del > sl->size)
    {
        printf("该位置无可删除的数据,请重新输入:");
        scanf("%d", &del);
    }
    SQDataType* pf = &(sl->arr[del - 1]);
    SQDataType* pf1 = pf + 1;
    while (pf1 <= &(sl->arr[sl->size - 1]))
    {
        *(pf1 - 1) = *pf1;
        pf1++;
    }
    sl->size--;
}


//查找
void SeqListFind(SL* sl)
{
    SQDataType* pf = sl->arr;
    int find = 0;
    printf("请输入要查找的位置:");
    scanf("%d", &find);
    while (find > sl->size)
    {
        printf("查询失败,该位置无内容,请重新输入:");
        scanf("%d", &find);
    }
    if (find <= sl->size)
    {
        printf("查询成功,该位置内容为:%d\n", sl->arr[find - 1]);
    }

}


//更改
void SeqListChange(SL* sl)
{
    int change = 0;
    int flag = 0;
    printf("请输入要更改的位置:");
    scanf("%d", &flag);
    while (flag > sl->size)
    {
        printf("该位置无数据可更改,请重新输入:");
        scanf("%d", &flag);
    }
    printf("请输入想要更换为的数据:");
    scanf("%d", &change);
    SQDataType* pf = &(sl->arr[flag - 1]);
    *pf = change;
}

    1.3 Test.c 源文件测试

#define _CRT_SECURE_NO_WARNINGS 1

#include "SeqList.h"

void menu()
{
    printf("**********************************************\n");
    printf("**********************************************\n");
    printf("*********** 1. endadd   2. beginadd **********\n");
    printf("*********** 3. randadd  4. endel    **********\n");
    printf("*********** 5. begindel 6. randdel  **********\n");
    printf("*********** 7. find     8. change   **********\n");
    printf("***********        0. exit          **********\n");
    printf("**********************************************\n");
    printf("**********************************************\n");
    printf("请输入要进行的操作:");
}


enum SQ
{
    Exit,
    endadd,
    beginadd,
    randadd,
    enddel,
    begindel,
    randdel,
    find,
    change
}sq;


int main()
{
    SeqListInit(&sl);
    int i = 0;
    int option = 0;
    int input = 0;
    int add = 0;
    do
    {
        menu();
        scanf("%d", &i);
        input = (enum SQ)i;
        switch (input)
        {
        case endadd:
            printf("请输入要插入的数据,以-1结束:");
            do
            {
                scanf("%d", &option);
                if (option != -1)
                {
                    SeqListPushBack(&sl, option);
                }
            } while (option != -1);
            SeqListPrint(&sl);
            break;
        case beginadd:
            SeqListPushHead(&sl);
            SeqListPrint(&sl);
            break;
        case randadd:
            SeqListPushRand(&sl);
            SeqListPrint(&sl);
            break;
        case enddel:
            SeqListPopBack(&sl);
            SeqListPrint(&sl);
            break;
        case begindel:
            SeqListPopHead(&sl);
            SeqListPrint(&sl);
            break;
        case randdel:
            SeqListPopRand(&sl);
            SeqListPrint(&sl);
            break;
        case find:
            SeqListFind(&sl);
            break;
        case change:
            SeqListChange(&sl);
            SeqListPrint(&sl);
            break;
        case Exit:
            printf("退出程序\n");
            break;
        default:
            printf("输入非法,请重新输入:");
            scanf("%d", &input);
            break;
        }
    } while (input);
    return 0;
}

2. OJ算法题

     1. 27. 移除元素 - 力扣(LeetCode)

  这题的最优解是双指针解法:时间复杂度O(N),空间复杂度O(1)。解法:

int removeElement(int* nums, int numsSize, int val)

{

    int left = 0;    //左指针,用于保存不等于val的数据

    int right = 0;  //右指针,用于排除等于val的值,并把不等于val的值赋值给左指针

    for(right = 0;right<numsSize;right++)  //右指针遍历

    {

        if(nums[right]!=val)  //如果右指针数据不等于val,右指针的数据复制给左指针

        {

            nums[left] = nums[right];

            left++;    //左右指针都++

        }

               //否则,如果右指针的数据等于val,左指针不动,右指针++

    }

    return left;         //最后数组中元素的个数就等于left的大小

}

      2. 88. 合并两个有序数组 - 力扣(LeetCode)

    这题的思路是用第三个数组来将数组1、2中的内容从小到大排放,然后再按个放进数组1中:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)

{

    int i = 0;  

    int j = 0;  //数组3的下标

    int pf1 = 0;  //数组1的指针

    int pf2 = 0;  //数组2的指针

    int nums3[m+n];  //用于存放数据的数组3

    while(pf1<m||pf2t<n)

    {

        if(pf1==m)  //如果数组1的内容已经全部放进数组3,则直接将数组2中的内容放进数组3

        {

            nums3[j++] = nums2[pf2++];

        }

        else if(pf2==n)  //如果数组2的内容已经全部放进数组3,则直接将数组1中的内容放进数组3

        {

            nums3[j++] = nums1[pf1++];

        }

        else if(nums1[pf1]<nums2[pf2])  //比较两数组中数据的大小,小的先放进数组3

        {

            nums3[j++] = nums1[pf1++];

        }

        else  

        {

            nums3[j++] = nums2[pf2++];

        }

    }

    for(i = 0;i<j;i++)

    {

        nums1[i] = nums3[i];  //将数组3的内容放回数组1中

    }

}

                                                        创作不易,点个赞呗,蟹蟹啦~

           

  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值