【数据结构与算法】线性表之-顺序表

本文详细介绍了线性表的概念,特别是动态顺序表的实现,包括初始化、扩容、头插、尾插、头删、尾删等基本操作,并提供了查找、替换、插入和删除数据的扩展功能。示例代码展示了顺序表的C语言实现,以及一个简单的测试程序,便于理解和应用。
摘要由CSDN通过智能技术生成

目录

前言

一、线性表是什么?

二、顺序表

1.概念

2. 接口实现

1.初始化

2.扩容

3.头插数据

4.尾插数据

3.头删数据

4.尾删数据

5.打印数据

三、实现效果

四、扩展

1.查找数据

2.替换数据

3.插入数据

4.删除数据

5.修改数据

五、示例代码

1.SeqList.h

2.SeqList.c

3.test.c

总结



前言



一、线性表是什么?

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上线性结构,也就说是连续的一条直线。但是在物理结构上并不一定连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。


二、顺序表


1.概念

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

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

// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
    SLDataType a[N]; // 定长数组
    int size; //有效数据的个数
}SL;

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

// 顺序表的动态存储
typedef struct SeqList
{
    SLDataType* a; // 指向动态开辟的数组
    int size ; // 有效数据个数
    int capicity ; // 容量空间的大小
}SL;


2. 接口实现

1.初始化

void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

2.扩容

void SeqListCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SQDataType* tmp = (SQDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(SQDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			ps->a = tmp;
			ps->capacity = newcapacity;
		}
	}
}

3.头插数据

void SeqListPushFront(SL* ps, SQDataType x)
{
	SeqListCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;
}

4.尾插数据

void SeqListPushBack(SL* ps, SQDataType x)
{
	SeqListCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

3.头删数据

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);
	int start = 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		++start;
	}
	ps->size--; 
}

4.尾删数据

void SeqListPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

5.打印数据

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

三、实现效果

四、扩展

1.查找数据

(输入位置查找该位置的数据是什么)

int SeqListFind(SL* ps, SQDataType x)
{
	for (int i = 0; i < ps->size; ++i)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

2.替换数据

void SeqListModity(SL* ps, int pos, SQDataType x)
{
	assert(pos < ps->size);
	ps->a[pos] = x;
}

3.插入数据

void SeqListInsert(SL* ps, int pos, SQDataType x)
{
	assert(pos <= ps->size);
	SeqListCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps ->a[pos] = x;
	ps->size++;
}

4.删除数据

void SeqListErase(SL* ps, int pos)
{
	assert(pos < ps->size);
	int  start = pos + 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		++start;
	}
	ps->size--;
}

5.修改数据

void SeqListModity(SL* ps, int pos, SQDataType x)
{
	assert(pos < ps->size);
	ps->a[pos] = x;
}

五、示例代码

1.SeqList.h

#pragma once

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

// 增强程序可维护性
#define MAX_SIZE 100
typedef int SQDataType;

//静态顺序表
//typedef struct SeqList
//{
//    SQDataType a[MAX_SIZE]; // 定长数组
//    int size; //有效数据的个数
//}SL;
//动态顺序表
typedef struct SeqList
{
    SQDataType* a; // 指向动态开辟的数组
    int size; // 有效数据个数
    int capacity; // 容量空间的大小
}SL;

//初始化
void SeqListInit(SL* ps);
//打印
void SeqListPrint(SL* ps);
//扩容
void SeqListCheckCapacity(SL* ps);
//头插 尾插 头删 尾删
void SeqListPushBack(SL* ps, SQDataType x);
void SeqListPushFront(SL* ps, SQDataType x);
void SeqListPopBack(SL* ps);
void SeqListPopFront(SL* ps);
//插入和删除
void SeqListInsert(SL* ps, int pos, SQDataType x);
void SeqListErase(SL* ps, int pos);
//销毁
void SeqListDestory(SL* ps);
//查找
int SeqListFind(SL* ps, SQDataType x);
//修改
void SeqListModity(SL* ps, int pos, SQDataType x);

2.SeqList.c

#include "SeqList.h"

//void SeqListInit(SL* ps)
//{
//	
//	memset(ps->a, 0, sizeof(SQDataType) * MAX_SIZE);
//	ps->size = 0;
//}
//
//void SeqListPushBack(SL* ps, SQDataType x)
//{
//	if (ps->size >= MAX_SIZE)
//	{
//		printf("");
//		return 0;
//	}
//	ps->a[ps->size] = x;
//	ps->size++;
//}

void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

//满了扩容
void SeqListCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SQDataType* tmp = (SQDataType*)realloc(ps->a, newcapacity * 2 * sizeof(SQDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			ps->a = tmp;
			ps->capacity = newcapacity;
		}
	}
}

void SeqListPushBack(SL* ps, SQDataType x)
{
	/*SeqListCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;*/
	SeqListInsert(ps, ps->size, x);
}

void SeqListPushFront(SL* ps, SQDataType x)
{
	/*SeqListCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;*/
	SeqListInsert(ps, 0, x);
}

void SeqListPopBack(SL* ps)
{
	/*assert(ps->size > 0);
	ps->size--;*/
	SeqListErase(ps, ps->size - 1);
}

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);
	/*int start = 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		++start;
	}
	ps->size--; */
	SeqListErase(ps, 0);
}

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

void SeqListInsert(SL* ps, int pos, SQDataType x)
{
	assert(pos <= ps->size);
	SeqListCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps ->a[pos] = x;
	ps->size++;
}

void SeqListErase(SL* ps, int pos)
{
	assert(pos < ps->size);
	int  start = pos + 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		++start;
	}
	ps->size--;
}

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

int SeqListFind(SL* ps, SQDataType x)
{
	for (int i = 0; i < ps->size; ++i)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

void SeqListModity(SL* ps, int pos, SQDataType x)
{
	assert(pos < ps->size);
	ps->a[pos] = x;
}

3.test.c

#define _CRT_SECURE_NO_WARNINGS
#include "SeqList.h"

void menu()
{
	printf("********************************************\n");
	printf("***1.尾插数据************2.头插数据*********\n");
	printf("***3.尾删数据************4.头删数据*********\n");
	printf("***5.打印数据************-1.退出************\n");
	printf("********************************************\n");
	printf( "请输入你操作选项:" );
}

int main()
{
	int control = 0;
	SL s;
	SeqListInit(&s);
	int x = 0;
	while (control != -1)
	{
		menu();
		scanf("%d",&control);
		switch (control)
		{
		case 1:
			printf("请输入你要插入的数据,以-1结束\n");  
			do 
			{
				scanf("%d",&x);
				if (x != -1)
				{
					SeqListPushBack(&s, x);
				}
			} while (x != -1);
			break;		
		case 2:
			printf("请输入你要插入的数据,以-1结束\n");
			do
			{
				scanf("%d", &x);
				if (x != -1)
				{
					SeqListPushFront(&s, x);
				}
			} while (x != -1);
			break;
		case 3:
			printf("请输入你要删除的数据位置,以-1结束\n");
			do
			{
				scanf("%d", &x);
				if (x != -1)
				{
					SeqListPopBack(&s, x);
				}
			} while (x != -1);
			break;
		case 4:
			printf("请输入你要删除的数据位置,以-1结束\n");
			do
			{
				scanf("%d", &x);
				if (x != -1)
				{
					SeqListPopFront(&s, x);
				}
			} while (x != -1); 
			break;
		case 5:
			SeqListPrint(&s);
			break;
		default:
			break;
		}
	}
	SeqListDestory(&s);
	return 0;
}


总结

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愿百事可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值