顺序表基本操作

顺序表

  • 一、顺序表是什么?
  • 二、顺序表分类
    • 1. 静态顺序表:
    • 2. 动态顺序表:
  • 三、接口实现
    • 头文件
    • 设置顺序表大小
    • 设置顺序表最大容量
    • 顺序表初始化
    • 顺序表销毁
    • 顺序表打印
    • 顺序表尾插
    • 顺序表尾删
    • 顺序表头插
    • 顺序表头删
    • 判断顺序表是否为空
    • 查找元素位置
    • 在指定位置插入
    • 顺序表删除pos位置的值
    • 测试功能代码
    • 主函数
  • 总结
    • 完整代码

一、顺序表是什么?

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

二、顺序表分类

顺序表一般可以分为:

1. 静态顺序表:

使用定长数组存储元素。
顺序表基本操作_第1张图片

2. 动态顺序表:

使用动态开辟的数组存储。
顺序表基本操作_第2张图片

三、接口实现

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

头文件

#pragma once

#include 
#include 
#include 


typedef int SLDateType;
typedef struct SeqList
{
     
	SLDateType* a;
	size_t size;
	size_t capacity; // unsigned int
}SeqList;

// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestory(SeqList* ps);

void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType data);
void SeqListPushFront(SeqList* ps, SLDateType data);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType data);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDateType data);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos);

设置顺序表大小

int SeqListSize(SeqList* ps)
{
     
	assert(ps);
	return ps->size;
}

设置顺序表最大容量

int SeqListCapacity(SeqList* ps)
{
     
	assert(ps);
	return ps->capacity;
}

顺序表初始化

void SeqListInit(SeqList* ps, int initCapacity)
{
     
	assert(ps);
	ps->a = (int*)malloc(initCapacity * sizeof(int));
	if (NULL == ps->a)
	{
     
		assert(0);
		return;
	}
	ps->capacity = initCapacity;
	ps->size = 0;
}

顺序表销毁

void SeqListDestory(SeqList* ps)
{
     
	assert(ps);
	if (ps->a)
	{
     
		free(ps->a);
		ps->a = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}

顺序表打印

void SeqListPrint(SeqList* ps)
{
     
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
     
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

顺序表尾插

void SeqListPushBack(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	ps->a[ps->size] = data;
	ps->size++;
}

顺序表尾删

void SeqListPopBack(SeqList* ps)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		return;
	}
	ps->size--;
}

顺序表头插

void SeqListPushFront(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	for (int i = ps->size-1; i >=0; i--)
	{
     
		ps->a[i+1] = ps->a[i];
	}
	ps->size++;
	ps->a[0] = data;
}

顺序表头删

void SeqListPopFront(SeqList* ps)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		return;
	}

	for (int i = 0; i < ps->size; i++)
	{
     
		ps->a[i] = ps->a[i + 1];
	}

	ps->size--;
}

判断顺序表是否为空

int SeqListEmpty(SeqList* ps)
{
     
	assert(ps);
	return 0 == ps->size;
}

查找元素位置

int SeqListFind(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		printf("顺序表为空\n");
	}
	for (int i = 0; i < ps->size; i++)
	{
     
		if (data == ps->a[i]);
		return i;
	}
	printf("没有这个元素。\n");
	return -1;
}

在指定位置插入

