C++中如何建立一个顺序表

本文详细介绍了顺序表的基本操作,包括初始化、插入、追加、删除、查找和显示等,并提供了完整的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

准备数据

#define MAXLEN 100	//定义顺序表的最大长度
struct DATA
{
	char key[10];	//结点的关键字 
	char name[20];
	int age;
};
struct	SLType	//定义顺序表结构 
{
	DATA ListData[MAXLEN+1];//保存顺序表的结构数组
	int ListLen;			//顺序表已存结点的数量 
}; 

定义了顺序表的最大长度MAXLEN、顺序表数据元素的类型DATA以及顺序表的数据结构SLType。

在数据结构SLType中,Listen为顺序表已存结点的数量,也就是当前顺序表的长度,ListData是一个结构数组,用来存放各个数据结点。

我们认为该顺序表是一个班级学生的记录。其中,key为学号,name为学生的名称,age为年龄。

因为数组都是从下标0开始的,为了使用方便,我们从下标1开始记录数据结点,下标0的位置不可用。


初始化顺序表


在使用顺序表之前,首先创建一个空的顺序表,也就是初始化顺序表。这里,在程序中只需设置顺序表的结点数量ListLen为0即可。这样,后面需要添加的数据元素将从顺序表的第一个位置存储。
示例代码:
void SLInit(SLType * SL)	//初始化顺序表
{
	SL->Listlen=0; 
} 

计算线性表的长度


计算线性表的长度也就是计算线性表中结点的个数,由于我们在SLType中定义了ListLen来表示结点的数量,所以我们只需要获得这个变量的值即可。
int SLLenght(SLType *SL)
{
	return(SL->ListLen);	//返回顺序表的元素数量 
} 

插入结点


插入节点就是在线性表L的第i个位置上插入一个新的结点,使其后的结点编号依次加1。
这时,插入一个新节点之后,线性表L的长度将变为n+1。插入结点操作的难点在于随后的每个结点数据都要向后移动,计算机比较大,示例代码如下:
int SLInsert(SLType *SL,int n,DATA data)
{
	int i;
	if(SL->ListLen>=MAXLEN)	//顺序表结点数量已超过最大数量
	{
		cout<<"顺序表已满,不能插入结点!"<<endl;
		return 0;			//返回0表示插入不成功 
	} 
	if(n<1||n>SL->ListLen)	//插入结点的序号不合法 
	{
		cout<<"插入序号错误!"<<endl;
		return 0;
	}
	for(i=SL->ListLen;i>=n;i--)	//将顺序表中的数据向后移动
	{
		SL->ListData[i+1]=SL->ListData[i];
	}
	SL->ListData[n]=data;
	SL->ListLen++;
	return 1; 
}

在程序中首先判断顺序表结点数量时候已超过最大数量,以及插入点的序号是否正确。前面条件都瞒住以后,便将顺序表中的数据向后移动,同时插入结点,并更新结点数量ListLen。

追加结点


追加结点就是在顺序表的尾部插入结点,因此不必进行大量数据的移动,代码实现与插入结点相比就要简单的多。
int SLAdd(SLType * SL,DATA data)
{
	if(SL->ListLen>=MAXLEN)
	{
		cout<<"顺序表已满,不能再添加结点了!"<<endl;
		return 0;
	} 
	SL->ListData[++SL->ListLen]=data;
	return 1;
}

删除结点


删除结点就是删除线性表L中的第i个结点,使得其后的所有节点编号依次减1.这是,删除一个结点之后,线性表L的长度将变为n-1。删除结点和插入结点类似,都需要进行大量数据的移动。

int SLDelete(SLType *SL,int n)	//删除顺序表中的数据元素
{
	int i;
	if(n<1||n>SL->ListLen)	//删除结点的序号不合法 
	{
		cout<<"删除序号错误!"<<endl;
		return 0;
	}
	for(i=n;i<SL->ListLen;i++)//将顺序表中的数据向前移动 
	{
		SL->ListData[i]=SL->ListData[i+1]; 
	} 
	SL->ListLen--;			//顺序表元素数量减1 
	return 1;				//成功删除返回1 
} 

