用 C 语言 实现线性表中的顺序表结构

用 C 语言 实现线性表中的顺序表结构

代码中有详细的解释

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 用于初始化线性表的最大值
#define LIST_INIT_SIZE 100
// 当线性表存储空间已满,进行扩容的空间大小
#define LIST_INCREMENT 10

/* 顺序表 */

/*
 * 定义添加数据抽象类型(实体)
 */
typedef struct Student {
	int *s_id;
	char *s_sex;
	char *s_name;
};


/*
 * 定义 顺序表
 */
typedef struct SqList {
    // 存储空间的基地址
	Student *elem;
	// 当前线性表的长度
    int length;
	// 当前分配的存储容量
    int listSize;
};


int main() {
	
	// 声明函数
	int InitList(SqList &L);
	int GetStudentNumber(SqList L, char *name);
	int *GetStudentNumberByName(SqList L, char *name);
	int GetStudentNumberById(SqList L, int *id);
	int ListInsert(SqList &L, int i, Student s);
	int ListDelete(SqList &L, int i, Student &s);
	
	// 初始化线性表
    SqList list;
    InitList(list);
	
	// 定义学号
	int s1_id[10], s2_id[10], s3_id[10], s4_id[10], s5_id[10], s6_id[10];
	for(int i = 0; i < 9; i++) {
		s1_id[i] = i + 1;
		s2_id[i] = i + 1;
		s3_id[i] = i + 1;
		s4_id[i] = i + 1;
		s5_id[i] = i + 1;
		s6_id[i] = i + 1;
	}
	s1_id[9] = 1;
	s2_id[9] = 2;
	s3_id[9] = 3;
	s4_id[9] = 4;
	s5_id[9] = 5;
	s6_id[9] = 6;
	
	// 定义姓名
	char *s1_name, *s2_name, *s3_name, *s4_name, *s5_name, *s6_name;
	s1_name = (char *)malloc(sizeof(char) * 12);
	s2_name = (char *)malloc(sizeof(char) * 12);
	s3_name = (char *)malloc(sizeof(char) * 12);
	s4_name = (char *)malloc(sizeof(char) * 12);
	s5_name = (char *)malloc(sizeof(char) * 12);
	s6_name = (char *)malloc(sizeof(char) * 12);
	strcpy(s1_name, "小刚");
	strcpy(s2_name, "小晓");
	strcpy(s3_name, "小晓");
	strcpy(s4_name, "小红");
	strcpy(s5_name, "xiao");
	strcpy(s6_name, "xiao");
	
	// 定义性别
	char *s1_sex, *s2_sex, *s3_sex, *s4_sex, *s5_sex, *s6_sex;
	s1_sex = (char *)malloc(sizeof(char) * 4);
	s2_sex = (char *)malloc(sizeof(char) * 4);
	s3_sex = (char *)malloc(sizeof(char) * 4);
	s4_sex = (char *)malloc(sizeof(char) * 4);
	s5_sex = (char *)malloc(sizeof(char) * 4);
	s6_sex = (char *)malloc(sizeof(char) * 4);
	strcpy(s1_sex, "男");
	strcpy(s2_sex, "男");
	strcpy(s3_sex, "女");
	strcpy(s4_sex, "女");
	strcpy(s5_sex, "女");
	strcpy(s6_sex, "女");
    Student s1 = {s1_id, s1_sex, s1_name};
    Student s2 = {s2_id, s2_sex, s2_name};
    Student s3 = {s3_id, s3_sex, s3_name};
    Student s4 = {s4_id, s4_sex, s4_name};
    Student s5 = {s5_id, s5_sex, s5_name};
    Student s6 = {s6_id, s6_sex, s6_name};
	
    // 添加 4 个 Student 给线性表 list
    ListInsert(list, 1, s1);
    ListInsert(list, 2, s2);
    ListInsert(list, 3, s3);
    ListInsert(list, 4, s4);
    ListInsert(list, 5, s5);
    ListInsert(list, 6, s6);
	
    // 输出线性表
	printf("\n输出线性表:\n");
    for(int i = 0; i < list.length; i++) {
		printf("学号:");
		for(int j = 0; j < 10; j++) {
			printf("%d", *(list.elem[i].s_id + j));
		}
        printf(", 姓名:%s, 性别:%s\n", list.elem[i].s_name, list.elem[i].s_sex);
    }
	
	// 操作对象
	printf("请选择操作(i: 添加, d: 删除, g: 查看, 其它键子退出):");
	char op;
	scanf("%c", &op);
	

	if(op == 'd') {
		// 删除第 delete_m 个
		int delete_m;
		printf("请输入要删除 Student 的位置:");
		scanf("%d", &delete_m);
		Student delete_s;
		int delect_bool = ListDelete(list, delete_m, delete_s);
		if(delect_bool == 0) {
			printf("填写错误,请重新运行!\n");
			return 1;
		}
		// 输出删除的 Student (s 在函数中赋值了)
		printf("删除的 Student:学号:");
		for(int i = 0; i < 10; i++) {
			printf("%d", *(delete_s.s_id + i));
		}
		printf(", 姓名:%s, 性别:%s\n", delete_s.s_name, delete_s.s_sex);
	
		// 查看删除后的线性表
		printf("\n查看删除后的线性表:\n");
		for(int i = 0; i < list.length; i++) {
			printf("学号:");
			for(int j = 0; j < 10; j++) {
				printf("%d", *(list.elem[i].s_id + j));
			}
			printf(", 姓名:%s, 性别:%s\n", list.elem[i].s_name, list.elem[i].s_sex);
		}
		
		system("pause");
		
	} else if(op == 'i') {
	
		Student insert_s;
		
		// 插入 Student
		int insert_m;
		printf("请输入要添加 Student 的位置:");
		scanf("%d", &insert_m);
		
		printf("\n请输入要添加 Student 的学号:");
		int insert_id[10];
		scanf("%d", insert_id);
		insert_s.s_id = insert_id;
		
		printf("\n请输入要添加 Student 的名字:");
		char insert_name[12];
		scanf("%s", insert_name);
		insert_s.s_name = insert_name;
		
		printf("\n请输入要添加 Student 的性别(男 或者 女):");
		char insert_sex[12];
		scanf("%s", insert_sex);
		insert_s.s_sex = insert_sex;
		
		int insert_bool = ListInsert(list, insert_m, insert_s);
		if(insert_bool == 0) {
			printf("填写错误,请重新运行!\n");
			return 1;
		}
		
		// 查看添加的线性表
		printf("\n查看添加的线性表:\n");
		for(int i = 0; i < list.length; i++) {
			printf("学号:");
			for(int j = 0; j < 10; j++) {
				printf("%d", *(list.elem[i].s_id + j));
			}
			printf(", 姓名:%s, 性别:%s\n", list.elem[i].s_name, list.elem[i].s_sex);
		}
		
		system("pause");
		
	} else if(op == 'g') {
		
		/* 查找 */
		printf("请选择操作(gn: 通过名字查看, gi: 通过学号查看, 其它键子退出):");
		char g_op[1];
		scanf("%s", g_op);
		
		if(strcmp(g_op, "gn") == 0) {
			
			// 通过名字查看
			printf("\n请输入要查找 Student 的名字:");
			char get_name[12];
			scanf("%s", get_name);
			
			printf("%s 的位置为:", get_name);
			
			// 输出位置
			for(int i = 0; i < GetStudentNumber(list, get_name); i++) {
				printf("%d, ", GetStudentNumberByName(list, get_name)[i]);
			}
			printf("\n");
			system("pause");
			
		} else if(strcmp(g_op, "gi") == 0) {
			
			// 通过学号查看
			printf("\n请输入要查找 Student 的学号:");
			int get_id[10];
			for(int i = 0; i < 10; i++) {
				scanf("%d", &get_id[i]);
			}
			printf("位置为:%d\n", GetStudentNumberById(list, get_id));
			
			system("pause");
		}
			
		
	}
		
}


