C/C++线性表的实现

新手出路,多多请教!!

线性表的定义:

线性表(linear list)是最基本、最简单、最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的,但这只适用大部分线性表,而不是全部。在数据结构逻辑层次上细分,线性表可分为一般线性表和受限线性表。

线性表的功能以下:

======1.输入数据======
======2.输出数据======
======3.插入数据======
======4.查找指定位置的元素======
======5.删除指定位置的元素======
======6.增加线性表======
======7.线性表合并=======
======8.清空线性表=======
======0.退出程序======

使用typedef struct定义一个线性表sqlist,代码如下:(详情见代码解释)

#define SIZE 100
typedef int ElemType;
typedef int status;

typedef struct sqlist {
	ElemType* elem;//存放线性表地址
	string name;//给线性表一个名字,便于后续有需要输出时利用
	int length;	   //存放线性表长度
	int listsize;  //存放线性表的个数
}SqList;//定义线性表

其中的SqList时为了在以下的操作中使用。

定义线性表后,我们需要对线性表初始化:

该过程中用到函数malloc,他的用法在C中C++是有差异的,使用它需要头文件的#include<malloc.h>

(详情见代码解释)

status IniList(SqList* L,string name){
	L->elem = (int*)malloc(SIZE*sizeof(ElemType));//为L争取动态存储空间
	L->length = 0;//初始化是将线性表的长度设置为0
	L->listsize = SIZE;//表格的最长长度为100,若要修改见顶部
	L->name = name;//给线性表一个名字
	return 1;//正常退出
}//线性表的初始化

在main()中先初始化三个线性表:IniList(&表格名,string name)

IniList(&L1,"1");
IniList(&L2,"2");
IniList(&L_Merge,"_Merge");//三个表格初始化,然后给表L1赋值

线性表的赋值:(详情见代码解释)input(SqList* L,int Num),其中的Num是输入的数的个数

void input(SqList* L,int Num){
	L->length = Num;//将输入的数据的个数作为线性表的长度
	for (int i = 0; i < L->length; i++)
	{
		scanf_s("%d", &L->elem[i]);//给线性表赋值
	}
	printf("输入完毕!\n");
}//给线性表赋值

线性表的输出:(详情见代码解释)Display(SqList* L)

void Display(SqList* L){
	if (L->length == 0) {
		return;
	}//如果线性表为空的话,直接退出
	cout << "L" << L->name << ":";
	for (int i = 0; i < L->length; i++) {
		printf("%d", L->elem[i]);
		printf(" ");
	}
	printf("\n");
}//打印线性表

在线性表中插入值的操作:使用ListInsert(SqList*L),(详情见代码解释)

status ListInsert(SqList* L) {
	int pos;//定义position的缩写pos,为插入数据的位置
	ElemType* p, * p1, * p2,value;
	if (L->length == 0) {
		printf("\n此表为空,无法插入数据,插入数据程序已退出!!!\n");
		return 0;
	}//判断插入数据的表格是否为空,空的话退出
	printf("\n请输入要插入的位置:");
	scanf_s("%d", &pos); 
	if (pos<1 || pos>L->length+1) {
		printf("插入位置信息错误!\n");
		return 0;
	}//判断插入值的位置是否合理,不合理则推出
	printf("请输入要插入的元素:");
	scanf_s("%d", &value);
	if (L->length >= L->listsize) {
		p =(int*)realloc(L->elem, sizeof(ElemType) * (L->listsize + 10));
		if (!p) return 0;
		L->elem = p;//新地址赋给L
		L->listsize += 10;//大小应进行相应调整改变
	} //空间不足时,扩充容量,这个if条件语句一般用不上,可以省略
	p1 = &L->elem[pos - 1];
	for (p2 = &L->elem[L->length - 1]; p2 >= p1; p2--) {
		*(p2 + 1) = *(p2);//向后移动一个单位
	}
	L->elem[pos - 1] = value;
	L->length++;
	return 1;	
}//插入元素

