目录
[1.1 SeqList.h](#1.1 SeqList.h)
[1.2 SeqList.c](#1.2 SeqList.c)
[2.1 Contact.h](#2.1 Contact.h)
[2.2 Contact.c](#2.2 Contact.c)
[2.3 SeqList.h](#2.3 SeqList.h)
[2.4 SeqList.c](#2.4 SeqList.c)
[2.5 main.c](#2.5 main.c)
一、顺序表源代码
顺序表的底层实现为数组,源代码以整形数据为例,使用C语言编写
1.1 SeqList.h
cpp
typedef int SLDataType;
//动态顺序表
typedef struct SeqList
{
SLDataType* arr;//数据类型
int size; //有效数据个数
int capacity; //空间大小
}SL;
//顺序表初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//顺序表的打印
void SLPrint(SL s);
//头部插入
void SLPushFront(SL* ps, SLDataType x);
//尾部插入
void SLPushBack(SL* ps, SLDataType x);
//头部删除
void SLPopFront(SL* ps);
//尾部插入
void SLPopBack(SL* ps);
//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//指定位置擦除数据
void SLErase(SL* ps, int pos);
//寻找数据
int SLFind(SL* ps, SLDataType x);
1.2 SeqList.c
cpp
#include"SeqList.h"
void SLPrint(SL s)
{
for (int i = 0; i < s.size; i++)
{
printf("%d ", s.arr[i]);
}
printf("\n");
}
//顺序表的初始化
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
if (ps->arr != NULL)
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
//检查空间是否足够
void SLCheckCapacity(SL* ps)
{
//插入数据之前先看空间够不够
if (ps->capacity == ps->size)
{
int newCapacity = 0;
if (ps->capacity == 0)
{
newCapacity = 4;
}
else
{
newCapacity = 2 * ps->capacity;
}
SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);
}
//空间申请成功
ps->arr = tmp;
ps->capacity = newCapacity;
}
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{
//温柔的解决方式
if (ps == NULL)
{
return 1;
}
SLCheckCapacity(ps);
ps->arr[ps->size++] = x;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
//先让顺序表中已有的数据整体往后挪动一位
for (int i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[0] = x;
ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps->size);
--ps->size;
}
//头删
void SLPopFront(SL* ps)
{
assert(ps);
assert(ps->size);
//数据整体往前挪动一位
for (int i = 0; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//指定位置前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
SLCheckCapacity(ps);
//向后移动数据
for (int i = ps->size ; i > pos ; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;
ps->size++;
}
//指定位置擦除数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//寻找数据
int SLFind(SL* ps, SLDataType x)
{
assert(ps);
int i = 0;
for (; i < ps->size; i++)
{
if (ps->arr[i] == x)
{
return i;
break;
}
}
if (i+1==ps->size )
{
return -1;
}
}
二、顺序表的应用
实现基础通讯录的编写,本文使用C语言编写。基于顺序表的底层逻辑,仅仅将数据类型修改为了自定义数据类型-结构体。
2.1 Contact.h
cpp
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDRESS_MAX 100
//定义联系人自定义数据类型
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char address[ADDRESS_MAX];
}peoInfo;
typedef struct SeqList Contact;
// 初始化通讯录
void ContactInit(Contact* con);
// 添加通讯录数据
void ContactAdd(Contact* con);
// 删除通讯录数据
void ContactDel(Contact* con);
// 展⽰通讯录数据
void ContactShow(Contact* con);
// 查找通讯录数据
void ContactFind(Contact* con);
// 修改通讯录数据
void ContactModify(Contact* con);
// 销毁通讯录数据
void ContactDestroy(Contact* con);
2.2 Contact.c
cpp
#include"Contact.h"
#include"SeqList.h"
int FindByname(Contact* con, char* cmp)
{
for (int i = 0; i < con->size; i++)
{
if (strcmp(con->arr[i].name, cmp) == 0)
{
return i;
break;
}
}
return -1;
}
// 初始化通讯录
void ContactInit(Contact* con)
{
SLInit(con);
}
// 添加通讯录数据
void ContactAdd(Contact* con)
{
peoInfo info;
printf("请输入要添加的联系人姓名\n");
scanf("%s", info.name);
printf("请输入要添加的联系人性别\n");
scanf("%s", info.gender);
printf("请输入要添加的联系人年龄\n");
scanf("%d", &info.age);
printf("请输入要添加的联系人电话\n");
scanf("%s", info.tel);
printf("请输入要添加的联系人住址\n");
scanf("%s", info.address);
SLPushBack(con, info);
}
// 删除通讯录数据
void ContactDel(Contact* con)
{
char name[NAME_MAX];
printf("请输入要删除的联系人姓名\n");
scanf("%s", name);
int ret = FindByname(con, name);
if (ret >= 0)
{
SLErase(con, ret);
printf("删除成功!\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
// 展⽰通讯录数据
void ContactShow(Contact* con)
{
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
for (int i = 0; i < con->size; i++)
{
printf("%s ", con->arr[i].name );
printf("%s ", con->arr[i].gender );
printf("%d ", con->arr[i].age );
printf("%s ", con->arr[i].tel );
printf("%s ", con->arr[i].address );
printf("\n");
}
}
// 查找通讯录数据
void ContactFind(Contact* con)
{
char name[NAME_MAX];
printf("请输入要查找的联系人姓名\n");
scanf("%s", name);
int ret = FindByname(con, name);
if (ret>=0)
{
printf("查找成功!\n");
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%s ", con->arr[ret].name);
printf("%s ", con->arr[ret].gender);
printf("%d ", con->arr[ret].age);
printf("%s ", con->arr[ret].tel);
printf("%s ", con->arr[ret].address);
printf("\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
// 修改通讯录数据
void ContactModify(Contact* con)
{
char name[NAME_MAX];
printf("请输入要修改的联系人姓名\n");
scanf("%s", name);
int ret = FindByname(con, name);
if (ret >= 0)
{
printf("请输入新的联系人姓名\n");
scanf("%s", con->arr[ret].name);
printf("请输入新的联系人性别\n");
scanf("%s", con->arr[ret].name);
printf("请输入新的联系人年龄\n");
scanf("%d", &(con->arr[ret].age));
printf("请输入新的联系人电话\n");
scanf("%s", con->arr[ret].tel);
printf("请输入新的联系人住址\n");
scanf("%s", con->arr[ret].address);
printf("修改成功!\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
// 销毁通讯录数据
void ContactDestroy(Contact* con)
{
SLDestroy(con);
}
2.3 SeqList.h
cpp
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
#include<string.h>
typedef peoInfo SLDataType;
typedef struct SeqList
{
SLDataType* arr;
int size;
int capacity;
}SL;
//顺序表初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//顺序表的打印
void SLPrint(SL s);
//头部插入
void SLPushFront(SL* ps, SLDataType x);
//尾部插入
void SLPushBack(SL* ps, SLDataType x);
//头部删除
void SLPopFront(SL* ps);
//尾部删除
void SLPopBack(SL* ps);
//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//指定位置擦除数据
void SLErase(SL* ps, int pos);
2.4 SeqList.c
cpp
#include"SeqList.h"
//顺序表初始化
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->capacity = 0;
ps->size = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
assert(ps);
if (ps->arr != NULL)
{
free(ps->arr);
}
ps->capacity = 0;
ps->size = 0;
}
void SLCheck(SL* ps)
{
assert(ps);
if (ps->capacity == ps->size)
{
int newCapacity = 0;
if (ps->capacity == 0)
{
newCapacity = 4;
}
else
{
newCapacity = 2 * ps->capacity;
}
SLDataType* temp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
if (temp == NULL)
{
perror("realloc fail!");
exit(1);
}
//空间申请成功
ps->arr = temp;
ps->capacity = newCapacity;
}
}
//头部插入
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheck(ps);
for (int i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[0] = x;
ps->size++;
}
//尾部插入
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
SLCheck(ps);
ps->arr[ps->size++] = x;
}
//头部删除
void SLPopFront(SL* ps)
{
assert(ps);
for (int i = 0; i < ps->size-1 ; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//尾部删除
void SLPopBack(SL* ps)
{
assert(ps);
ps->size--;
}
//指定位置前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
SLCheck(ps);
//向后移动数据
for (int i = ps->size; i > pos; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;
ps->size++;
}
//指定位置擦除数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
2.5 main.c
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"SeqList.h"
#include"Contact.h"
void menu()
{
printf("******************通讯录******************\n");
printf("*******1.增加联系人 2.删除联系人********\n");
printf("*******3.修改联系人 4.查找联系人********\n");
printf("*******5.展示联系人 0. 退出 *********\n");
printf("******************************************\n");
}
int main()
{
int a = -1;
Contact con;
ContactInit(&con);
do {
menu();
printf("请选择您的操作:\n");
scanf("%d", &a);
switch (a)
{
case 1:
ContactAdd(&con);
break;
case 2:
ContactDel(&con);
break;
case 3:
ContactModify(&con);
break;
case 4:
ContactFind(&con);
break;
case 5:
ContactShow(&con);
break;
case 0:
printf("退出通讯录....\n");
break;
default:
printf("输入错误,请重新选择您的操作!\n");
break;
}
} while (a != 0);
ContactDestroy(&con);
return 0;
}