目录
顺序表
????????头文件
????????源文件
相关练习
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构
????????头文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;//将 int 重命名为 SLDataType
typedef struct SeqList
{
SLDataType* data;//指向存储数据空间的指针
int capacity;//表当前的最大容量
int size;//表中当前数据数量
}SL;
void SLInit(SL* psl);//初始化表
void SLDestroy(SL* psl);//释放表中数据
void SLInsert(SL* psl, size_t pos, SLDataType x);//将数据插入表中指定位置前
void SLPushFront(SL* psl, SLDataType x);//头插
void SLPushBack(SL* psl, SLDataType x);//尾插
void SLErase(SL* psl, int pos);//删除表中指定数据
void SLPopFront(SL* psl);//头删
void SLPopBack(SL* psl);//尾删
int SLFind(SL* psl, SLDataType x);//查找表中指定数据并返回下标
void SLModify(SL* psl, int pos, SLDataType x);//修改表中指定数据
????????源文件
#include"SeqList.h"
void SLInit(SL* psl)//初始化表
{
assert(psl);
psl->data = NULL;
psl->capacity = psl->size = 0;
}
void SLDestroy(SL* psl)//释放表中数据
{
assert(psl);
if (psl->data == NULL)
return;
free(psl->data);
psl->data = NULL;
psl->capacity = psl->size = 0;
}
void AddCap(SL* psl)//扩容
{
assert(psl);
int newcap = psl->capacity == 0 ? 4 : psl->capacity * 2;//增容后的容量
SLDataType* tmp = (SLDataType*)realloc(psl->data, newcap * sizeof(SLDataType));//重新开辟空间
assert(tmp);//判断空间是否开辟失败
psl->data = tmp;//将新开辟的空间赋给指向存放数据空间的指针
psl->capacity = newcap;//更新原容量
}
void SLInsert(SL* psl, size_t pos, SLDataType x)//将数据插入到下标 pos 前
{
assert(psl);
assert(pos <= psl->size && pos >= 0);//pos 要在 size 间,pos = size 时为尾插
if (psl->capacity == psl->size)//检查容量
AddCap(psl);
//将 pos 后的数据依次向后移动一位(包括 pos),最后给 pos 位赋值
int end = psl->size;//最后一个元素的后一个位置
while (end > pos)
{
//向后移动
psl->data[end] = psl->data[end - 1];
end--;
}
//赋值
psl->data[pos] = x;
psl->size++;
}
void SLPushFront(SL* psl, SLDataType x)//头插
{
assert(psl);
SLInsert(psl, 0, x);
}
void SLPushBack(SL* psl, SLDataType x)//尾插
{
assert(psl);
SLInsert(psl, psl->size, x);
}
void SLErase(SL* psl, int pos)//删除表中下标为 pos 的数据
{
assert(psl);
assert(pos < psl->size&& pos >= 0);//pos 要在 size 间
if (psl->size == 0)//判断数据是否为空
return;
//将 pos 后的数据依次向前覆盖
while (pos < psl->size - 1)
{
psl->data[pos] = psl->data[pos + 1];
pos++;
}
psl->size--;
}
void SLPopFront(SL* psl)//头删
{
assert(psl);
SLErase(psl, 0);
}
void SLPopBack(SL* psl)//尾删
{
assert(psl);
SLErase(psl, psl->size - 1);
}
int SLFind(SL* psl, SLDataType x)//查找表中指定数据并返回下标
{
assert(psl);
for (int i = 0; i < psl->size; i++)
{
if (psl->data[i] == x)
{
return i;
}
}
return -1;//未找到返回 -1
}
void SLModify(SL* psl, int pos, SLDataType x)//修改表中下标为 pos 数据
{
assert(psl);
assert(pos < psl->size && pos > -1);// pos 要在 size 间
psl->data[pos] = x;
}
相关练习
(1)27. 移除元素 - 力扣(LeetCode) https://leetcode.cn/problems/remove-element/
思路:使用两个下标分别寻找?val?和非?val,使用找到的非?val?替换找到的?val。
int removeElement(int* nums, int numsSize, int val)
{
int des = 0;//用来找 val
int src = 0;//用来找非 val
while (src < numsSize)
{
if (nums[src] != val)
{
nums[des] = nums[src];
des++;
src++;
}
else
{
src++;
}
}
return des;//这时的 des 正好是元素个数
}
(2)26. 删除有序数组中的重复项 - 力扣(LeetCode) https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
思路:使用两个下标,一个快,一个慢,当两个下标指向的值相等,快下标继续向后寻找不同的值并赋给慢下标的后一个位置。
int removeDuplicates(int* nums, int numsSize)
{
int slow = 0;
int fast = 0;
while (fast < numsSize)
{
if (nums[fast] == nums[slow])
{
fast++;
}
else
{
slow++;
nums[slow] = nums[fast];
fast++;
}
}
return slow + 1;
}
(3)88. 合并两个有序数组 - 力扣(LeetCode) https://leetcode.cn/problems/merge-sorted-array/
思路:定义 3?个下标,分别指向如下位置。
?将下标 1?和下标 3?指向的值进行对比,把较大的值放入下标 2?指向的位置,依次向前。
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
int end1 = m - 1;
int end2 = n - 1;
int index = m + n - 1;
while (end1 >= 0 && end2 >= 0)
{
if (nums1[end1] > nums2[end2])
{
nums1[index] = nums1[end1];
end1--;
index--;
}
else
{
nums1[index] = nums2[end2];
end2--;
index--;
}
}
if (end2 >= 0)//将 2 号数组剩下元素进行拷贝,由于 1 号数组为自身,所以无需拷贝
{
while (end2 >= 0)
{
nums1[index] = nums2[end2];
index--;
end2--;
}
}
}
|