IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构 -- 顺序表 -> 正文阅读

[数据结构与算法]数据结构 -- 顺序表

顺序表

概念及结构

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

  • 静态顺序表:使用定长数组存储
  • 动态顺序表:使用动态开辟的数组存储

接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组会导致空间开多了浪费,开少了不够用。
所以动态顺序表会用的比较多,根据需要动态的分配空间大小。

相关操作代码示例

  1. seqList.h
#pragma once
//顺序表:数组,数组相关信息:有效元素个数,数组的容量

//静态顺序表  404byte
#define N 100
typedef int SLDataType;
struct seqList
{
	SLDataType _data[N];
	int _size;
};

//动态顺序表  12byte
typedef struct seqList1
{
	SLDataType* _data; //数组指针
	int _size; //有效元素个数
	int _capacity; //数组的空间
}seqList1;

void initseqList(seqList1* s1);

void seqListCheckCapacity(seqList1* s1); //扩容

//操作:增删查改
//尾插:给顺序表最后一个有效数据的末尾插入新的数据
void seqList_pushBack(seqList1* s1, SLDataType val);
//尾删:删除最后一个数据
void seqList_popBack(seqList1* s1);
//打印
void seqList_print(seqList1* s1);
//访问某一个位置的元素
SLDataType seqList(seqList1* s1, int pos);
//判断顺序表是否为空
int seqList_isEmpty(seqList1* s1);
//头插:给顺序表头部插入一个新的数据
void seqList_pushFront(seqList1* s1, SLDataType val);
//头删:删除第一个数据
void seqList_popFront(seqList1* s1);
//任意位置插入
void seqList_insPos(seqList1* s1, int pos, SLDataType val);
//任意位置删除
void seqList_delPos(seqList1* s1, int pos);

//销毁
void seqList_Destroy(seqList1* s1);
  1. Tes1204.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"seqList.h"


//初始化一个空的顺序表
void initseqList(seqList1* s1)
{
	if (s1 == NULL)
	{
		return;
	}
	s1->_data = NULL;
	s1->_size = 0;
	s1->_capacity = 0;
}

//判断是否为空 //1->空
int seqList_isEmpty(seqList1* s1)
{
	if (s1 == NULL)
	{
		return;
	}

	if (s1->_size == 0)
		return 1;
	else
		return 0;
}

//扩容
void seqListCheckCapacity(seqList1* s1)
{
	if (s1->_size == s1->_capacity)
	{
		//空间已满,扩容
		//1.开辟新空间
		int newCapacity = s1->_capacity == 0 ? 1 : 2 * s1->_capacity;
		SLDataType* tmp = (SLDataType*)malloc(newCapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			return;
		}
		//2.拷贝
		memcpy(tmp, s1->_data, sizeof(SLDataType) * s1->_size);

		//3.释放原有空间
		free(s1->_data);

		s1->_data = tmp;

		//用realloc等价于2.3两步
		//s1->_data = (SLDataType*)realloc(s1->_data, newCapacity * sizeof(SLDataType));

		//4.更新容量
		s1->_capacity = newCapacity;
	}
}

//尾插操作
void seqList_pushBack(seqList1* s1, SLDataType val)
{
	if (s1 == NULL)
	{
		return;
	}
	//容量检查
	seqListCheckCapacity(s1);
	//尾插
	s1->_data[s1->_size] = val;
	s1->_size++;
}

//尾删操作
void seqList_popBack(seqList1* s1)
{
	if (s1 == NULL)
	{
		return;
	}

	//假删除,只是看不到了
	if (s1->_size > 0)
		s1->_size--;
}

//打印
void seqList_print(seqList1* s1)
{
	if (s1 == NULL)
	{
		return;
	}

	for (int i = 0; i < s1->_size; ++i)
	{
		printf("%d ", s1->_data[i]);
	}
	printf("\n");
}

//访问某一个位置的元素
SLDataType seqList(seqList1* s1, int pos)
{
	if (s1 == NULL)
	{
		return;
	}
	if (seqList_isEmpty(s1))
		return -1;

	if (pos <= s1->_size)
		return s1->_data[pos];
	else
	{
		printf("位置错误!\n");
		return -1;
	}
}

//头插:给顺序表头部插入一个新的数据
void seqList_pushFront(seqList1* s1, SLDataType val)
{
	if (s1 == NULL)
	{
		return;
	}
	//容量检查
	seqListCheckCapacity(s1);
	//头插
	for (int i = s1->_size; i > 0; --i)
	{
		s1->_data[i] = s1->_data[i - 1];
	}
	s1->_data[0] = val;
	s1->_size++;
}

//头删
void seqList_popFront(seqList1* s1)
{
	if (s1 == NULL)
	{
		return;
	}
	for (int i = 0; i < s1->_size - 1; ++i)
	{
		s1->_data[i] = s1->_data[i + 1];
	}
	s1->_size--;
}

//任意位置插入
void seqList_insPos(seqList1* s1, int pos, SLDataType val)
{
	if (s1 == NULL)
	{
		return;
	}
	if (pos <= s1->_size && pos >= 0)
	{
		seqListCheckCapacity(s1);
		for (int i = s1->_size; i > pos; --i)
		{
			s1->_data[i] = s1->_data[i - 1];
		}
		s1->_data[pos] = val;
		s1->_size++;
	}
	else
	{
		printf("位置错误!\n");
		return;
	}
}

//任意位置删除
void seqList_delPos(seqList1* s1, int pos)
{
	if (s1 == NULL)
	{
		return;
	}
	if (seqList_isEmpty(s1))
		return;

	if (pos < s1->_size && pos >= 0)
	{
		for (int i = pos; i < s1->_size - 1; ++i)
		{
			s1->_data[i] = s1->_data[i + 1];
		}
		s1->_size--;
	}
	else
	{
		printf("位置错误!\n");
		return;
	}

}

//销毁
void seqList_Destroy(seqList1* s1)
{
	if (s1 == NULL || s1->_data == NULL)
	{
		return;
	}
	free(s1->_data);
	s1->_data == NULL;
}

void test()
{
	//栈上开辟的系统会自动销毁
	seqList1 s1;
	initseqList(&s1);
	seqList_pushBack(&s1, 1);
	seqList_pushBack(&s1, 2);
	seqList_pushBack(&s1, 3);
	seqList_pushBack(&s1, 4);
	seqList_pushBack(&s1, 5);
	seqList_pushFront(&s1, 0);
	seqList_print(&s1);
	seqList_popFront(&s1);
	seqList_print(&s1);
	seqList_pushFront(&s1, 0);
	seqList_print(&s1);
	seqList_delPos(&s1, 3);
	seqList_print(&s1);
	seqList_insPos(&s1, 5, 9);
	seqList_print(&s1);
	printf("\n=============\n");

	//堆上开辟的空间,需要销毁
	seqList1* s2 = (seqList1*)malloc(sizeof(seqList1));
	initseqList(s2);
	seqList_Destroy(s2);
	free(s2);
}

int main()
{
	test();
	system("pause");
	return 0;
}

顺序表特点

  1. 空间连续
  2. 支持随机访问
  3. 尾插、尾删操作:O(1)
  4. 空间利用率高,不容易造成内存碎片
  5. 其他位置(除了尾部)插入、删除:O(n)
  6. 增容的代价较大
  • 适合:访问、存储
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 14:16:53  更:2022-01-08 14:19:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 18:22:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码