栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言:顺序表以及单链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言:顺序表以及单链表

实验题目:        线性表的基本操作         

实验环境:          Visual Studio          

实验目的:

1、掌握线性表的定义;

2、掌握线性表的基本操作,如建立、查找、插入和删除等。

实验内容:

定义一个包含学生信息(学号,姓名,成绩)的顺序表和链表,使其具有如下功能:

(1) 根据指定学生个数,逐个输入学生信息;

(2) 逐个显示学生表中所有学生的相关信息;

(3) 根据姓名进行查找,返回此学生的学号和成绩;

(4) 根据指定的位置可返回相应的学生信息(学号,姓名,成绩);

(5) 给定一个学生信息,插入到表中指定的位置;

(6) 删除指定位置的学生记录;

(7) 统计表中学生个数。

实验提示: 

学生信息的定义:

typedef struct {

    char no[8];   //8位学号

    char name[20]; //姓名

    int grade;     //成绩

}Student;

顺序表的定义

typedef  struct {

  Student  *elem;     //指向数据元素的基地址

  int  length;       //线性表的当前长度                                                           

 }SqList;

链表的定义:

typedef struct LNode{

     Student   data;       //数据域

     struct LNode  *next;   //指针域

}LNode,*linkList;

实验要求:

(1) 程序要添加适当的注释,程序的书写要采用缩进格式。

(2) 程序要具有一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。

