【数据结构】顺序表

目录

顺序表

        头文件

        源文件

相关练习


顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构

        头文件

#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--;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值