通讯录就是顺序表,只是常见的数据类型是整型,而通讯录储存的数据是自定义类型,实际上二者底层逻辑完全相同
一.Contact.h
自定义数据类型为联系人
#pragma once //保证头文件只预处理一次 #define NAME_MAX 20 #define GENDER_MAX 10 #define TEL_MAX 20 typedef struct PersonInfo { char name[NAME_MAX]; char gender[GENDER_MAX]; int age; char tel[TEL_MAX]; }peoInfo; typedef struct SeqList Contact; //将顺序表重命名为通讯录,便于理解 void ContactInit(Contact* con); void ContactDestroy(Contact* con); void ContactAdd(Contact* con); void ContactDel(Contact* con); void ContactModify(Contact* con); void ContactFind(Contact* con); void ContactShow(Contact* con);
二.seqlist.h
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include"Contact.h" #define INIT_CAPACITY 4 typedef peoInfo SLDataType; // 动态顺序表 -- 按需申请 typedef struct SeqList { SLDataType* a; int size; // 有效数据个数 int capacity; // 空间容量 }SL; //初始化和销毁 void SLInit(SL* ps); void SLDestroy(SL* ps); show //void SLPrint(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);
三.seqlist.c
1.顺序表的初始化
#include"seqlist.h" void SLInit(SL* ps) { ps->a = NULL; ps->capacity = 0; ps->size = 0; }
2. 顺序表的销毁
void SLDestroy(SL* ps) { if (ps->a) { free(ps->a); } ps->a = NULL; ps->capacity = 0; ps->size = 0; }
3.顺序表申请空间
//扩容 void SLCheckCapacity(SL* ps) { //SL* temp=NULL; if (ps->capacity == ps->size) { int newcapacity = ps->capacity == 0 ? INIT_CAPACITY : ps->capacity * 2; SLDataType* temp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType)); if (temp == NULL) { perror("realloc"); return; } ps->a = temp; ps->capacity = newcapacity; } }
成功申请空间后要将capacity的值更新,否则会出现运行错误
4. 尾部插入与删除
// 尾部插入 void SLPushBack(SL* ps, SLDataType x) { assert(ps); SLCheckCapacity(ps); ps->a[ps->size++] = x; } //尾部删除 void SLPopBack(SL* ps) { if (ps->size > 0) ps->size--; }
需要注意的是,元素个数的增减,要对size做处理
5.头部插入与删除
//头部插入 void SLPushFront(SL* ps, SLDataType x) { assert(ps); SLCheckCapacity(ps); for (int i = ps->size; i > 0; i--) { ps->a[i] = ps->a[i - 1]; } ps->a[0] = x; ps->size++; } //头部删除 void SLPopFront(SL* ps) { assert(ps); for (int i = 1; i < ps->size; i++) { ps->a[i - 1] = ps->a[i]; } ps->size--; }
注意对size做处理:++或--
6.指定位置前插入或删除
//指定位置之前插入数据 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->a[i] = ps->a[i - 1]; } ps->a[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->a[i] = ps->a[i + 1]; } ps->size--; }
四.Contact.c
1.通讯录的初始化与销毁
#include"Contact.h" #include"seqlist.h" void ContactInit(Contact* con) { SLInit(con); } void ContactDestroy(Contact* con) { SLDestroy(con); }
2.联系人的添加与删除
//添加 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); //自由选择之前所写的通讯录(顺序表)插入函数 SLPushBack(con, info); } //查找 int FindByName(Contact* con, char name[]) { for (int i = 0; i < con->size; i++) { if (0 == strcmp(con->a[i].name, name))//strcmp:字符串的比较函数,返回值为0则相等 { return i; } } return -1; } //删除 void ContactDel(Contact* con) { char name[NAME_MAX]; printf("请输入要删除的联系人姓名:\n"); scanf("%s", name); int find = FindByName(con, name); if (find < 0) { printf("该联系人不存在!"); return; } SLErase(con, find); printf("删除成功!\n"); }
3.联系人的信息修改
//查找 int FindByName(Contact* con, char name[]) { for (int i = 0; i < con->size; i++) { if (0 == strcmp(con->a[i].name, name)) { return i; } } return -1; } void ContactModify(Contact* con) { char name[NAME_MAX]; printf("请输入要修改的联系人的姓名:\n"); scanf("%s", name); int find = FindByName(con, name); if (find < 0) { printf("该联系人不存在!"); return; } printf("请输入新的姓名:\n"); scanf("%s", con->a[find].name); printf("请输入新的性别:\n"); scanf("%s", con->a[find].gender ); printf("请输入新的年龄:\n"); scanf("%d", &con->a[find].age); printf("请输入新的电话:\n"); scanf("%s", con->a[find].tel); printf("修改成功!!!\n"); }
4.联系人的查找
//查找 int FindByName(Contact* con, char name[]) { for (int i = 0; i < con->size; i++) { if (0 == strcmp(con->a[i].name, name)) { return i; } } return -1; } void ContactFind(Contact* con) { char name[NAME_MAX]; printf("请输入要查找的联系人的姓名:\n"); scanf("%s", name); int find = FindByName(con, name); if (find < 0) { printf("该联系人不存在!"); return; } printf("姓名 性别 年龄 电话\n"); printf("%s %s %d %s\n", con->a[find].name,con->a[find].gender, con->a[find].age,con->a[find].tel); }
5.联系人的展示
void ContactShow(Contact* con) { printf("姓名 性别 年龄 电话\n"); for (int i = 0; i < con->size; i++) { printf("%s %s %d %s\n", con->a[i].name,con->a[i].gender, con->a[i].age,con->a[i].tel); } }
五.text.c
#include"seqlist.h" void ContactTest01() { Contact con; ContactInit(&con); ContactAdd(&con); ContactAdd(&con); ContactShow(&con); ContactModify(&con); ContactShow(&con); ContactDel(&con); ContactShow(&con); ContactFind(&con); ContactDestroy(&con); } int main() { ContactTest01(); return 0; }