线性表的顺序表示和实现-C语言

2019/10/7 周一

一、顺序表和线性表的简介

在这里插入图片描述

二、顺序表的所有常见操作

PS:我写的表基本上都是默认线性表已存在,所以如果在实际中最好还是在函数的最开始加上 if(L.elem) ,除去链表可能为空的情况

(1)、常见函数操作目录

/*【常见操作的函数】*/
Status InitList_Sq(SqList &L);//【1】、构造一个空的线性表
Status DestoryList(SqList &L);//【2】、销毁已存在的线性表L
Status ClearList(SqList &L);//【3】、将线性表重置为空表
Status ListEmpty(SqList L);//【4】、判断线性表是否为空表,若是返回TRUE,反之返回FALSE
Status GetElem(SqList L,int i,ElemType *e);//【5】、用e返回线性表L中第 i 个元素,i的范围为1<= i <= L.length
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType));
// 【6】、在顺序线性表中查找第1个值与e满足compare的元素的位序
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e);
//【7】、若cur_e是线性表L中的数据元素且不是第一个,则用pre_e返回他的前驱;否则操作失败,pre_e无定义
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e);
//【8】、若cur_e是线性表L中的数据元素且不是最后一个,则用next_e返回他的后继;否则操作失败,next_e无定义
Status ListInsert_Sq(SqList &L,int i,ElemType e);
//【9】、在顺序表第I个位置之前插入新的元素e
void CreatList_Sq(SqList &L,int n);
//【10】、表尾插入法建立一个顺序储存的线性表
Status ListDelete_Sq(SqList &L,int i,ElemType &e);
//【11】、算法2.5 在顺序线性表L中删除第I个元素,并用e返回元素的值,L的长度减1

(2)、操作执行代码

A、头文件
#include <stdlib.h>/*atoi()*/
#include <malloc.h>/*malloc()等*/
#include <memory.h>
#include <tchar.h>
#include<iostream.h>
#include<string.h>
#include<ctype.h>
#include<limits.h>/*INT_MAX等*/
#include<stdio.h>/*EOF(=^Z或F6),NULL*/
#include<io.h>/*eof()*/
#include<math.h>/*floor(),ceil(),abs()*/
#include<process.h>/*exit()*/

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1/*infeasible*/
#define LIST_INIT_SIZE 100/*list_init_size线性表存储空间的初始分配量*/
#define LIST_INCREMENT 10 /*list_increment线性表存储空间的分配增量*/
typedef int Status;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
 /* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/
typedef int Boolean;/*Boolean是布尔类型,其值是TRUE或FALSE*/
typedef int ElemType;

typedef struct{
	ElemType	*elem;//存储空间基址
	int			length;//当前长度
	int			listsize;//当前分配的存储器容量
}SqList;


/*【常见操作的函数】*/
Status InitList_Sq(SqList &L);//【1】、构造一个空的线性表
Status DestoryList(SqList &L);//【2】、销毁已存在的线性表L
Status ClearList(SqList &L);//【3】、将线性表重置为空表
Status ListEmpty(SqList L);//【4】、判断线性表是否为空表,若是返回TRUE,反之返回FALSE
Status GetElem(SqList L,int i,ElemType *e);//【5】、用e返回线性表L中第 i 个元素,i的范围为1<= i <= L.length
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType));
// 【6】、在顺序线性表中查找第1个值与e满足compare的元素的位序
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e);
//【7】、若cur_e是线性表L中的数据元素且不是第一个,则用pre_e返回他的前驱;否则操作失败,pre_e无定义
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e);
//【8】、若cur_e是线性表L中的数据元素且不是最后一个,则用next_e返回他的后继;否则操作失败,next_e无定义
Status ListInsert_Sq(SqList &L,int i,ElemType e);
//【9】、在顺序表第I个位置之前插入新的元素e
void CreatList_Sq(SqList &L,int n);
//【10】、表尾插入法建立一个顺序储存的线性表
Status ListDelete_Sq(SqList &L,int i,ElemType &e);
//【11】、算法2.5 在顺序线性表L中删除第I个元素,并用e返回元素的值,L的长度减1

/*【显示函数】*/
void ListPrint(SqList L);/*显示函数*/

