顺序表及其代码实现

目录

  • 前言
  • 1.顺序表
    • [1.1 顺序表介绍](#1.1 顺序表介绍)
    • [1.2 顺序表基本操作代码实现](#1.2 顺序表基本操作代码实现)
  • 总结

前言

顺序表一般不会用来单独存储数据,但自身的优势,很多时候不得不使用顺序表。

1.顺序表

1.1 顺序表介绍

顺序表是物理结构连续的线性表,支持随机存取 (底层是数组),存储密度大(只需存储数据元素,与链表相比,无需存储额外的指针)。缺点是,由于物理结构的连续,插入、删除要移动大量元素 ,时间复杂度为O(n),效率低下。

顺序表的组成如下,顺序表分为静态顺序表与动态顺序表。静态顺序表申请内存后不能更改,存在的问题是由于不确定需要的内存大小,如果开辟的内存块比较小,不够用;开辟过大,造成浪费。

动态顺序表可以在内存不够的时候调整顺序表的大小,注意,每次增加开辟的内存空间可以是原来内存的1~2倍,如果每次增加一个元素都要调整空间大小,效率太低。

1.2 顺序表基本操作代码实现

SeqList.h

c 复制代码
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//静态顺序表
//typedef int SLDataType;
//#define N 100000
//
//struct SeqList
//{
//	SLDataType a[N];
//	int size;
//};

//动态顺序表
typedef int SLDataType;
#define INIT_CAPACITY 4
typedef struct SeqList
{
	SLDataType* a;
	int size;
	int capacity;
}SL;

//增删查改
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
void SLPrint(SL* ps);
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);

void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
void SLCheckCapacity(SL* ps);
int SLFind(SL* ps,SLDataType x);

SeqList.c

c 复制代码
#include "SeqList.h"
void SLInit(SL* ps)
{
	assert(ps);
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);
	if (ps->a == NULL)
	{
		perror("malloc failed");
		return;
	}
	ps->size = 0;
	ps->capacity = INIT_CAPACITY;
}
void SLDestroy(SL* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
		printf("%d ", ps->a[i]);
	printf("\n");
}
void SLPushBack(SL* ps, SLDataType x)
{
	/*SLCheckCapacity(ps);
	ps->a[ps->size++] = x;*/
	SLInsert(ps, ps->size, x);
}
void SLPopBack(SL* ps)
{
	//assert(ps);
	//assert(ps->size > 0);
	//if (ps->size == 0)
		//return;
	ps->a[--ps->size] = 0;
	//ps->size--;
	SLErase(ps, ps->size - 1);
}
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc failed");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}
void SLPushFront(SL* ps, SLDataType x)
{
	/*SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;*/
	SLInsert(ps, 0, x);
}
void SLPopFront(SL* ps)
{
	/*assert(ps);
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
		ps->a[begin - 1] = ps->a[begin++];
	ps->size--;*/
	SLErase(ps, 0);
}
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
		ps->a[end + 1] = ps->a[end--];
	ps->a[pos] = x;
	ps->size++;
}
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;
	while (begin<ps->size)
		ps->a[begin-1] = ps->a[begin++];
	ps->size--;
}
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
			return i;
	}
	return -1;
}

Test.c

c 复制代码
#include "SeqList.h"
void TestSeqList1()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPushBack(&s, 5);
	SLPushBack(&s, 6);
	SLPushBack(&s, 7);
	SLPushBack(&s, 8);
	SLPushBack(&s, 9);
	SLPrint(&s);

	SLPopBack(&s);
	SLPopBack(&s);
	SLPrint(&s);

	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPrint(&s);

	SLPopBack(&s);

	SLPushBack(&s, 10);
	SLPushBack(&s, 20);
	SLPrint(&s);

	SLDestroy(&s);
}
void TestSeqList2()
{
	SL s;
	SLInit(&s);
	for (int i = 0; i < 10; i++)
		SLPushFront(&s, i);
	SLPrint(&s);

	SLPopFront(&s);
	SLPopFront(&s);
	SLPrint(&s);

	SLInsert(&s, 2, 40);
	SLPrint(&s);

	SLInsert(&s, 8, 30);
	SLPrint(&s);

	SLErase(&s, 4);
	SLPrint(&s);

	printf("%d\n", SLFind(&s, 40));
}
int main()
{
	TestSeqList2();
	/*void* ptr1 = malloc(5);
	printf("%p\n", ptr1);
	void* ptr2 = malloc(6);
	printf("%p\n", ptr2);*/
	return 0;
}

//顺序表可以结合菜单进行操作,但要保证函数代码实现没有问题,否则在菜单中难以调试
//void menu()
//{
//	printf("****************************************\n");
//	printf("******    1.尾插数据 2.尾删数据   ******\n");
//	printf("******    7.打印数据 0.退出程序   ******\n");
//	printf("****************************************\n");
//}
//int main()
//{
//	SL s;
//	SLInit(&s);
//	int option = -1;
//	while (option != 0)
//	{
//		menu();
//		scanf("%d", &option);
//		switch (option)
//		{
//		case 1:
//			printf("请依次输入要尾插的数据,以-1结束>:");
//			int x = 0;
//			while (x != -1)
//			{
//				scanf("%d", &x);
//				SLPushBack(&s, x);
//			}
//			break;
//		case 7:
//			SLPrint(&s);
//			break;
//		default:
//			break;
//		} 
//	}
//	return 0;
//}

总结

顺序表以及后续链表的学习都是对代码能力的锻炼,学习数据结构都是这个思路,逻辑结构、物理结构即基本操作实现。

相关推荐
huapiaoy8 分钟前
Redis中数据类型的使用(hash和list)
redis·算法·哈希算法
冷白白21 分钟前
【C++】C++对象初探及友元
c语言·开发语言·c++·算法
鹤上听雷29 分钟前
【AGC005D】~K Perm Counting(计数抽象成图)
算法
一叶祇秋41 分钟前
Leetcode - 周赛417
算法·leetcode·职场和发展
武昌库里写JAVA1 小时前
【Java】Java面试题笔试
c语言·开发语言·数据结构·算法·二维数组
ya888g1 小时前
GESP C++四级样题卷
java·c++·算法
Funny_AI_LAB1 小时前
MetaAI最新开源Llama3.2亮点及使用指南
算法·计算机视觉·语言模型·llama·facebook
NuyoahC1 小时前
算法笔记(十一)——优先级队列(堆)
c++·笔记·算法·优先级队列
jk_1011 小时前
MATLAB中decomposition函数用法
开发语言·算法·matlab
penguin_bark2 小时前
69. x 的平方根
算法