顺序表的实现看这一篇就够辣



1.顺序表

1.1 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。
  2. 动态顺序表:使用动态开辟的数组存储。

在这里插入图片描述

1.2接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。
在这里插入图片描述

1.2.1 头文件

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct seqlist
{
	SLDataType* a;
	int size;//元素个数
	int capacity;//容量
}SL;
//顺序表打印
void SLPrint(SL* ps);
//顺序表初始化
void SLInit(SL* ps);
//顺序表销毁
void SLDestroy(SL* ps);
// 尾插尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
//头插头删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
// 中间插入删除
// 在pos位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
// 删除pos位置数据
void SLErase(SL* ps, int pos);
//查找元素
int SLFind(SL* ps, SLDataType x);


1.2.2函数实现部分

#define _CRT_SECURE_NO_WARNINGS 1
#include"seqlist.h"
void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
//打印
void SLPrint(SL* ps)
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d", ps->a[i]);
	}
}
//摧毁顺序表
void SLDestroy(SL* ps)
{
	assert(ps);
	if (ps->a)
	{
		ps->a = NULL;
		ps->size = 0;
		ps->capacity = 0;
	}
}
//检查扩容
void checkcapacity(SL*ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		int newcapacity = (ps->capacity == 0 ? 4 : 2 * (ps->capacity));
		SLDataType*p = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));//注意数据类型
		if (p == NULL)
		{
			perror(realloc);
		}
		ps->a = p;
		ps->capacity = newcapacity;
	}
}
//尾插
void SLPushBack(SL* ps,SLDataType x)
{
	assert(ps);
	checkcapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	checkcapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
	
}
//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	int start = 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		start++;
	}
	ps->size--;

}
//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	checkcapacity(ps);
	int end =  ps-> size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;

}
//任意位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size > 0);
	int start =pos+1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		start++;

	}
	ps->size--;


}
//查找
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (x == ps->a[i])
		{
			return i;
		}
	}
	return -1;
}

1.2.3主函数部分

#define _CRT_SECURE_NO_WARNINGS 1
#include"seqlist.h"
void testseqlist()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPushFront(&s1, 5);
	SLPushBack(&s1, 5);
	SLPopFront(&s1);
	SLPopBack(&s1);
	int pos = SLFind(&s1, 4);
	printf("%d\n", pos);
	SLInsert(&s1, 0, 2);
	SLErase(&s1, 2);

	SLPrint(&s1);
	SLDestroy(&s1);
}
int main()
{
	testseqlist();
	return 0;
}

1.3数组相关面试题

1.3.1第一题

在这里插入图片描述

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

int i=0;
int j=0;
for(i=0;i<numsSize;i++)
{
    if(nums[i]!=val)
    {
        nums[j++]=nums[i];

    }
}
return j;
}

1.3.2第二题

在这里插入图片描述

int removeDuplicates(int* nums, int numsSize)
{
    int fast=0;//双指针来解决
    int slow=0;
    while(fast<numsSize&&slow<numsSize)
    {
       if(nums[fast]!=nums[slow])
       {
           nums[++slow]=nums[fast];
       }
       fast++;
    }
    return ++slow;


}

1.3.3第三题

在这里插入图片描述

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
    int n1=m-1;//三指针解决
    int n2=n-1;
    int n3=m+n-1;
    while(n1>=0&&n2>=0)
    {
        if(nums1[n1]>=nums2[n2])
        {
            nums1[n3--]=nums1[n1];
            n1--;
        }
        else
         {
            nums1[n3--]=nums2[n2];
            n2--;
        }
    }
    while(n2>=0)
    {
        nums1[n3--]=nums2[n2--];
    }
    return nums1;


}

在这里插入图片描述

在这里插入图片描述

1.4 顺序表的问题及思考

问题:

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间

在这里插入图片描述

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值