/*【元素之间关系判定函数】*/
Status comp(ElemType c1,ElemType c2);/*【1】、数据元素判定函数(平方关系)*/
int equal(ElemType c1,ElemType c2);/*【2】、判断是否相等函数*/
B、函数操作
PS:记得写上头文件哦!例如:#include “Ctest4.h”
1、构造一个空的线性表
/*算法2.3 构造一个空的线性表 */
/*构造一个空的线性表*/
Status InitList_Sq(SqList &L)
{
	L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));//在计算机内开辟空间
	/*利用malloc分配100*sizeof(int)个字节的内存变量,并且将此内存首字节的指针强制转换为ElemType类型的指针*/
	if(!L.elem)exit(OVERFLOW);//存储分配失败
	L.length = 0;//称长度为0的表为空表
	L.listsize = LIST_INIT_SIZE;//初始存储容量
	return OK;
}
2、销毁已存在的线性表L
Status DestoryList(SqList &L)
{
	free(L.elem);
	L.elem = NULL;
	L.length = 0;
	L.listsize = 0;
	return OK;
}
3、将线性表重置为空表
//将线性表重置为空表
Status ClearList(SqList &L)
{
	L.length = 0;	return OK;
}
4、判断线性表是否为空表,若是返回TRUE,反之返回FALSE
Status ListEmpty(SqList L)
{
	if(L.length == 0) return TRUE;
	else return FALSE;
}
5、//用e返回线性表L中第 i 个元素
Status GetElem(SqList L,int i,ElemType *e)
{
	if(i<1||i>L.length)	exit(ERROR);
	*e = *(L.elem + i -1);//或者*e = L.elem[i-1]
	return OK;
}
6、在顺序线性表中查找第1个值与e满足compare的元素的位序
/*算法2.6 在顺序线性表中查找第1个值与e满足compare的元素的位序*/
//在顺序线性表中查找第1个值与e满足compare的元素的位序,找到返回元素位序,反之返回0
//compare()函数可随意指定,例如判断函数是否相等,判断函数的值的大小
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
{
	cout<<"进入LocateElem()"<<endl;
	int i;ElemType *p;
	i = 1;	p = L.elem;
	while(i<=L.length && !(*compare)(*p++,e) )++i;
	if(i<=L.length )return i;
	else return 0;
}
7、若cur_e是线性表L中的数据元素且不是第一个,则用pre_e返回他的前驱;否则操作失败,pre_e无定义
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
	cout<<"进入PriorElem()"<<endl;
	int i=2;
	ElemType *p = L.elem;
	if(*p == cur_e)return ERROR;
	while(*(p+i-1)!=cur_e&&i<=L.length)
	{
		i++;*p++;
	}
	if(i>L.length) return INFEASIBLE;
	else {	--*p;pre_e = *p;	return OK;	}
}
8、若cur_e是线性表L中的数据元素且不是最后一个,则用next_e返回他的后继;否则操作失败,next_e无定义
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e)
{
	cout<<"进入NextElem()"<<endl;
	int i=0;
	ElemType *p = L.elem;
	while(*(p+i)!=cur_e && i<L.length)
	{	
		i++;	*p++;	
	}
	if(i == L.length)return INFEASIBLE;
	else {	*next_e = *++p;	return OK;	}
}

9、在顺序表第I个位置之前插入新的元素e
/*算法2.4 在顺序表第I个位置之前插入新的元素e */
//在顺序表第I(1<=i<=L.length+1)个位置之前插入新的元素e
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
	cout<<"进入ListInsert_Sq"<<endl;
	ElemType *newbase,*p,*q;
	if(i>L.length+1 || i<1 )return ERROR;
	if(L.length >= L.listsize ){
		newbase = (ElemType *)realloc(L.elem ,(L.listsize +LIST_INCREMENT)*sizeof(ElemType));
		//是重新分配一块空间,还是在原有的基础上增加????

		if(!newbase)exit(OVERFLOW);//存储分配失败
		L.elem = newbase;//新基址
		L.listsize += LIST_INCREMENT;//增加存储容量
	}
	q = &(L.elem[i-1]);//q为插入的位置
	for(p = &(L.elem[L.length - 1]);p>=q;--p) *(p+1) = *p;//插入位置之后的元素后移
	*q = e;//将q指向e,即插入e
	++L.length ;//表长增加1
	return OK;
}
10、表尾插入法建立一个顺序储存的线性表
void CreatList_Sq(SqList &L,int n)
{
	cout<<"进入CreatSqList()"<<endl;
	int i,e;
	for(i=1; i<=n; i++)
	{
		cin>>e;ListInsert_Sq(L,i,e);
	}
}
11、在顺序线性表L中删除第I个元素,并用e返回元素的值
Status ListDelete_Sq(SqList &L,int i,ElemType &e)
{
	cout<<"进入ListDelete_Sq()"<<endl;
	ElemType *p,*q;
	if(i<1 || i>L.length) return ERROR;
	p = &(L.elem[i-1]);//p为被删除元素的位置
	e = *p;//用e保存被删除的元素
	q = &(L.elem[L.length-1]);//或者q=L.elem+L.length-1指得也是表为元素的位置
	for(++p;p<=q;++p) *(p-1) = *p;//被删除元素之后的元素左移
	/*注意:前面的++p*/
	--L.length;//表长减1
	return OK;
}
12、打印顺序表
//Status ListTraverse(SqList L,void )即是打印函数
void ListPrint(SqList L)
{
	cout<<"进入ListPrint()"<<endl;
	int i;
	ElemType *p=L.elem ;
	for(i=0; i<L.length; i++)
		cout<<"第"<<i+1<<"个元素为:"<<*(p+i)<<endl;
}
C、元素之间关系判定函数
/*元素之间关系判定函数*/
/*【1】、数据元素判定函数(平方关系)*/
Status comp(ElemType c1,ElemType c2)
{
	if(c1==c2*c2) return TRUE;
	else return FALSE;
}