/*
 * 初始化
 */
int InitList(SqList &L) {
	// 开辟一个存储空间,并把这块存储空间的基地址赋值给elem
	// 注:这个方法是 C 语言
    L.elem = (Student *)malloc(sizeof(Student) * LIST_INIT_SIZE);
	// 注:这个方法是 C++ 语言
	// L.elem = new Student[LIST_INIT_SIZE];
    // 空间分配失败则退出
	if(!L.elem) {
		return 0;
    }
	// 由于没有添加当前长度
    L.length = 0;
	// 当前分配量
    L.listSize = LIST_INIT_SIZE;
    return 1;
}


/*
 * 取数
 */
int GetStudentNumber(SqList L, char *name) {
	int j = 0;
	for(int i = 0; i < L.length; i++) {
        if(strcmp(L.elem[i].s_name, name) == 0) {
			j++;
        }
    }
	return j;
}

/*
 * 取值
 */

// 输入的是名字
int *GetStudentNumberByName(SqList L, char *name) {
    int getStuNumber[GetStudentNumber(L, name)];
	int j = 0;
    for(int i = 0; i < L.length; i++) {
        if(strcmp(L.elem[i].s_name, name) == 0) {
            getStuNumber[j] = i + 1;
			j++;
        }
    }
    return getStuNumber;
}

