顺序表

线性表(线性存储)

2.1线性表

这是一种线性结构,含有n>=0个结点的有序列,其中的结点,有且只有一个开始结点,它没有前驱但有一个后继结点;有且只有一个终端结点,它没有后继但有一个前驱结点;其他结点都有一个前驱和一个后继。

线性表在计算机的存储基本上都是采用顺序存储链式存储两种方式。

2顺序表

2.2.1基本概念及描述

线性表采用顺序存储的方式存储。将表中的结点依次存放在计算机内存中一组连续的存储单元中 ,只需找到顺序表中第一个结点的存储地址,就可以访问顺序表中的任意结点。而数组中的元素是可以随机访问的,所以可以使用数组来表示顺序表。

2.2.2顺序表的实现

数组的下标是从0开始的,下标为i的元素对应的是第i+1个结点.

顺序表又分为静态顺序表动态顺序表,静态顺序表使用了定长数组存储元素

typedef int datatype;
#define N 7
typedef struct
{
    datatype a[N];
    int size;
}Sqlist;

缺陷:空间少了不够用,给多了会造成空间浪费

所以这里我们使用动态顺序表,按需申请,避免空间浪费

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

typedef int datatype;
typedef struct
{
	datatype* a;
	int size;
	int capacity;
}Sqlist;

void display(Sqlist slt);//打印顺序表
void init(Sqlist* slt);//初始化
void CheckCapacity(Sqlist* slt);//扩容
void append(Sqlist* slt, datatype x);//尾插
void insert(Sqlist* slt, datatype x,int position);//在指定位置插入数据x
void del(Sqlist* slt, int postion);//删除指定位置的数据
int find(Sqlist slt, datatype x);//查找x在顺序表中的位置,返回其位置
void Destroy(Sqlist* slt);//销毁顺序表

(1)打印顺序表

void display(Sqlist slt)
{
	if (!slt.size)
		printf("顺序表是空的\n");
	else
	{
		for (size_t i = 0; i < slt.size; i++)
		{
			printf("%d ", slt.a[i]);
		}
		printf("\n");
	}
}

(2)初始化

void init(Sqlist* slt)
{
	slt->a = NULL;
	slt->size =slt->capacity= 0;
}

(3)扩容

void CheckCapacity(Sqlist* slt)
{
	if (slt->size == slt->capacity)//扩容
	{
		int newcapacity = slt->capacity == 0 ? 4 : 2 * slt->capacity;
		datatype* tmp = (datatype*)realloc(slt->a, sizeof(datatype) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		slt->a = tmp;
		slt->capacity = newcapacity;
	}
}

(4)尾插

void append(Sqlist* slt, datatype x)
{
	CheckCapacity(slt);
	slt->a[slt->size++] = x;
}

(5)指定位置插入

花费的时间主要是元素后移操作,将position以及以后的元素向后移动一位,在position上插入x,该算法最好的情况是数据没有移动,就是尾插,最坏就是全部移动,时间复杂度取平均为n/2,时间复杂度为O(n)

void insert(Sqlist* slt, datatype x, int position)
{
	assert(slt);
	assert(position >= 0 && position < slt->size);
	CheckCapacity(slt);
	for (int i = slt->size; i > position; i--)
	{
		slt->a[i] = slt->a[i - 1];
	}
	slt->a[position] = x;
	slt->size++;
}

(6)指定位置删除

将pos位置之后的元素整体向前移动一位,时间复杂度为O(n)

void del(Sqlist* slt, int position)
{
	assert(slt);
	assert(position >= 0 && position < slt->size);
	for (int i = position; i < slt->size - 1; i++)
	{
		slt->a[i] = slt->a[i + 1];
	}
	slt->size--;
}

(7)查找

int find(Sqlist slt, datatype x)
{
	for (int i = 0; i < slt.size; i++)
	{
		if (slt.a[i] == x)
			return i;
	}
	return -1;
}

(8)销毁

void Destroy(Sqlist* slt)
{
	if (slt->a)
	{
		free(slt->a);
	}
	slt->a = NULL;
	slt->capacity = slt->size = 0;
}
posted @ 2024-08-16 21:11  kio鱼  阅读(24)  评论(0编辑  收藏  举报