查找结点


查找节点就是在线性表L中查找值为x的结点,并返回该节点在线性表L中的位置。如果在线性表中没有找到值为x的结点,则返回一个错误标志。
根据x的类型不同,查找结点可以分为:

按照序号查找结点


对于一个顺序表,序号就是数据元素在数组中的位置,也就是数组的下标标号。按照序号查找结点是顺序表查找结点最常用的方法,这是因为顺序表的存储本身就是一个数组,示例代码如下:
DATA * SLFindByNum(SLType *SL,int n)//根据呼号返回数据元素
{
	if(n<1||n>SL->ListLen)			//查询结点的序号不合法 
	{
		cout<<"查询序号错误!"<<endl;
		return 0;
	}
	return &(SL->ListData[n]); 
} 


按照关键字查找结点


关键字可以是数据元素中的任意一项。
这里以key关键字为例进行介绍,例如,可以通过key查找学生的信息。示例代码如下:
int SLFindByCont(SLType * SL,char *key)//按关键字查询结点 
{
	int i;
	for(i=1;i<=SL->ListLen;i++)
	{
		if(strcmp(SL->ListData[i].key,key)==0)//如果找到结点 
		{
			return i;
		}
	}
	return 0;						//在整个表中都没有找到,返回0 
} 

显示所有的结点


示例代码如下:
void SLALL(SLType *SL)
{
	int i;
	for(i=1;i<SL->ListLen;i++)
	{
		cout<<"key:"<<SL->ListData[i].key<<endl;
		cout<<"name:"<<SL->ListData[i].name<<endl;
		cout<<"age:"<<SL->ListData[i].age<<endl;
		cout<<"============================="<<endl; 
	}
} 

顺序表操作完整示例:


基本上就是把上面的函数放到一块,集中展示了一下功能,代码有些长,请耐心阅读^.^

