新手出路,多多请教!!
线性表的定义:
线性表(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;
}
一名来自北京印刷学院计科的学生