🚀前言
大家好!我是 EnigmaCoder。
本文介绍线性表的实验,使用顺序表和链表实现通讯录管理,包含初始化、插入、删除、查询、输出。
🦜任务目标
-
线性表数据结构应用:利用顺序表和链表实现动态存储通讯录信息,包括初始化、插入、删除、查询和遍历功能。
-
核心算法实现:
-
动态扩容机制(
realloc
实现顺序表空间扩展); -
按学号/姓名的精准查询(基于自定义比较函数);
-
元素的插入与删除(涉及数据移位操作)。
- 学生数据样例:
学号(num) | 姓名(name) | 性别(sex) | 电话号码(tel) | QQ号码(qq) | 备注 |
---|---|---|---|---|---|
1001 | 张三 | 男 | 13812345678 | 1234567890 | 常规数据(男) |
1002 | 李四 | 女 | 13987654321 | 9876543210 | 常规数据(女) |
1003 | 王芳 | 女 | 15800001111 | 456789123 | QQ号为9位(合法) |
1010 | 刘畅 | 男 | 18666668888 | 123456789012 | QQ号为12位(最大值) |
🌟顺序表实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LIST_INIT_SIZE 10
#define LISTIHCREAHENT 5
typedef struct {
int num;
char name[20];
char sex[3];
char tel[14];
char qq[12];
}ElemType;
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
int InitList_Sq(SqList& L) {
L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if (!L.elem)exit(-1);
L.length = 0;
L.listsize = LIST_INIT_SIZE;
}
int ListInsert_Sq(SqList& L, int i, ElemType e) {
ElemType* newbase;
if (i<1 || i>L.length + 1) {
return 0;
}
if (L.length == L.listsize) {
newbase = (ElemType*)realloc(L.elem, (LIST_INIT_SIZE + LISTIHCREAHENT) * sizeof(ElemType));
if (!L.elem)exit(-1);
L.elem = newbase;
L.listsize += LISTIHCREAHENT;
}
for (int j = L.length - 1; j >= i - 1; j--) {
L.elem[j + 1] = L.elem[j];
}
L.elem[i - 1] = e;
L.length++;
return 1;
}
int ListDelete_Sq(SqList& L, int i, ElemType& e) {
if (i<0 || i>L.length)return 0;
for (int j = i ; j <= L.length-1; j++) {
L.elem[j-1] = L.elem[j];
}
L.length--;
return 1;
}
int LocateElem_Sq(SqList L, ElemType e, int(*equal)(ElemType, ElemType)) {
int i = 1;
while (i <= L.length && !equal(e, L.elem[i - 1])) i++;
if (i <= L.length) return 1;
else return 0;
}
int comparebynum(ElemType x, ElemType y) {
return x.num == y.num ? 1 : 0;
}
int comparebyname(ElemType x, ElemType y) {
if (strcmp(x.name, y.name) == 0)return 1;
else return 0;
}
void inputOne(ElemType& x) {
scanf("%d%s%s%s%s", &x.num, x.name, x.sex, x.tel, x.qq);
}
void outputOne(ElemType x) {
printf("%d\t%s\t%s\t%s\t%s\n", x.num, x.name, x.sex, x.tel, x.qq);
}
void Output(SqList L) {
for (int i = 0; i <= L.length-1; i++) {
outputOne(L.elem[i]);
}
}
int main() {
SqList L;
int choice,i,y,m;
ElemType e,t,x;
do
{
printf(" 通讯录管理系统\n");
printf("====================================\n");
printf(" 0:退出\n");
printf(" 1:建立通讯录\n");
printf(" 2:插入\n");
printf(" 3:删除\n");
printf(" 4:查询\n");
printf(" 5:输出\n");
printf("====================================\n");
printf("请选择0-5\n");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(1);
case 1: InitList_Sq(L);break;
case 2: printf("input i:");scanf("%d",&i);
printf("input one record:");inputOne(e);
ListInsert_Sq(L,i,e);break;
case 3: printf("input i:");scanf("%d",&i);
ListDelete_Sq(L,i,t);break;
case 4: printf("41.姓名查询\n42.学号查询\n");
printf("输入选项: ");scanf("%d",&y);
if(y!=41&&y!=42) {
printf("请重新选择。\n");break;
}
if(y==41){
printf("需查询的姓名:");scanf("%s",t.name);
m=LocateElem_Sq(L,t,comparebyname);
}
else {
printf("需查询的学号:");scanf("%d",&t.num);
m=LocateElem_Sq(L,t,comparebynum);
}
if(m) outputOne(L.elem[m-1]);
else printf("查询失败。\n");break;
case 5: Output(L);break;
}
}while(choice);
free(L.elem);
return 0;
}
🐍链表实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int num;
char name[20];
char sex[3];
char tel[14];
char qq[12];
} ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;
} LNode, * LinkList;
void InitList_L(LinkList& L) {
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
}
int ListInsert_L(LinkList& L, int i, ElemType e) {
LinkList p = L, s;
int j = 0;
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1) return -1;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return 1;
}
int ListDelete_L(LinkList& L, int i, ElemType& e) {
LinkList p = L, q;
int j = 0;
while (p->next && j < i - 1) {
p = p->next;
j++;
}
if (!(p->next) || j > i - 1) return -1;
q = p->next;
p->next = q->next;
e = q->data;
free(q);
return 1;
}
LinkList LocateElem_L(LinkList L, ElemType e, int(*op)(ElemType a, ElemType b)) {
LinkList p = L->next;
while (p && !op(p->data, e)) {
p = p->next;
}
return p;
}
int comparebynum(ElemType x, ElemType y) {
return x.num == y.num ? 1 : 0;
}
int comparebyname(ElemType x, ElemType y) {
return strcmp(x.name, y.name) == 0 ? 1 : 0;
}
void inputOne(ElemType& x) {
printf("请输入学号、姓名、性别、电话、QQ:");
scanf("%d%s%s%s%s", &x.num, x.name, x.sex, x.tel, x.qq);
}
void outputOne(ElemType x) {
printf("%d\t%s\t%s\t%s\t%s\n", x.num, x.name, x.sex, x.tel, x.qq);
}
void outputList(LinkList L) {
LinkList p = L->next;
while (p) {
outputOne(p->data);
p = p->next;
}
}
int main() {
LinkList L;
int choice, i, y;
ElemType e, t;
do {
printf(" 通讯录管理系统\n");
printf("====================================\n");
printf(" 0:退出\n");
printf(" 1:建立通讯录\n");
printf(" 2:插入\n");
printf(" 3:删除\n");
printf(" 4:查询\n");
printf(" 5:输出\n");
printf("====================================\n");
printf("请选择0 - 5\n");
scanf("%d", &choice);
switch (choice) {
case 0:
exit(1);
case 1:
InitList_L(L);
break;
case 2:
printf("input i:");
scanf("%d", &i);
inputOne(e);
if (ListInsert_L(L, i, e) == -1) {
printf("插入失败\n");
}
break;
case 3:
printf("input i:");
scanf("%d", &i);
if (ListDelete_L(L, i, e) == -1) {
printf("删除失败\n");
}
else {
printf("删除的记录为:");
outputOne(e);
}
break;
case 4:
printf("41.姓名查询\n42.学号查询\n");
printf("输入选项: ");
scanf("%d", &y);
if (y != 41 && y != 42) {
printf("请重新选择。\n");
break;
}
if (y == 41) {
printf("需查询的姓名:");
scanf("%s", t.name);
LinkList result = LocateElem_L(L, t, comparebyname);
if (result) {
outputOne(result->data);
}
else {
printf("查询失败。\n");
}
}
else {
printf("需查询的学号:");
scanf("%d", &t.num);
LinkList result = LocateElem_L(L, t, comparebynum);
if (result) {
outputOne(result->data);
}
else {
printf("查询失败。\n");
}
}
break;
case 5:
outputList(L);
break;
}
} while (choice);
LinkList p = L;
while (p) {
LinkList temp = p;
p = p->next;
free(temp);
}
return 0;
}