【数据结构】【C语言】------- 顺序表

前言

大家好,我是Abert。

这篇文章和大家分享C语言实现数据结构的顺序表。顺序表也是之后的数据结构的学习的基础,整体实现过程也不复杂,和通讯录类似。下面我们一起来学习顺序表吧!!!


文章目录

1、程序基本框架的搭建与讲解

        1.1 文件的创建

        1.2 变量的创建与声明

2、各种功能的实现及逻辑关系的讲解

        2.1 菜单

        2.2 尾插

        2.3 头插

        2.4 尾删

        2.5 头删

        2.6 任意位置插入

        2.7 任意位置删除数据

        2.8 查找数据

        2.9 修改任意位置的数据         

        2.10 销毁程序

3、完整代码

        3.1 SeqList.h

        3.2 SeqList.c

        3.3 test.c


正文

一、程序基本框架的搭建与讲解

1.1 文件的创建

类似于通讯录,顺序表也需要三个文件。

头文件:SeqList.h

源文件:SeqList.c

               test.c

SeqList.h中存放函数的声明和程序所需要的头文件

SeqList.c中存放实现顺序表功能的代码

 test.c是整个程序结构的主题,引用前两个文件并测试功能。

1.2 变量的创建与声明

        该过程放入SeqList.h中

typedef int SLDataType;

typedef struct SeqList
{
	SLDataType* a;//指向动态数组指针
	int size;// 数据个数
	int capacity; // 容量 - 空间大小

}SL;

二、各种功能的实现及逻辑关系的讲解

2.1 菜单

void menu()
{
	printf("---------------------------------------\n");
	printf("***************************************\n");
	printf("**** 1.PushBack        2.PushFront ****\n");
	printf("**** 3.PopBack         4.PopFront  ****\n");
	printf("**** 5.SLInsert        6.SLErase   ****\n");
	printf("**** 7.SLFind          8.SLModify  ****\n");
	printf("**** 0.exit                        ****\n");
	printf("***************************************\n");
	printf("---------------------------------------\n");

	//1.尾插
	//2.头插
	//3.尾删
	//4.头删
	//5.任意位置插入
	//6.任意位置删除数据
	//7.查找数据
	//8.修改任意位置的数据
	//0.退出并销毁程序
}

2.2 尾插

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);

	void SLCheckCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}

2.3 头插

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);

	SLCheckCapacity(ps);

	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}

	ps->a[0] = x;
	ps->size++;
}

2.4 尾删

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	//温柔检查
	/*if (ps->size == 0)
	{
		printf("SeqList is empty\n");
		return;
	}*/

	//暴力检查
	assert(ps->size > 0);
	
	ps->size--;
}

2.5 头删

//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);

	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}

	ps->size--;
}

2.6 任意位置插入

//在任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);

	SLCheckCapacity(ps);

	// 挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}

	ps->a[pos] = x;
	ps->size++;
}

2.7 任意位置删除数据

//任意位置删除
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];
		++begin;

	}

	ps->size--;
}

2.8 查找数据


// 查找
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; ++i)
	{
		if (ps->a[i] == x)
			return 1;
	}

	return -1;
}

2.9 修改任意位置的数据

//改变指定位置的数据
void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);

	ps->a[pos] = x;
}

2.10 销毁程序

//销毁
void SLDestory(SL* ps)
{
	assert(ps);

	if (ps->a)
	{
		free(ps->a);
		ps->a = NULL;
		ps->capacity = ps->size = 0;
	}
}

三、完整代码

3.1 SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef int SLDataType;

typedef struct SeqList
{
	SLDataType* a;//指向动态数组指针
	int size;// 数据个数
	int capacity; // 容量 - 空间大小

}SL;

// 打印顺序表

void SLPrint(SL* ps);

//增删查改
void SLInit(SL* ps);
void SLDestory(SL* ps);

void SLCheckCapacity(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);

//查找
int SLFind(SL* ps, SLDataType x);

//修改
void SLModify(SL* ps, int pos, SLDataType x);

3.2 SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

//打印
void SLPrint(SL* ps)
{
	assert(ps);

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

}


//初始化
void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}


//销毁
void SLDestory(SL* ps)
{
	assert(ps);

	if (ps->a)
	{
		free(ps->a);
		ps->a = NULL;
		ps->capacity = ps->size = 0;
	}
}


//检查
void SLCheckCapacity(SL* ps)
{
	//检查容量空间,满了扩容
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("relloc fail\n");
			return;
		}

		ps->a = tmp;
		ps->capacity = newcapacity;
	}

}

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);

	void SLCheckCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}


//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	//温柔检查
	/*if (ps->size == 0)
	{
		printf("SeqList is empty\n");
		return;
	}*/

	//暴力检查
	assert(ps->size > 0);
	
	ps->size--;
}

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);

	SLCheckCapacity(ps);

	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}

	ps->a[0] = x;
	ps->size++;
}

//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);

	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}

	ps->size--;
}

//在任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);

	SLCheckCapacity(ps);

	// 挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--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];
		++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 1;
	}

	return -1;
}

//改变指定位置的数据
void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);

	ps->a[pos] = x;
}

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void menu()
{
	printf("---------------------------------------\n");
	printf("***************************************\n");
	printf("**** 1.PushBack        2.PushFront ****\n");
	printf("**** 3.PopBack         4.PopFront  ****\n");
	printf("**** 5.SLInsert        6.SLErase   ****\n");
	printf("**** 7.SLFind          8.SLModify  ****\n");
	printf("**** 0.exit                        ****\n");
	printf("***************************************\n");
	printf("---------------------------------------\n");

	//1.尾插
	//2.头插
	//3.尾删
	//4.头删
	//5.任意位置插入
	//6.任意位置删除数据
	//7.查找数据
	//8.修改任意位置的数据
	//0.退出并销毁程序
}


int SetNum()
{
	int num = 0;
	printf("请输入要操作的数字:>");
	scanf("%d", &num);
	return num;
}

int POS()
{
	int pos = 0;
	printf("请输入位置:>");
	scanf("%d", &pos);
	return pos;
}


void SeqlTest()
{
	SL sl;
	SLInit(&sl);

	int input = 1;
	do
	{
		menu();
		printf("请输入要执行的操作:>");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			SLPushBack(&sl, SetNum());
			break;
		case 2:
			SLPushFront(&sl, SetNum());
			break;
		case 3:
			SLPopBack(&sl);
			break;
		case 4:
			SLPopFront(&sl);
			break;
		case 5:
			SLInsert(&sl, POS(), SetNum());
			break;
		case 6:
			SLErase(&sl, POS());
			break;
		case 7:
			SLFind(&sl, SetNum());
			break;
		case 8:
			SLModify(&sl, POS(), SetNum());
			break;
		case 0:
			SLDestory(&sl);
			break;
		default:
			printf("输入错误,请重新输入!!!\n");
			break;
		}

	} while (input);
}


int main()
{
	SeqlTest();
	return 0;
}

总结

顺序表的有点事可以连续存储数据,可以随机访问数据。缺点是尾插尾删效率低。

以上就是这篇文章的全部内容,欢迎大家学习交流。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值