线性表的基本操作与顺序有序表的合并
1,线性表:最典型最常用的线性结构,只有一个首结点和尾结点,除首尾结点外,其他结点都只有一个直接前驱和直接后继,即结点间的逻辑结构是一对一的。
2,线性表基本操作:结构的初始化和销毁操作,引用型与加工型操作。
引用型操作:线性表的判空、线性表求长度、线性表求前驱后继、得到线性表固定位置上的元素值、求元素在线性表中的位置和遍历线性表;
加工型操作:线性表置空、改变线性表中元素的值、插入数据元素和删除数据元素。
3,两个顺序有序表的合并
实验要求:已知线性表LA和LB中的数据元素按值非递减有序排列,现要求将LA和LB中的数据元素归并到线性表LC,且LC中的元素同样按值呈非递减有序排列。
实验分析:LC中的元素要么存在于LA中,要么存在于LB中,只需设置空表LC,将LA和LB中的元素依次插入到LC即可。
4,实验的实现功能:
5,实验功能函数部分和主函数代码:
//头文件
#include<iostream>
#include<cstdlib>
using namespace std;
宏定义与结构体定义部分:
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
#define MAXSIZE 100 //顺序表可能达到的最大长度
typedef struct{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList;
//算法2.1 顺序表的初始化,构造一个空的顺序表L,顺序表分配一个大小为MAXSIZE的数组空间
Status InitList_Sq(SqList &L){
L.elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType)); //将L.elem这个指针指向一块通过malloc函数分配的内存的地址
if(!L.elem) exit(OVERFLOW); //存储分配失败,exit(1)表示正常退出进程,exit(其他)表示强制退出进程
L.length = 0; //空表长度为0,里面的元素个数是0
return OK;
}
//分配空间只是说改顺序表有这么大的内存空间,在顺序表中输入数据之前顺序表的长度依然是0
void InitList(SqList &L,int n) //创建顺序表,功能14合并两个线性表
{
L.elem = (int *)malloc(n * sizeof(int));
L.length = n;
}
void input(SqList &L,int n) //依次往顺序表L里输入数据,功能14合并两个线性表
{
int i;
for(i=0;i<n;i++)
{
cin>>L.elem[i];
}
cout<<endl;
}
void output(SqList L) //依次输出顺序表里的每个元素
{
int i;
for(i=0;i<=L.length-1;i++)
{
cout<<L.elem[i]<<" ";
}
cout<<endl;
}
void MergeList_Sq(SqList LA,SqList LB,SqList &LC)
//算法 顺序有序表的合并
{
//已知顺序有序表LA和LB的元素按值非递减排列
//归并LA和LB得到新的顺序有序表LC,LC的元素也按值非递减排列
int *pa,*pb,*pc,*pa_last,*pb_last;
pa = LA.elem;
pb = LB.elem;
//指针pa和pb的初值分别指向两个表的第一次元素
LC.length = LA.length + LB.length;
//新表长度为待合并两表的长度之和
LC.elem = (int *)malloc(LC.length * sizeof(int));
//为合并后的新表分配一个数组空间
pc = LC.elem;
//指针pc指向新表的第一个元素
pa_last = LA.elem + LA.length-1;
//指针pa_last指向LA表的最后一个元素
pb_last = LB.elem + LB.length-1;
//指针pb_last指向LB表的最后一个元素
while(pa<=pa_last && pb<=pb_last){//两个表都非空
if (*pa<=*pb)
*pc++=*pa++;
else
*pc++=*pb++; }
//依次“摘取”两表中值较小的结点插入到LC表的最后
while(pa<=pa_last)
//LA已到达表尾,依次将LB的剩余元素插入LC表的最后
{*pc++=*pa++; }
while(pb<=pb_last)
//LB已到达表尾,依次将LA的剩余元素插入LC表的最后
{*pc++=*pb++; }
} //MergeList_List
//输入数据
Status input_Sq(SqList &L){
cout<<"请输入10个数:";
for(int i=0;i<10;++i)
{
cin >> L.elem[i];
++L.length;
}
return OK;
}
//线性表的销毁操作
Status Destory_Sq(SqList &L){
free(L.elem);
L.elem = NULL;
L.length = 0;
return OK;
}
//线性表的清空操作
Status Clear_Sq(SqList &L){
InitList_Sq(L);
L.length = 0;
return OK;
}
//判断线性表是否为空
Status SqEmpty(SqList &L){
if(L.length == 0)
return OK;
else
return ERROR;
}
Status HqSq(SqList &L,ElemType e){
// return L.elem[e-1];
if(e<0 || e>= L.length)
return ERROR;
else
return OK;
}
//求前驱
int Qq_Sq(SqList L,ElemType e){
int i;
for(i=0;i<L.length;i++)
{if(L.elem[i]==e)
{if(i == 0)
cout<<"第一个元素无前驱。\n";
else
cout<<"该元素前驱的值是:"<<L.elem[i-1]<<endl;
//返回前驱的值
}
}
//求后继
int Hj_Sq(SqList L,ElemType e){
int i;
for(i=0;i<L.length;++i)
{
if(L.elem[i]==e)
{
if(i == L.length-1)
cout<<"最后一个元素无后继。\n";
else
cout<<"该元素后继的值是:"<<L.elem[i+1]<<endl;
}
}
//算法2.2 顺序表的查找
int LocateElem_Sq(SqList L,ElemType e){
int i;
for(i=0;i<L.length;++i)
{
if(L.elem[i]==e)
{
return i; //如果存在,返回位置
}
}
return 0;
}
//算法2.3 顺序表的插入,在顺序表L中第i个位置之前插入新的元素e
Status ListInsert_Sq(SqList &L,int i,ElemType e){
if(i<1||i>L.length+1) //i值的合法范围是1<=i<=L.length
return ERROR; //i值不合法
if(L.length>=MAXSIZE) //当前存储空间已满
return ERROR;
for(int j=L.length-1;j>=i-1;--j)
L.elem[j+1] = L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1] = e; //将新元素e放入第i个位置
L.length++; //表长增1
return OK;
}
//算法2.4 顺序表的删除,在顺序表L中删除第i个元素,并用e返回其值
Status ListDelete_Sq(SqList &L,int i,ElemType &e){
if(i<1||i>L.length) //i值的合法范围是1<=i<=L.length
return ERROR; //i值不合法
e = L.elem[i-1]; //将欲删除的元素保留在e中
for(int j=i;j<L.length;++j)
L.elem[j-1] = L.elem[j]; //被删除元素之后的元素前移
L.length--; //表长减1
return OK;
}
//主函数
int main()
{
SqList L,La,Lb,Lc;
int i,res,temp,a,b,c,e,choose,num_a,num_b;
cout<<"1----初始化一个线性表"<<endl;
cout<<"2----向线性表中输入数据"<<endl;
cout<<"3----销毁线性表"<<endl;
cout<<"4----清空线性表"<<endl;
cout<<"5----判断线性表是否为空"<<endl;
cout<<"6----求线性表长度"<<endl;
cout<<"7----获取线性表中指定位置的元素"<<endl;
cout<<"8----获取线性表中元素的位置"<<endl;
cout<<"9----求前驱"<<endl;
cout<<"10---求后继"<<endl;
cout<<"11---在线性表中指定位置插入元素"<<endl;
cout<<"12---删除线性表中指定位置的元素"<<endl;
cout<<"13---显示线性表"<<endl;
cout<<"14---合并两个非递减有序的线性表"<<endl;
cout<<"0----退出,输入一个负数"<<endl;
while(choose >= 0)
{
cout<<"请选择:";
cin>>choose;
switch(choose)
{
case 1:
if(InitList_Sq(L)) //创建初始化顺序表
cout<<"顺序表的创建与初始化成功\n";
else
cout<<"顺序表创建失败\n";
cout<<endl;
break;
case 2:
if(InitList_Sq(L)){
if(input_Sq(L))
cout << "线性表输入数据成功!\n";
else
cout << "输入数据失败!\n";
}
else
cout<<"请先利用功能1对线性表进行初始化操作。\n";
cout<<endl;
break;
case 3: //销毁线性表
if(InitList_Sq(L)){
if(Destory_Sq(L))
cout<<"线性表销毁成功!\n";
else
cout<<"线性表销毁失败!\n";
}
else
cout<<"请先利用功能1对线性表进行初始化操作。\n";
cout<<endl;
break;
case 4: //清空线性表
if(input_Sq(L)){
if(Clear_Sq(L))
cout<<"线性表清空成功!\n";
else
cout<<"线性表清空失败!\n";
}
else
cout<<"线性表为空表,无需对其进行清空操作。\n";
cout<<endl;
break;
case 5: //判断线性表是否为空
if(SqEmpty)
cout<<"线性表不为空。\n";
else
cout<<"线性表为空。\n";
cout<<endl;
break;
case 6: //线性表长度
cout<<"线性表长度为:" <<L.length<<endl;
cout<<endl;
break;
case 7:
cout<<"请输入位置:";
cin>>e;
if(HqSq(L,e))
cout<<"该位置上的元素是:"<<L.elem[e]<<endl;
else
cout<<"该位置上没有元素。"<<endl;
cout<<endl;
break;
case 8: //获取线性表中元素的位置
cout<<"请输入所要查找的数:";
cin >> e; //输入e,代表所要查找的数值
if(LocateElem_Sq(L,e)!=0)
cout << "所要查找的数的位置为" << LocateElem_Sq(L,e) << endl;
else
cout << "这个数不存在在顺序表中!" << endl;
cout<<endl;
break;
case 9: //求前驱
cout<<"请输入需要求前驱的元素的值:";
cin>>e;
Qq_Sq(L,e);
cout<<endl;
break;
case 10: //求后继
cout<<"请输入需要求后继的元素的值:";
cin>>e;
Hj_Sq(L,e);
cout<<endl;
break;
case 11: //在线性表中指定位置插入元素
cout<<"请输入两个数,分别代表插入的位置和插入数值:";
cin>>a>>b; //输入a和b,a代表插入的位置,b代表插入的数值
if(ListInsert_Sq(L,a,b))
cout<<"已插入!"<<endl;
else
cout<<"位置超出顺序表范围或者是顺序表内存已满!"<<endl;
cout<<endl;
break;
case 12: //删除线性表中指定位置的元素
cout<<"请输入所要删除的数的位置:";
cin>>c; //输入c,代表要删除数的位置
ElemType e;
if(ListDelete_Sq(L,c,e))
cout<<"删除数"<<e<<"成功!"<<endl ;
else
cout<<"删除失败!"<<endl;
cout<<endl;
break;
case 13: //显示线性表
cout<<"当前顺序表为:\n";
output(L);
cout<<endl;
break;
case 14:
cout<<"请输入非递减线性表a的个数:";
cin>>num_a;
cout<<"请输入具体数据:";
InitList(La,num_a); //La表的创建
input(La,num_a); //依次往顺序表La里输入数据
cout<<endl;
cout<<"请输入非递减线性表b的个数n:";
cin>>num_b;
cout<<"请输入具体数据:";
InitList(Lb,num_b);
//Lb表的创建
input(Lb,num_b);
//依次往顺序表Lb里输入数据
MergeList_Sq(La,Lb,Lc);
//将顺序表La和Lb进行合并
cout<<"非递减线性表a,b合并后的非递减线性表c为:\n";
output(Lc); //输出合并后的有序顺序表Lc
cout<<endl;
break;
case 0:
cout<<"输入任意一个负数结束程序的运行:" ;
cin>>choose;
break;
}
}
return 0;
}
6,实验运行结果截图: