【数据结构】实验一:线性表的应用---成绩有序表的建立以及合并

实验一:线性表的应用

学时:2学时

实验目的:

  掌握线性表的基本结构和操作方法,培养学生灵活使用表解决实际问题的能力。

实验内容:

  一条记录有学号和成绩两个数据项,按成绩由大到小建立两个有序表(分别用顺序表和链式表实现),并合并成一个有序表。

  第一个表输入的数据如下(学号,成绩):(1,70),(2,85), (3,75), (4,90),

  第二个表输入的数据如下(学号,成绩):(5,60),(6,80), (7,76),(8,50)。

提示:

  1,编写初始化函数,插入函数,显示函数,释放函数,对两个表统一处理。

  2,编写合并函数,把两个有序表合并成一个新的有序表(保留原表)。

  3,分别用顺序表和链表实现。

源代码①:顺序表实现

// *.cpp: 定义控制台应用程序的入口点。

#include <iostream>

using namespace std;

#define LIST_INIT_SIZE 100
#define LISTINCREASE 10
#define Status int
#define SCORE double
#define NUMBER int
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define EXIST 2

//定义线性表
typedef struct {
	NUMBER *num;
	SCORE *score;
	int length;
	int listsize;
}SqList1;

//初始化线性表
Status InitList(SqList1 &L) {
	L.num = (NUMBER *)malloc(LIST_INIT_SIZE * sizeof(NUMBER));
	L.score = (SCORE *)malloc(LIST_INIT_SIZE * sizeof(SCORE));
	if (!L.num) exit(OVERFLOW);
	L.length = 0;
	L.listsize = LIST_INIT_SIZE;
	return OK;
}


//将数据输入到线性表1 中,并按照成绩有大到小排序
Status InsertSqList1(SqList1 &L, NUMBER num, SCORE score) {
	int i;

	if (L.length == L.listsize)
		return OVERFLOW;

	if (L.length == 0) {
		L.num[0] = num;
		L.score[0] = score;
		L.length++;
		return OK;
	}
	for (i = 0; i < L.length; i++) {
		if (num ==L.num[i]) return EXIST;
	}

	for (i = L.length; i > 0, score < L.score[i - 1]; i--) {
		L.num[i] = L.num[i-1];
		L.score[i] = L.score[i-1];
	}
	L.num[i] = num;
	L.score[i] = score;
	L.length++;
	return OK;
}

//将两个成绩单合并
void MergeList_Sq(SqList1 &L1, SqList1 &L2, SqList1 &L3) {
	int i=0,j=0,k=0;
	while (i < L1.length && j < L2.length) {
		if (L1.score[i] <= L2.score[j])
		{
			L3.num[k] = L1.num[i];
			L3.score[k] = L1.score[i];
			L3.length++;
			i++;
			k++;
		}
		else
		{
			L3.num[k] = L2.num[j];
			L3.score[k] = L2.score[j];
			L3.length++;
			j++;
			k++;
		}
	}
	while (i<L1.length)
	{
		L3.num[k] = L1.num[i];
		L3.score[k] = L1.score[i];
		L3.length++;
		i++;
		k++;
	}
	while (j<L2.length)
	{
		L3.num[k] = L2.num[j];
		L3.score[k] = L2.score[j];
		L3.length++;
		j++;
		k++;
	}
	
}

//打印成绩单
void PrintList(SqList1 &L) {
	int i;
	if (L.length == 0) {
		cout << "无任何成绩数据!\n";
		return;
	}

	cout << "学号\t成绩\n";
	for (i = L.length-1; i >=0; i--) {
		cout << L.num[i] << "\t" << L.score[i] << endl;
	}
	cout << endl;
	return;
}

//主函数
int main(){
	SqList1 L1, L2, L3;

	NUMBER num;
	SCORE score;
	InitList(L1);
	InitList(L2);	
	InitList(L3);

	cout << "-->1:将成绩输入到成绩单1中 \n-->2:将成绩输入到成绩单2中\n-->3:打印成绩单1\n-->4:打印成绩单2\n-->5:将成绩单1、2合并并输出\n" << endl;
	int choice,flag;
	while (1)
	{
		cout << "请输入操作项:";
		cin >> choice;

		switch (choice) {
		case 1:
			cout << "请输入学号、成绩:";
			cin >> num >> score;
			flag = InsertSqList1(L1, num, score);
			if (flag == OK) cout << "成绩输入成功!\n\n";
			if (flag == OVERFLOW) cout << "空间不足,输入成绩失败!\n\n";
			if (flag == EXIST) cout << "该考生号已存在! 输入成绩失败!\n\n";
			break;

		case 2:
			cout << "请输入学号、成绩:";
			cin >> num >> score;
			flag = InsertSqList1(L2, num, score);
			if (flag == OK) cout << "成绩输入成功!\n\n";
			if (flag == OVERFLOW) cout << "空间不足,输入成绩失败!\n\n";
			if (flag == EXIST) cout << "该考生号已存在! 输入成绩失败!\n\n";
			break;

		case 3:
			PrintList(L1);
			break;

		case 4:
			PrintList(L2);
			break;

		case 5:
			MergeList_Sq(L1, L2, L3);
			cout << "合并成功,即将输出:\n";
			PrintList(L3);
			break;
		}
	}
    return 0;
}

