前言
大家好,我是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;
}
总结
顺序表的有点事可以连续存储数据,可以随机访问数据。缺点是尾插尾删效率低。
以上就是这篇文章的全部内容,欢迎大家学习交流。