顺序表、线性表的顺序表示和实现

顺序表、线性表的顺序表示和实现

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素, 这种表示也称作线性表的顺序存储结构或顺序映像。通常, 称这种存储结构的线性表为顺序表(Sequential List)。其特点是,逻辑上相邻的数据元素, 其物理次序也是相邻的

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储。

  2. 动态顺序表:使用动态开辟的数组存储。

静态顺序表

#define N 10000 //顺序表可能达到的最大长度
typedef int SLDataType;

// 静态顺序表
typedef struct SeqList
{
	SLDataType a[N]; // 定长数组
	int size;        // 表示数组中存储了多少个数据
}SL;                 //顺序表的结构类型为SL
静态顺序表

动态顺序表

typedef int SLDataType;

// 动态顺序表
typedef struct SeqList
{
	SLDataType* a; //存储空间的首地址
	int size;      // 表示数组中存储了多少个数据
	int capacity;  // 数组实际能存数据的空间容量是多大 
}SL;               //顺序表的结构类型为SL
动态顺序表

顺序表的实现

这里我们使用动态顺序表

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//#define N 10000
//typedef int SLDataType;
 静态顺序表
//typedef struct SeqList
//{
//	SLDataType a[N];
//	int size; // 表示数组中存储了多少个数据
//}SL;

typedef int SLDataType;
// 动态顺序表
typedef struct SeqList
{
	SLDataType* a;
	int size;      // 表示数组中存储了多少个数据
	int capacity;  // 数组实际能存数据的空间容量是多大 
}SL;



//顺序表初始化
void SeqListInit(SL* ps);
//顺序表销毁
void SeqListDestory(SL* ps);
//顺序表打印
void SeqListPrint(SL* ps);
//顺序表容量检查,容量不够则增加
void SeqListCheckCapacity(SL* ps);
//顺序表尾插
void SeqListPushBack(SL* ps, SLDataType x);
//顺序表尾删
void SeqListPopBack(SL* ps);
//顺序表头插
void SeqListPushFront(SL* ps, SLDataType x);
//顺序表头删
void SeqListPopFront(SL* ps);
// 找到了返回x位置下标,没有找打返回-1
int SeqListFind(SL* ps, SLDataType x);
// 指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x);
// 删除pos位置的数据
void SeqListErase(SL* ps, int pos);

SeqList.c文件

#include "SeqList.h"

//顺序表初始化
void SeqListInit(SL* ps) {
	//防止空指针
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

//顺序表销毁
void SeqListDestory(SL* ps) {
	//防止空指针
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

//顺序表打印
void SeqListPrint(SL* ps) {
	//防止空指针
	assert(ps);
	for (int i = 0; i < ps->size; i++) {
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

//顺序表容量检查,容量不够则增加
void SeqListCheckCapacity(SL* ps) {
	if (ps->size == ps->capacity) {
		ps->capacity = ps->capacity == 0 ? 1 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity);
		if (tmp == NULL) {
			printf("Memory development failed");
			exit(-1);
		}
		ps->a = tmp;
	}
}

//顺序表尾插
void SeqListPushBack(SL* ps, SLDataType x) {
	//写法一:
	//防止空指针
	assert(ps);
	//检查顺序表容量
	SeqListCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;

	//写法二:
	//利用顺序表插入函数
	//SeqListInsert(ps, ps->size, x);
}

//顺序表尾删
void SeqListPopBack(SL* ps) {
	//方法一:
	//防止空指针
	assert(ps);
	//判断顺序表是否为空
	if (ps->size == 0) {
		printf("SeqList is empty");
		return;
	}
	ps->size--;

	//方法二:
	//利用顺序表删除函数
	//SeqListErase(ps, ps->size - 1);
}

//顺序表头插
void SeqListPushFront(SL* ps, SLDataType x) {
	//方法一:
	//防止空指针
	assert(ps);
	SeqListCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--) {
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;

	//写法二:
	//利用顺序表插入函数
	//SeqListInsert(ps, 0, x);
}

//顺序表头删
void SeqListPopFront(SL* ps) {
	//方法一:
	//防止空指针
	assert(ps);
	if (ps->size == 0) {
		printf("SeqList is empty");
		return;
	}
	for (int i = 0; i < ps->size; i++) {
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;

	//方法二:
	//利用顺序表删除函数
	//SeqListErase(ps, 0);
}


// 找到了返回x位置下标,没有找到返回-1
int SeqListFind(SL* ps, SLDataType x) {
	//防止空指针
	assert(ps);
	for (int i = 0; i < ps->size; i++) {
		if (ps->a[i] == x) {
			return i;
		}
	}
	return -1;
}

// 指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x) {
	//防止空指针
	assert(ps);
	//判断pos是否合法
	if (pos<0 || pos>ps->size) {
		printf("pos not exist");
		return;
	}
	SeqListCheckCapacity(ps);
	for (int i = ps->size; i > pos; i--) {
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}

// 删除pos位置的数据
void SeqListErase(SL* ps, int pos) {
	//防止空指针
	assert(ps);
	//判断pos是否合法
	if (pos<0 || pos>ps->size) {
		printf("pos not exist");
		return;
	}
	//判断顺序表是否为空
	if (ps->size == 0) {
		printf("SeqList is empty");
		return;
	}
	for (int i = pos; i < ps->size; i++) {
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

顺序表相关OJ题

移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

来源:力扣(LeetCode)

int removeElement(int* nums, int numsSize, int val){
    int src = 0, dst = 0;
    while(src<numsSize){
        if(nums[src]==val){
            src++;
        }else{
            nums[dst]=nums[src];
            src++;
            dst++;
        }
    }
    return dst;
}
您的浏览器不支持 HTML5 video 标签。 移除元素思路视频下载观看

删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

来源:力扣(LeetCode)

int removeDuplicates(int* nums, int numsSize){
    if(numsSize==0)
    {return;}

    int src = 1, drt = 0;
    while(src < numsSize)
    {
        if(nums[src]==nums[drt])
        {
            src++;
        }
        else
        {
            nums[drt+1]=nums[src];
            src++;
            drt++;
        }
    }
    return drt+1;

}

本文出现任何错误,欢迎留言批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值