#include<iostream>
#include<string>
using namespace std;
#define MAXLEN 100	//定义顺序表的最大长度
/**************顺序表的定义部分*****************/ 
struct DATA
{
	string key;	//结点的关键字 
	string  name;
	int age;
};
struct	SLType	//定义顺序表结构 
{
	DATA ListData[MAXLEN+1];//保存顺序表的结构数组
	int ListLen;			//顺序表已存结点的数量 
}; 
/************顺序表的初始化函数*****************/ 
void SLInit(SLType * SL)	//初始化顺序表
{
	SL->ListLen=0; 
} 
/***********计算线性表的长度*******************/
int SLLenght(SLType *SL)
{
	return(SL->ListLen);	//返回顺序表的元素数量 
} 
/*********插入结点*******************************/
int SLInsert(SLType *SL,int n,DATA data)
{
	int i;
	if(SL->ListLen>=MAXLEN)	//顺序表结点数量已超过最大数量
	{
		cout<<"顺序表已满,不能插入结点!"<<endl;
		return 0;			//返回0表示插入不成功 
	} 
	if(n<1||n>SL->ListLen)	//插入结点的序号不合法 
	{
		cout<<"插入序号错误!"<<endl;
		return 0;
	}
	for(i=SL->ListLen;i>=n;i--)	//将顺序表中的数据向后移动
	{
		SL->ListData[i+1]=SL->ListData[i];
	}
	SL->ListData[n]=data;
	SL->ListLen++;
	return 1; 				//成功插入,返回1 
}
/***********************追加结点*************************/ 
int SLAdd(SLType * SL,DATA data)
{
	if(SL->ListLen>=MAXLEN)
	{
		cout<<"顺序表已满,不能再添加结点了!"<<endl;
		return 0;
	} 
	SL->ListData[++SL->ListLen]=data;
	return 1;
}
/***********************删除结点*************************/ 
int SLDelete(SLType *SL,int n)	//删除顺序表中的数据元素
{
	int i;
	if(n<1||n>SL->ListLen)	//删除结点的序号不合法 
	{
		cout<<"删除序号错误!"<<endl;
		return 0;
	}
	for(i=n;i<SL->ListLen;i++)//将顺序表中的数据向前移动 
	{
		SL->ListData[i]=SL->ListData[i+1]; 
	} 
	SL->ListLen--;			//顺序表元素数量减1 
	return 1;				//成功删除返回1 
} 
/*******************按照序号查找结点********************/
DATA * SLFindByNum(SLType *SL,int n)//根据序号返回数据元素
{
	if(n<1||n>SL->ListLen)			//查询结点的序号不合法 
	{
		cout<<"查询序号错误!"<<endl;
		return 0;
	}
	return &(SL->ListData[n]); 
} 
/*******************按照关键字查找结点********************/
DATA *SLFindByCont(SLType * SL,string name)//按关键字查询结点 
{
	int i;
	for(i=1;i<=SL->ListLen;i++)
	{
		if(SL->ListData[i].name==name)//如果找到结点 
		{
			return &(SL->ListData[i]);
		}
	}
	return 0;						//在整个表中都没有找到,返回0 
} 
/*******************显示所有的结点********************/
void SLALL(SLType *SL)
{
	int i;
	for(i=1;i<=SL->ListLen;i++)
	{
		cout<<"key:"<<SL->ListData[i].key<<",name:"<<SL->ListData[i].name<<",age:"<<SL->ListData[i].age<<endl;
	}
} 
int main()
{
	int i;
	SLType SL;	//定义顺序表变量 
	DATA data;	//定义结点保存数据类型变量 
	DATA *pdata;//定义指向结点的指针变量
	string name;
	cout<<"顺序表操作演示:"<<endl;
	SLInit(&SL);//初始化顺序表
	do
	{	//循环添加结点数据 
		cout<<"请输入要添加的结点(学号 姓名 年龄):";
		cin>>data.key>>data.name>>data.age;
		if(data.age)		//若年龄不为0
		{
			if(!SLAdd(&SL,data))//若添加结点失败 
			{
				break;			//退出循环 
			}
		}else
		{
			break;
		} 
	}while(1);
	cout<<"顺序表中的结点顺序为:" <<endl;
	SLALL(&SL);				//显示所有的结点
	cout<<"请输入要取出的结点序号:";
	cin>>i;
	pdata=SLFindByNum(&SL,i);//按序号查找结点
	if(pdata)
	{
		cout<<"第"<<i<<"个结点为:key:"<<pdata->key<<",name:"<<pdata->name<<",age:"<<pdata->age<<endl;
	} 
	cout<<"请输入要查找的姓名:";
	cin>>name;
	pdata=SLFindByCont(&SL,name);
	if(pdata)
	{
		cout<<"key:"<<pdata->key<<",name:"<<pdata->name<<",age:"<<pdata->age<<endl;
	} 
	cout<<"请输入您要删除的结点的序号:";
	cin>>i;
	if(SLDelete(&SL,i))
	{
		cout<<"数据删除成功"<<endl;
		SLALL(&SL);	
	}
	cout<<"请输入您要插入的结点的序号:";
	cin>>i;
	cout<<"请输入第"<<i<<"号结点的key,name,以及age"<<endl;
	cin>>data.key>>data.name>>data.age;
	if(SLInsert(&SL,i,data))
	{
		cout<<"插入数据成功"<<endl;
		SLALL(&SL);	
	} 
	return 0;
}

运行界面:
好啦,时间不早了,大家晚安~

转载于:https://www.cnblogs.com/zhezh/p/3773391.html