运行结果①:

源代码②:链式表实现

// 线性表的应用 链式表实现.cpp: 定义控制台应用程序的入口点。

#include <iostream>
using namespace std;

#define Status int
#define NUMBER int
#define SCORE double
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define NULL 0
#define EXIST 2
#define Status int

//定义链表
typedef struct LNode {
	NUMBER num;
	SCORE score;
	LNode *next;
}LNode, *LinkList;

//将数据按照顺序插入到链表中
Status InsertList(LinkList &L,NUMBER num,SCORE score) {
	LinkList p, q;
	q = new LNode;
	q->num = num;
	q->score = score;

	if (L == NULL)	{   //如果是空表,直接将数据插入到头指针处
		L = q;
		L->next = NULL;
		return OK;
	}

	if (L->score < score) {  //插入头部
		q->next = L;
		L = q;
		return OK;
	}

	p = L;
	while (p->next != NULL && p->next->score > score )   //进行比较数据大小  寻找插入点
		p = p->next;
	q->next = p->next;
	p->next = q;
	return OK;
}

//合并两个链表
Status CombineList(LinkList &L1, LinkList &L2, LinkList &L) {
	LinkList p1, p2;
	p1 = L1;
	p2 = L2;
	if (p1 == NULL && p2 == NULL) {
		return ERROR;
	}
	while (p1 != NULL) {
		InsertList(L, p1->num, p1->score);
		p1 = p1->next;
	}
	while(p2 != NULL) {
		InsertList(L, p2->num, p2->score);
		p2 = p2->next;
	}
	return OK;
}


//打印链表
Status PrintList(LinkList &L) {
	LinkList p;
	p = L;
	if (L==NULL){
		return ERROR;
	}	
	cout << "学号\t成绩" << endl;
	while (p != NULL){
	
		cout << p->num << "\t" << p->score << endl;
		p = p->next;
	}
	cout << endl;
	return OK;
}

int main()
{
	LinkList L1, L2,L;
	L1 = NULL; L2 = NULL;L=NULL;
	NUMBER num;
	SCORE score;

	cout << "-->1:将成绩输入到成绩单1中 \n-->2:将成绩输入到成绩单2中\n-->3:打印成绩单1\n-->4:打印成绩单2\n-->5:合并成绩单1、2" << endl;
	int choice, flag;
	while (1)
	{
		cout << "请输入操作项:";
		cin >> choice;

		switch (choice) {
		case 1:
			cout << "请输入学号、成绩:";
			cin >> num >> score;
			flag = InsertList(L1, num, score);
			if (flag == OK) cout << "成绩输入成功!\n\n";
			if (flag == OVERFLOW) cout << "空间不足,输入成绩失败!\n\n";
			if (flag == EXIST) cout << "该考生号已存在! 输入成绩失败!\n\n";
			break;

		case 2:
			cout << "请输入学号、成绩:";
			cin >> num >> score;
			flag = InsertList(L2, num, score);
			if (flag == OK) cout << "成绩输入成功!\n\n";
			if (flag == OVERFLOW) cout << "空间不足,输入成绩失败!\n\n";
			if (flag == EXIST) cout << "该考生号已存在! 输入成绩失败!\n\n";
			break;

		case 3:
			flag = PrintList(L1);
			if (flag == ERROR)  cout << "当前成绩单为空!请导入成绩!" << endl << endl;
			break;

		case 4:
			flag = PrintList(L2);
			if (flag == ERROR)  cout << "当前成绩单为空!请导入成绩!" << endl << endl;
			break;
		case 5:
			cout << "合并成绩单L1和L2:\n";
			flag = CombineList(L1, L2, L);
			if(flag == ERROR) cout << "当前成绩单为空!请导入成绩!" << endl << endl;
			PrintList(L);
			break;
		}
	}
    return 0;
}

运行结果②:

  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾年之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值