void SeqListInsert(SeqList* ps, size_t pos, SLDateType data)
{
     
	assert(ps);
	ps->size++;
	if (SeqListEmpty(ps))
	{
     
		SeqListPushBack(ps, data);
	}
	for (int i = ps->size - 1; i > pos; i--)
	{
     
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = data;
}

顺序表删除pos位置的值

void SeqListErase(SeqList* ps, size_t pos)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		printf("顺序表为空。\n");
		return;
	}
	for (int i = pos; i < ps->size; i++)
	{
     
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

测试功能代码

void TestSeqList()
{
     
	SeqList s;
	SeqListInit(&s,10);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPrint(&s);
	SeqListPushFront(&s, 0);
	SeqListPrint(&s);
	SeqListInsert(&s, 4, 10);
	SeqListPrint(&s);
	SeqListErase(&s, 4);
	SeqListPrint(&s);
	printf("%d\n", SeqListSize(&s));
	printf("%d\n", SeqListCapacity(&s));

	SeqListDestory(&s);
}

主函数

#include"SeqList.h"

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

总结

顺序表的问题及思考:

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

完整代码

SeqList.h

#pragma once

#include 
#include 
#include 


typedef int SLDateType;
typedef struct SeqList
{
     
	SLDateType* a;
	size_t size;
	size_t capacity; // unsigned int
}SeqList;

// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestory(SeqList* ps);

void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType data);
void SeqListPushFront(SeqList* ps, SLDateType data);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType data);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDateType data);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos);

SeqList.c

#include"SeqList.h"

void SeqListInit(SeqList* ps, int initCapacity)
{
     
	assert(ps);
	ps->a = (int*)malloc(initCapacity * sizeof(int));
	if (NULL == ps->a)
	{
     
		assert(0);
		return;
	}
	ps->capacity = initCapacity;
	ps->size = 0;
}

void SeqListDestory(SeqList* ps)
{
     
	assert(ps);
	if (ps->a)
	{
     
		free(ps->a);
		ps->a = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}

void SeqListPrint(SeqList* ps)
{
     
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
     
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

void SeqListPushBack(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	ps->a[ps->size] = data;
	ps->size++;
}

void SeqListPopBack(SeqList* ps)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		return;
	}
	ps->size--;
}

void SeqListPushFront(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	for (int i = ps->size-1; i >=0; i--)
	{
     
		ps->a[i+1] = ps->a[i];
	}
	ps->size++;
	ps->a[0] = data;
}

void SeqListPopFront(SeqList* ps)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		return;
	}

	for (int i = 0; i < ps->size; i++)
	{
     
		ps->a[i] = ps->a[i + 1];
	}

	ps->size--;
}

int SeqListEmpty(SeqList* ps)
{
     
	assert(ps);
	return 0 == ps->size;
}

int SeqListFind(SeqList* ps, SLDateType data)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		printf("顺序表为空\n");
	}
	for (int i = 0; i < ps->size; i++)
	{
     
		if (data == ps->a[i]);
		return i;
	}
	printf("没有这个元素。\n");
	return -1;
}

void SeqListInsert(SeqList* ps, size_t pos, SLDateType data)
{
     
	assert(ps);
	ps->size++;
	if (SeqListEmpty(ps))
	{
     
		SeqListPushBack(ps, data);
		return;
	}
	for (int i = ps->size - 1; i > pos; i--)
	{
     
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = data;
}

void SeqListErase(SeqList* ps, size_t pos)
{
     
	assert(ps);
	if (SeqListEmpty(ps))
	{
     
		printf("顺序表为空。\n");
		return;
	}
	for (int i = pos; i < ps->size; i++)
	{
     
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

int SeqListSize(SeqList* ps)
{
     
	assert(ps);
	return ps->size;
}

int SeqListCapacity(SeqList* ps)
{
     
	assert(ps);
	return ps->capacity;
}

void TestSeqList()
{
     
	SeqList s;
	SeqListInit(&s,10);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPrint(&s);
	SeqListPushFront(&s, 0);
	SeqListPrint(&s);
	SeqListInsert(&s, 4, 10);
	SeqListPrint(&s);
	SeqListErase(&s, 4);
	SeqListPrint(&s);
	printf("%d\n", SeqListSize(&s));
	printf("%d\n", SeqListCapacity(&s));

	SeqListDestory(&s);
}

main.c

#include"SeqList.h"

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

你可能感兴趣的:(数据结构与算法,c语言,数据结构)