/*【2】、判断是否相等函数*/
int equal(ElemType c1,ElemType c2)
{
	if(c1==c2)return TRUE;
	else return FALSE;
}
D、菜单函数
void menu()
{
	cout<<"1--新建顺序表"<<endl;
	cout<<"2--显示顺序表中的元素"<<endl;
	cout<<"3--在顺序表中查找元素X"<<endl;
	cout<<"4--在顺序表中查找元素X的平方"<<endl;
	cout<<"5--获取顺序表中第i个元素"<<endl;
	cout<<"6--向顺序表中插入一个元素"<<endl;
	cout<<"7--从顺序表中删除一个元素"<<endl;
	cout<<"0--退出"<<endl;
}
E、主函数
PS:为了更直观的显示函数操作,我用switch对函数进行了调用,如果有什么不恰的地方,欢迎留言指正哦。
void main()
{
	SqList L;ElemType e;
	Status i;int k,m,n,x;
	i = InitList_Sq(L);
	menu();
	while(k)
	{
		cout<<"请输入0-7的数字"<<endl;
		cin>>m;
		switch(m)
		{
		case 0:cout<<"退出了哦!!!"<<endl;break;
		case 1:{
			   if(L.length !=0) 
			   {	cout<<"已经存在一个线性表了哦。"<<endl;	
					ListPrint(L);break;
			   }
			   else{
					cout<<"请输入元素的个数"<<endl;
					cin>>n;
					CreatList_Sq(L,n);	ListPrint(L); break;
				}
			   }
		case 2:{
			   cout<<"当前顺序表的元素是:"<<endl;
			   ListPrint(L);break;
			   }
		case 3:{
				cout<<"请输入要查找的元素"<<endl;
				cin>>x;
				k = LocateElem(L,x,equal);
				if(k) cout<<"第一个"<<x<<"的位置为:"<<k;
				else cout<<"没有为"<<x<<"的元素";
				cout<<endl;break;
			   }
		case 4:{
			   cout<<"请输入要查找平方的元素"<<endl;
			   cin>>x;
			   k = LocateElem(L,x,equal);
			   if(k) cout<<"第一个等于"<<x<<"平方的元素的位置为:"<<k;
			   else cout<<"没有为"<<x<<"平方的元素";
			   cout<<endl;break;
			   }
		case 5:{
			   cout<<"输入要取出来的元素序号"<<endl;
			   cin>>i;
			   while(i<1||i>L.length)
			   {	cout<<"元素不合法请重新输入:"<<endl;	cin>>i;	}
			   GetElem(L,i,&e);
			   cout<<"取出的第"<<i<<"个元素为"<<e<<endl; break;
			   }
		case 6:{
			   cout<<"输入要插入的元素位置"<<endl;
			   cin>>i;
			   while(i<1||i>L.length+1)
			   {	cout<<"元素不合法请重新输入:"<<endl;	cin>>i;	}
			   cout<<"请输入要插入的元素:"<<endl;
			   cin>>e;
			   ListInsert_Sq(L,i,e);ListPrint(L);break;
			   }
		case 7:{
			   cout<<"输入要删除的元素位置"<<endl;
			   cin>>i;
			   while(i<1||i>L.length)
			   {	cout<<"元素不合法请重新输入:"<<endl;	cin>>i;	}
			   ListDelete_Sq(L,i,e);ListPrint(L);break;
			   }
		default:break;//return直接跳出了while的循环
			//break只是跳出了switch循环
		}
		cout<<"继续运行代码吗?"<<endl;
		cout<<"0-NO"<<'\n'<<"1-YES"<<endl;
		cin>>k;
		if(!k)return;
		/*【在这边如果为break则无法跳出循环????】*/
		menu();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值