// 输入的是学号
int GetStudentNumberById(SqList L, int *id) {
    for(int i = 0; i < L.length; i++) {
		int z = 0;
		for(int j = 0; j < 10; j++) {
			if(L.elem[i].s_id[j] == id[j]) {
				z++;
			}
		}
		if(z == 10) {
			return i + 1;
		}
    }
	return 0;
}


/*
 * 插入
 */
int ListInsert(SqList &L, int i, Student s) {
    // 判断插入位置的合法性
	// 若 i = L.length + 1 是指可以在最后面插入
    if(i < 1 || i > L.length + 1) {
		return 0;
	}
    // 当存储空间不够插入的时候
    if (L.length >= L.listSize) {
		// 给存储空间扩容
		// 注:这个方法是 C 语言, C++ 需用 vector 扩容
		Student *newElem = (Student *)realloc(L.elem, sizeof(Student) * (L.listSize + LIST_INCREMENT));
        // 存储空间分配失败
		if(!newElem) {
			return 0;
		}
		// 新基址
        L.elem = newElem;
		// 增加存储容量
        L.listSize += LIST_INCREMENT;
    }
	
    /* 插入操作 */
	
	// 定义 2 个指针变量
    Student *q, *p;
	// q 为插入位置(注意形参 i 是序号,序号是从 1 开始的,而下标是从 0 开始的,因此这里转成下标后是 i-1)
	// 此处为什么是 指针和&, 因为是有 引用 操作(和上面 有的用 SqList &L 和 有的用 SqList L 一样)
	p = &(L.elem[L.length - 1]);
    q = &(L.elem[i-1]);
	// 从 ai 到 an-1 依次后移,注意后移操作要从后往前进行
	// 此处为什么 多一部 用 q 指针来引用,在于 减少变量 提高速度(这个可以忽略)
    for(p; p >= q; p--) {
		// 改变指向内容
        *(p + 1) = *p;
    }
    *q = s;
	// 表长加 1
    L.length++;
    return 1;
}


/*
 * 删除
 */
int ListDelete(SqList &L, int i, Student &s) {
    // 判断删除位置的合法性
    if (i < 1 || i > L.length) {
		return 0;
	}
	
    /* 删除操作 */
	
	// 定义 2 个指针变量
    Student *q, *p;
	// p 为被删除元素的位置(注意形参 i 是序号,序号是从 1 开始的,而下标是从 0 开始的,因此这里转成下标后是 i-1)
    p = &(L.elem[i - 1]);
	// 被删除的元素赋值给 s (可能用不到,也可能用到,所以保存给 s 吧)
	s = *p;
	// q 指向表尾最后一个元素(q 是最后一个元素的地址)
    q = &(L.elem[L.length - 1]);
	// 从 p 的下一个元素开始依次前移
    for(p; p <= q; p++) {
        *p = *(p + 1);
    }
	// 表长减 1
    L.length--;
    return 1;
}


结果

添加
在这里插入图片描述
删除
在这里插入图片描述
通过名字查找
在这里插入图片描述
通过学号查找
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值