(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。


顺序表代码:
#include
#include
#include

#define MAXSIZE 5
#define OK 1
#define ERROR 0
#define Free -1

typedef int Status;
typedef int ElemType;

struct Student {
	int id;   //八位学号
	char name[20];//姓名
	float grade;    //成绩
};

typedef struct {                            //创建结构体
	Student* elem;
	int length;
}SqList;

//创建
Status Cj_List(SqList& L) {         //数据长度为0时就是创建成功了,不允许再次创建
	if (L.length >= 0) {
		printf("创建失败!原因:内存已被创建。an");
		return ERROR;
	}
	L.elem = (Student*)malloc(MAXSIZE * sizeof(Student));
	if (L.elem) {
		L.length = 0;                //创建成功,赋值长度为0
		return OK;
	}
	return ERROR;
}

//插入
Status Cr_List(SqList& L, int i, Student e) {
	if (L.length < 0) {
		printf("插入失败!原因:内存未被创建!an");
		return ERROR;               //当长度小于0就是未创建内存,不允许插入数据
	}
	if (L.length >= MAXSIZE) {        //长度大于顺序表最大值时不允许插入数据
		printf("插入失败!原因:顺序表已满。an");
		return ERROR;
	}
	if (i <= 0 || i > L.length + 1) {
		printf("插入位置不合法!an");
		return ERROR;
	}
	for (int j = L.length - 1; j >= i - 1; j--) {
		L.elem[j + 1] = L.elem[j];
	}
	L.elem[i - 1] = e;
	++L.length;
	printf("插入成功!n当前顺序表长度为:%dn", L.length);
	return OK;
}

//提取
Status Tq_List(SqList L, int i) {
	if (i <= 0 || i > L.length) {
		printf("提取位置不合法!an");
		return ERROR;
	}
	printf("学号:%d 姓名:%s 成绩:%.2f n", L.elem[i - 1].id, L.elem[i - 1].name, L.elem[i - 1].grade);                           //输出当前i位置的学生数据
	return OK;
}

//查找
Status Cz_List(SqList L, Student p) {
	for (int i = 0; i < L.length; i++) {
		if (strcmp(L.elem[i].name, p.name) == 0)return(i + 1);
	}                           //用strcmp()对比学生姓名,相等则输出序号
	return ERROR;
}
//删除
Status Sc_List(SqList& L, int i) {
	if (i <= 0 || i > L.length) {
		printf("删除的位置不合法!an");
		return ERROR;
	}
	printf("需删除的数据为:n学号: % d 姓名 : % s 成绩 : %.2f n", L.elem[i - 1].id, L.elem[i - 1].name, L.elem[i - 1].grade);
	for (i; i < L.length; i++) {
		L.elem[i - 1] = L.elem[i];
	}printf("删除成功!n当前顺序表长度为:%dn", --L.length);
	return OK;
}

//清空
void Qk_List(SqList& L) {
	printf("正在清空数据...........0%%n");
	for (int j = L.length; j > 0; j--) {
		L.elem[j - 1] = L.elem[j];                           //清楚表内所有数据
		printf("正在清除...............%d%%n", 100 - (--L.length));
	}
	printf("数据已清空成功!n");
	printf("正在清空内存......n");
	free(L.elem);                           //将顺序表内存释放
	L.length = Free;
	printf("清空内存成功!n");
}

//输出
Status print_List(SqList L) {
	if (L.length < 0) {
		printf("输出失败!原因:顺序表不存在。an");
		return ERROR;
	}
	if (L.length == 0) {
		printf("输出失败!原因:该顺序表没有数据。an");
		return ERROR;
	}
	else {
		printf("全部学生数据:n");
		for (int i = 0; i < L.length; i++) {
			printf("学号:%d 姓名:%s 成绩:%.2f n", L.elem[i].id, L.elem[i].name, L.elem[i].grade);
		}
		return OK;
	}
}

int main() {
	SqList L;
	int i, choose = -1;
	Student e,p;
	int id;
	L.length=-1; 
	while (1) {
		printf("*******************************n");
		printf("1.创建n");
		printf("2.插入n");
		printf("3.查找n");
		printf("4.提取n");
		printf("5.删除n");
		printf("6.输出n");
		printf("7.清空n");
		printf("8.退出n");
		printf("请选择操作:");
		scanf("%d", &choose);
		printf("n");
		switch (choose) {
		case 1: {
			if (Cj_List(L))printf("分配内存成功!n");
			break;
		}
		case 2: {
			printf("输入插入的位置、学号、姓名、成绩(空格隔开)n");
			scanf("%d %d %s %f", &i, &e.id, &e.name, &e.grade);
			Cr_List(L, i, e);
			break;
		}
		case 3: {
			printf("输入需查找学生的姓名:");
			scanf("%s", p.name,20);
			printf("n");
			if (Cz_List(L, p)) {
				printf("学生所在排序位置为:%dn", Cz_List(L, p));
			}
			else {
				printf("没有找到该学生!n");
			}
			break;
		}
		case 4: {
			printf("输入提取的位置: ");
			scanf("%d", &i);
			printf("n");
			Tq_List(L, i);
			break;
		}
		case 5: {
			printf("输入删除的位置: ");
			scanf("%d", &i);
			Sc_List(L, i);
			break;
		}
		case 6: {
			print_List(L);
			break;
		}
		case 7: {
			Qk_List(L);
			break;
		}
		case 8: {
			printf("已成功退出!n");
			system("pause");
			return 0;
		}
		}
	}
	return 0;
}


单链表代码:
#include
#include
#include

#define MAXSIZE 10
#define OK 1
#define ERROR 0
#define T 1
#define F -1

typedef int Status;
struct Student {
	int id;
	char name[20];
	float grade;
};

typedef struct Dlist {
	Student data;
	struct Dlist* next;
}Dlist,*Zdlist;

//创建
Status Cj_List(Zdlist& L) {
	L = (Zdlist)malloc(sizeof(Student));
	if (L) {
		L->next = NULL;
		printf("创建成功!n");
		return OK;
	}
	printf("创建失败!an");
	return ERROR;
}

//插入
Status Cr_List(Zdlist &L ,int i,Student e) {
	Zdlist p ,s;
	p = L;
	int j = 0;                          //判断是否有头结点,无头节点则创建失败。
	while (p && (j < i - 1)) {
		p = p->next;
		++j;
	}
	if (!p || j > i - 1) {
		printf("插入失败!an");
		return ERROR;
	}
	s = (Zdlist)malloc(sizeof(Student));//插入时先新建头结点
	s->next = NULL;                 //定义p=L用p代替L进行指针遍历,防止丢失头结点
	s->data = e;
	s->next = p->next;           
	p->next = s;
	printf("插入成功!n");
	return OK;
	
}

//查找
Status Cz_List(Zdlist L, Student e) {
	Zdlist p ;
	int i = 1;
	p = L->next;
	while (p && strcmp(p->data.name, e.name) != 0) {  // 比较名字字符
		p = p->next;
		i++;
	}
	if (p) {
		printf("学生数据在第 %d 位n", i);
		return OK;
	}
	printf("未找到该学生!an");
	return ERROR;
}

//取值
Status Qz_List(Zdlist L, int i) {     //找到位置直接输出学生信息
	Zdlist p = L;
	int j = 0;
	while (p && (j < i )) {
		p = p->next;
		++j;
	}
	if (!p || (j > i )) {
		printf("取值位置不合理!an");
		return ERROR;
	}printf("该学生信息为:学号:%d 姓名:%s 成绩:%.2fn", p->data.id, p->data.name, p->data.grade);
	return OK;
}

//删除
Status Sch_List(Zdlist& L, int i) {
	Zdlist p = L;
	int j = 0;
	while ((p->next) && (j < i - 1)) {
		p = p->next;
		++j;
	}
	if (!(p->next) || (j > i - 1)) {
		printf("删除的位置不合理!an");
		return ERROR;
	}
	Zdlist q = (Zdlist)malloc(sizeof(Student));
	Dlist* temp = q;
	q = p->next;
	p->next = q->next;
	free (temp);         //使指针指向删除节点的下一个节点,用free将删除节点内存释放
	temp->next = NULL;
	printf("删除成功!n");
	return OK;
}

//输出
Status Sc_List(Zdlist L) {
	Zdlist p = L;
	int sum=0;
	if (!p->next) {
		printf("链表为空!an");
		return ERROR;
	}
	printf("全部学生数据:n");
	while (p->next!=NULL) {
		p = p->next;
		sum++;      //输出总人数
		printf("学号:%d 姓名:%s 成绩:%.2fn学生总数量:%d个n", p->data.id, p->data.name, p->data.grade,sum);
	}
	return OK;
}


//清空
Status Qk_List(Zdlist& L,int open) {
	if (open != T) {
		printf("内存未被创建!an");
		return ERROR;
	}
	while (L->next!=NULL) {    //调用删除函数遍历清空链表所有元素及释放内存
		Sch_List(L, 1);
	}
	L = NULL;
	printf("清楚数据完成!n内存已清空n");
	return OK;
}


int main() {
	Zdlist L;
	Student e;
	int choose;
	int i;
	int open = F;    //判断内存是否已经创建,防止键盘非法输入造成遍历越界报错异常
	while (1) {
		printf("*******************************n");
		printf("1.创建n");
		printf("2.插入n");
		printf("3.查找n");
		printf("4.提取n");
		printf("5.删除n");
		printf("6.输出n");
		printf("7.清空n");
		printf("8.退出n");
		printf("请选择操作:");
		scanf("%d", &choose);
		printf("n");
		switch (choose) {
		case 1:
			if (open != F) {
				printf("请勿重复创建!an");
				break;
			}
			Cj_List(L);
			open = T;          //open=T 已申请内存  open=F 内存未被申请
			break;
		case 2:
			if (open != T) {
				printf("内存未被创建!an");
				break;
			}
			printf("输入插入的位置、学号、姓名、成绩(空格隔开)n");
			scanf("%d %d %s %f", &i, &e.id, &e.name,&e.grade);
			Cr_List(L, i, e);
			break;
		case 3:
			if (open != T) {
				printf("内存未被创建!an");
				break;
			}
			printf("输入需查找学生的姓名:");
			scanf("%s", e.name);
			printf("n");
			Cz_List(L, e);
			break;
		case 4:
			if (open != T) {
				printf("内存未被创建!an");
				break;
			}
			printf("输入提取的位置n");
			scanf("%d", &i);
			Qz_List(L, i);
			break;
		case 5:
			if (open != T) {
				printf("内存未被创建!an");
				break;
			}
			printf("输入删除的位置n");
			scanf("%d", &i);
			Sch_List(L, i);
			break;
		case 6:
			if (open != T) {
				printf("内存未被创建!an");
				break;
			}
			Sc_List(L);
			break;
		case 7:
			Qk_List(L,open);
			open = F;
			break;
		case 8:
			printf("已成功退出!n");
			system("pause");
			return 0;
		}
	}
}

由于作者内存分配知识非常薄弱,可以说是没有,尤其是单链表,作者想将头指针L的内存释放掉,但是用free一直会报错,到现在还没有找到解决的办法,所以干脆先将它赋值为NULL。请各位老师指出问题,多多提建议,谢谢。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352420.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号