<think>好的,我需要回答用户在C++中如何向顺序表输入数据的问题。首先,我应该回忆顺序表的基本结构。顺序表通常是使用数组来存储数据的,所以需要一个动态数组,以及记录容量和当前大小的变量。比如,用户提供的引用中提到了SL结构体,可能包含a(数组指针)、size(当前元素个数)、capacity(总容量)。接下来,数据输入的方法可能有几种:逐个输入、批量插入、文件读取等。 逐个输入的话,可能需要循环接收用户输入,并调用插入函数,比如Insert函数,将每个元素添加到顺序表中。需要注意检查容量是否足够,如果不够的话需要扩容,比如使用realloc或者new重新分配更大的内存空间。 批量插入的话,可以一次性输入多个数据,可能通过指定数量或者特殊结束符来终止输入。比如用户输入n个数据,然后循环插入。或者像示例中的Insert函数,支持在指定位置插入元素,这里可能需要先输入位置和值,或者直接追加到末尾。 文件读取的话,需要打开文件,读取数据,并逐个或批量插入到顺序表中。这可能涉及文件操作函数,如fstream的使用。 用户提供的代码中有SeqListPrint函数,用来打印数据,这可以作为输入后的验证。同时,引用的资料提到了增删查改的接口函数,所以可能需要结合这些接口来实现数据输入。 还需要考虑输入时的错误处理,比如输入的数据类型是否匹配,位置是否合法等。例如,当用户输入的位置超过当前size时,应该提示错误或者自动调整位置。 另外,C++中可能使用类来封装顺序表,但用户提供的代码中使用的是结构体SL,可能更偏向C风格,但结合了C++的输入输出,比如cout。所以实现数据输入时,可能需要使用cin来获取用户输入的值。 总结一下,步骤可能包括: 1. 初始化顺序表,分配初始内存。 2. 选择输入方式:逐个、批量或文件读取。 3. 循环接收输入,调用插入函数。 4. 每次插入前检查容量,不足时扩容。 5. 处理可能的输入错误。 6. 输入完成后,调用打印函数验证数据。 然后,生成相关问题,可能涉及扩容策略、不同插入方式的效率、输入验证的方法等。</think>在C++中向顺序表输入数据通常需要结合动态数组和插入函数实现。以下是具体实现方法及代码示例: ### 一、顺序表数据结构定义 ```cpp typedef struct { int* a; // 动态数组指针 int size; // 当前元素个数 int capacity; // 总容量 } SL; ``` ### 二、数据输入实现方法 #### 方法1:逐个输入元素(尾部插入) ```cpp void InputData(SL* ps) { int num; cout << "输入元素(输入-1结束): "; while (cin >> num && num != -1) { // 检查容量是否足够 if (ps->size == ps->capacity) { int newCap = ps->capacity == 0 ? 4 : ps->capacity * 2; int* tmp = new int[newCap]; // C++风格扩容 memcpy(tmp, ps->a, ps->size * sizeof(int)); delete[] ps->a; ps->a = tmp; ps->capacity = newCap; } // 插入数据 ps->a[ps->size++] = num; } } ``` #### 方法2:指定位置插入(使用Insert接口) ```cpp void InsertData(SL* ps) { int pos, val; cout << "输入插入位置和值(位置从0开始):"; while (cin >> pos >> val) { if (pos < 0 || pos > ps->size) { // 验证位置合法性 cout << "非法插入位置!" << endl; continue; } // 调用已实现的插入函数[^1] SeqListInsert(ps, pos, val); cout << "继续输入?(y/n)"; char ch; cin >> ch; if (ch == 'n') break; } } ``` ### 三、输入验证建议 1. 使用`cin.fail()`检测非法输入 2. 添加输入范围限制 3. 清空输入缓冲区防止错误累积 ```cpp cin.clear(); while (cin.get() != '\n') continue; ``` ### 四、使用示例 ```cpp int main() { SL list; InitSeqList(&list); // 初始化顺序表[^1] InputData(&list); SeqListPrint(&list); // 打印验证 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值