【数据结构与算法篇】动态顺序表及相关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中
}
}
创作不易,点个赞呗,蟹蟹啦~