线性表中删除指定位置的值操作:(详情见代码解释)DeleteDate(SqList* L)

status DeleteDate(SqList* L) {
	int pos_delete;//定义删除数据的位置
	while (true) {
		printf("请输入你要删除的数据的位置(该表的长度为:%d):", L->length);
		cin >> pos_delete;
		if (pos_delete-1<0 || pos_delete-1>=L->length) {
			printf("\n输入的位置有误!请重新输入!!\n");
			continue;
		}
		else break;
	}//判断删除数据的位置是否合理,合理则退出while循环结构
	int date_delete = L->elem[pos_delete-1];//由于角标是从0开始的,所以我们需要pos_delete-1来进行操作
	for (int i = pos_delete-1; i <= L->length-1; i++) {
		L->elem[i] = L->elem[i + 1];
	}//由于角标是从0开始的,所以我们需要pos_delete-1来进行操作
	L->length = L->length - 1;
	printf("已删除数据:%d\n", date_delete);
	return 1;
}//删除数据

在线性表中查找数据的操作如下:(详情看代码解析)SearchDate(SqList*L)

status SearchDate(SqList*L){
	int pos_search;//定义查找的位置
	while (true) {
		printf("请输入你要查找的位置(该表的长度为:%d):", L->length);
		cin >> pos_search;
		if (pos_search-1 < 0 || pos_search-1 >= L->length) {
			printf("\n输入的位置有误!请重新输入!!\n");
			continue;
		}
		else break;
	}//判断查找数据的位置是否合理,合理则退出while循环结构
	printf("这个值是:%d\n", L->elem[pos_search-1]);//由于角标是从0开始的,所以我们需要pos_search-1来输出
	return 1;
}//查找数据

线性表中的数据添加线性表的操作:(详情看代码解析) AddList(SqList *L,int Num)    其中的Num是输入的数的个数

status AddList(SqList *L,int Num) {
	L->length = Num;//增加线性表,该线性表的长度=输入值的个数
	for (int i = 0; i < L->length; i++){
		scanf_s("%d", &L->elem[i]);
	}
	printf("输入完毕!\n");
	return 1;
}//增加数据

线性表的合并:ListMerge(SqList*表1, SqList* 表2, SqList* 合并表名)(详情看代码)

status ListMerge(SqList* L1, SqList* L2, SqList* L_Merge) {
	L_Merge->length = L1->length + L2->length;//将要合并的线性表的长度相加,然后赋值给合并表格的长度
	int pos1 = L1->length, pos2 = L2->length;//定义pos1和pos2是为了一下便于赋值给合并表
	for (int i = 0; i < L1->length; i++) {
		L_Merge->elem[i] = L1->elem[i];
	}
	for (int i = L1->length, k = 0; k < L2->length; k++, i++) {
		L_Merge->elem[i] = L2->elem[k];
	}/*此for循环的条件体比较关键,int i = L1->length这条语句是使用了表L1的长度
	 由于角标是从0开始的,所以这里直接利用L1的长度作为角标来开始取值*/
	IniList(L1,"1");
	IniList(L2,"2");//合并表格以后,将两表初始化(相当于销毁线性表)
	printf("合并完毕!\n");
	return 1;
}//线性表合并

销毁线性表的方法:DeleteList(SqList*表1, SqList* 表2, SqList* 表3)

status DeleteList(SqList* L1, SqList* L2, SqList* L_Merge) {
	IniList(L1,"1");
	IniList(L2,"2");
	IniList(L_Merge,"_Merge");
	printf("销毁线性表完毕!\n");
	return 1;
}//销毁线性表,其本质是将线性表重新初始化,此时每个表格的长度皆为0,故已销毁

main()函数主体代码:

int main(){
	SqList L1, L2, L_Merge;//定义三个表格
	string answer;
	int i=1;
	while (true) {
	start:
		printf("===================================\n");
		printf("======1.输入数据======\n");//input
		printf("======2.输出数据======\n");//Display
		printf("======3.插入数据======\n");//ListInsert
		printf("======4.查找指定位置的元素======\n");//SearchDate
		printf("======5.删除指定位置的元素======\n");//DeleteDate
		printf("======6.增加线性表======\n");//AddList
		printf("======7.线性表合并=======\n");//Union
		printf("======8.清空线性表=======\n");//IniList
		printf("======0.退出程序======\n");
		printf("===================================\n");
		printf("\n请输入相应数字进行此程序:");
		scanf_s("%d", &i);
		switch (i) {
		case 1://给线性表赋值
			IniList(&L1,"1");
			IniList(&L2,"2");
			IniList(&L_Merge,"_Merge");//三个表格初始化,然后给表L1赋值
			printf("请输入数的个数:");
			scanf_s("%d", &L1.length);
			input(&L1, L1.length); 
			system("pause");
			system("cls");
			goto start;
		case 2://查看表
			Display(&L1);
			if (&L2.length != 0) {
				printf("\n");
				Display(&L2);
			}
			if (&L_Merge.length != 0) {
				printf("\n");
				Display(&L_Merge);
			}
			system("pause");
			system("cls");
			goto start;
		case 3://插入元素
			printf("请输入你要插入数据的表格名称(L1,L2,L_Merge):");
			cin >> answer;
			if(answer=="L1")ListInsert(&L1);
			if (answer == "L2")ListInsert(&L2);
			if (answer == "L_Merge")ListInsert(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 4:
			printf("请输入查找哪个表格的数据(L1,L2,L_Merge;注意区分大小写):");
			cin >> answer;
			if (answer == "L1")SearchDate(&L1);
			if (answer == "L2")SearchDate(&L2);
			if (answer == "L_Merge")SearchDate(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 5:
			printf("请输入你要删除哪个表格中的数据(L1,L2,L_Merge;注意区分大小写):");
			cin >> answer;
			if (answer == "L1")DeleteDate(&L1);
			if (answer == "L2")DeleteDate(&L2);
			if (answer == "L_Merge")DeleteDate(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 6://增加线性表
			printf("请输入数的个数:");
			scanf_s("%d", &L2.length);
			AddList(&L2, L2.length);
			system("pause");
			system("cls");
			goto start;
		case 7:
			ListMerge(&L1, &L2, &L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 8:
			IniList(&L1, "1");
			IniList(&L2, "2");
			IniList(&L_Merge, "_Merge");
			system("pause");
			system("cls");
			goto start;
		case 0:
			printf("确定退出程序吗?(yes or no):");
			cin >> answer;
			if (answer == "yes"||answer=="YES")exit(0);
			if (answer == "no" || answer == "NO") {
				system("pause");
				system("cls");
				goto start;
			}
		}
	}
	return 0;
}

完整代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;

#define SIZE 100
typedef int ElemType;
typedef int status;

typedef struct sqlist {
	ElemType* elem;//存放线性表地址
	string name;//给线性表一个名字,便于后续有需要输出时利用
	int length;	   //存放线性表长度
	int listsize;  //存放线性表的个数
}SqList;//定义线性表
status IniList(SqList* L,string name){
	L->elem = (int*)malloc(SIZE*sizeof(ElemType));//为L争取动态存储空间
	L->length = 0;//初始化是将线性表的长度设置为0
	L->listsize = SIZE;//表格的最长长度为100,若要修改见顶部
	L->name = name;//给线性表一个名字
	return 1;//正常退出
}//线性表的初始化
void input(SqList* L,int Num){
	L->length = Num;//将输入的数据的个数作为线性表的长度
	for (int i = 0; i < L->length; i++)
	{
		scanf_s("%d", &L->elem[i]);//给线性表赋值
	}
	printf("输入完毕!\n");
}//给线性表赋值
void Display(SqList* L){
	if (L->length == 0) {
		return;
	}//如果线性表为空的话,直接退出
	cout << "L" << L->name << ":";
	for (int i = 0; i < L->length; i++) {
		printf("%d", L->elem[i]);
		printf(" ");
	}
	printf("\n");
}//打印线性表
status ListInsert(SqList* L) {
	int pos;//定义position的缩写pos,为插入数据的位置
	ElemType* p, * p1, * p2,value;
	if (L->length == 0) {
		printf("\n此表为空,无法插入数据,插入数据程序已退出!!!\n");
		return 0;
	}//判断插入数据的表格是否为空,空的话退出
	printf("\n请输入要插入的位置:");
	scanf_s("%d", &pos); 
	if (pos<1 || pos>L->length+1) {
		printf("插入位置信息错误!\n");
		return 0;
	}//判断插入值的位置是否合理,不合理则推出
	printf("请输入要插入的元素:");
	scanf_s("%d", &value);
	if (L->length >= L->listsize) {
		p =(int*)realloc(L->elem, sizeof(ElemType) * (L->listsize + 10));
		if (!p) return 0;
		L->elem = p;//新地址赋给L
		L->listsize += 10;//大小应进行相应调整改变
	} //空间不足时,扩充容量,这个if条件语句一般用不上,可以省略
	p1 = &L->elem[pos - 1];
	for (p2 = &L->elem[L->length - 1]; p2 >= p1; p2--) {
		*(p2 + 1) = *(p2);//向后移动一个单位
	}
	L->elem[pos - 1] = value;
	L->length++;
	return 1;	
}//插入元素
status AddList(SqList *L,int Num) {
	L->length = Num;//增加线性表,该线性表的长度=输入值的个数
	for (int i = 0; i < L->length; i++){
		scanf_s("%d", &L->elem[i]);
	}
	printf("输入完毕!\n");
	return 1;
}//增加数据
status SearchDate(SqList*L){
	int pos_search;//定义查找的位置
	while (true) {
		printf("请输入你要查找的位置(该表的长度为:%d):", L->length);
		cin >> pos_search;
		if (pos_search-1 < 0 || pos_search-1 >= L->length) {
			printf("\n输入的位置有误!请重新输入!!\n");
			continue;
		}
		else break;
	}//判断查找数据的位置是否合理,合理则退出while循环结构
	printf("这个值是:%d\n", L->elem[pos_search-1]);//由于角标是从0开始的,所以我们需要pos_search-1来输出
	return 1;
}//查找数据
status DeleteDate(SqList* L) {
	int pos_delete;//定义删除数据的位置
	while (true) {
		printf("请输入你要删除的数据的位置(该表的长度为:%d):", L->length);
		cin >> pos_delete;
		if (pos_delete-1<0 || pos_delete-1>=L->length) {
			printf("\n输入的位置有误!请重新输入!!\n");
			continue;
		}
		else break;
	}//判断删除数据的位置是否合理,合理则退出while循环结构
	int date_delete = L->elem[pos_delete-1];//由于角标是从0开始的,所以我们需要pos_delete-1来进行操作
	for (int i = pos_delete-1; i <= L->length-1; i++) {
		L->elem[i] = L->elem[i + 1];
	}//由于角标是从0开始的,所以我们需要pos_delete-1来进行操作
	L->length = L->length - 1;
	printf("已删除数据:%d\n", date_delete);
	return 1;
}//删除数据
status ListMerge(SqList* L1, SqList* L2, SqList* L_Merge) {
	L_Merge->length = L1->length + L2->length;//将要合并的线性表的长度相加,然后赋值给合并表格的长度
	int pos1 = L1->length, pos2 = L2->length;//定义pos1和pos2是为了一下便于赋值给合并表
	for (int i = 0; i < L1->length; i++) {
		L_Merge->elem[i] = L1->elem[i];
	}
	for (int i = L1->length, k = 0; k < L2->length; k++, i++) {
		L_Merge->elem[i] = L2->elem[k];
	}/*此for循环的条件体比较关键,int i = L1->length这条语句是使用了表L1的长度
	 由于角标是从0开始的,所以这里直接利用L1的长度作为角标来开始取值*/
	IniList(L1,"1");
	IniList(L2,"2");//合并表格以后,将两表初始化(相当于销毁线性表)
	printf("合并完毕!\n");
	return 1;
}//线性表合并
status DeleteList(SqList* L1, SqList* L2, SqList* L_Merge) {
	IniList(L1,"1");
	IniList(L2,"2");
	IniList(L_Merge,"_Merge");
	printf("销毁线性表完毕!\n");
	return 1;
}//销毁线性表,其本质是将线性表重新初始化,此时每个表格的长度皆为0,故已销毁
int main(){
	SqList L1, L2, L_Merge;//定义三个表格
	string answer;
	int i=1;
	while (true) {
	start:
		printf("===================================\n");
		printf("======1.输入数据======\n");//input
		printf("======2.输出数据======\n");//Display
		printf("======3.插入数据======\n");//ListInsert
		printf("======4.查找指定位置的元素======\n");//SearchDate
		printf("======5.删除指定位置的元素======\n");//DeleteDate
		printf("======6.增加线性表======\n");//AddList
		printf("======7.线性表合并=======\n");//Union
		printf("======8.清空线性表=======\n");//IniList
		printf("======0.退出程序======\n");
		printf("===================================\n");
		printf("\n请输入相应数字进行此程序:");
		scanf_s("%d", &i);
		switch (i) {
		case 1://给线性表赋值
			IniList(&L1,"1");
			IniList(&L2,"2");
			IniList(&L_Merge,"_Merge");//三个表格初始化,然后给表L1赋值
			printf("请输入数的个数:");
			scanf_s("%d", &L1.length);
			input(&L1, L1.length); 
			system("pause");
			system("cls");
			goto start;
		case 2://查看表
			Display(&L1);
			if (&L2.length != 0) {
				printf("\n");
				Display(&L2);
			}
			if (&L_Merge.length != 0) {
				printf("\n");
				Display(&L_Merge);
			}
			system("pause");
			system("cls");
			goto start;
		case 3://插入元素
			printf("请输入你要插入数据的表格名称(L1,L2,L_Merge):");
			cin >> answer;
			if(answer=="L1")ListInsert(&L1);
			if (answer == "L2")ListInsert(&L2);
			if (answer == "L_Merge")ListInsert(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 4:
			printf("请输入查找哪个表格的数据(L1,L2,L_Merge;注意区分大小写):");
			cin >> answer;
			if (answer == "L1")SearchDate(&L1);
			if (answer == "L2")SearchDate(&L2);
			if (answer == "L_Merge")SearchDate(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 5:
			printf("请输入你要删除哪个表格中的数据(L1,L2,L_Merge;注意区分大小写):");
			cin >> answer;
			if (answer == "L1")DeleteDate(&L1);
			if (answer == "L2")DeleteDate(&L2);
			if (answer == "L_Merge")DeleteDate(&L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 6://增加线性表
			printf("请输入数的个数:");
			scanf_s("%d", &L2.length);
			AddList(&L2, L2.length);
			system("pause");
			system("cls");
			goto start;
		case 7:
			ListMerge(&L1, &L2, &L_Merge);
			system("pause");
			system("cls");
			goto start;
		case 8:
			IniList(&L1, "1");
			IniList(&L2, "2");
			IniList(&L_Merge, "_Merge");
			system("pause");
			system("cls");
			goto start;
		case 0:
			printf("确定退出程序吗?(yes or no):");
			cin >> answer;
			if (answer == "yes"||answer=="YES")exit(0);
			if (answer == "no" || answer == "NO") {
				system("pause");
				system("cls");
				goto start;
			}
		}
	}
	return 0;
}

一名来自北京印刷学院计科的学生

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值