线性表的动态表示和实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线性表的动态表示和实现
线性表采用动态生成方式,其私有数据成员只给出了指向存储节点数据的基址,在初始化时不必预先知道需要多长的数组,动态的确定线性表的长度.
声明部分:
//List.h
#pragma once
#define EQUAL 1
#define OVERFLOW -1
#define LIST_INIT_SIZE 30
#define LISTINCREMENT 10
#include <stdlib.h>
typedef struct STU{
char name[10];
char stuno[8];
int age;
int score;
}ElemType;
//线性表的动态分配顺序存储结构
class List {
private:
ElemType *elem;//存储空间基址
int length; //当前长度
int listsize;
//当前分配的存储容量以一数据元素存储长度为单位
public:
//初始化顺序表
void init(List *);
//删除顺序表
void DestroyList(List &L) {free(&L);}
//将顺序表置为空表
void ClearList() {length=0;}
//判断顺序表是否为空表
bool ListEmpty()
{if(length==0) return true;
else return false;}
//判断顺序表是否为满
bool ListFull()
{return length==listsize;}
//决定返回表中元素pre_e的前驱
ElemType PriorElem(ElemType cur_e,ElemType &pre_e);
// 决定返回表中元素next_e的后继
ElemType NextElem(ElemType cur_e,ElemType &next_e);
//删除顺序表中第i 个元素
bool ListDelete(int,ElemType &e);
//遍历顺序表
//遍历顺序表
void ListTraverse();
//返回顺序表的长度
int ListLength();
// 获取顺序表中第i 个元素
void GetElem(int,ElemType *);
// 判断顺序表两元素是否相等
bool EqualList(ElemType *,ElemType *);
// 判断顺序表两元素是否不等
bool Less_EqualList(ElemType *,ElemType *);
//顺序表的查找算法
bool LocateElem(ElemType,int);
//更新线性表中的给定元素
bool UpdateList(ElemType& e,ElemType);
//顺序表的合并算法
void MergeList(List *,List *);
public:
List(void);
public:
~List(void);
bool ListInsert(int i,struct STU e);
void UnionList(List *La, List *Lb);
void printlist(int mark);
};
实现部分:
//List.cpp
#include "List.h"
#include <string.h>
#include <iostream>
#include <iomanip>
using namespace std ;
List::List(void)
{
}
List::~List(void)
{
}
void List::init(List *L)
{ L->elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!L->elem) exit(OVERFLOW);
L->length=0;
L->listsize=LIST_INIT_SIZE;
}
int List::ListLength()
{ return length;}
//返回前驱
ElemType List::PriorElem(ElemType cur_e,ElemType &pre_e)
{for(int i=0;i<length;i++)
if(i!=0&&strcmp(cur_,elem[i].name)==0)
{pre_e=elem[i-1];return pre_e;}
return cur_e;
}
ElemType List::NextElem(ElemType cur_e,ElemType &next_e){
for(int i=0;i<length;i++)
if (i!=0&&strcmp(cur_,elem[i].name)==0)
{
next_e=elem[i+1];return next_e;
}
return cur_e;
}
bool List::ListDelete(int mark,ElemType &e)
{int i,j;
if(ListEmpty()) return false;
if(mark>0) { //删除表头元素
e=elem[0];
for(i=1;i<length; i++)
elem[i-1]=elem[i];}
else //删除表尾元素
if(mark<0) e=elem[length-1];
else { //删除值为e的元素
for(i=0;i<length;i++)
if(strcmp(elem[i].name,)==0) break;
if(i>=length) return false;
else e=elem[i];
for(j=i+1;j<length;j++)
elem[j-1]=elem[j];}
length--;
return true;
}
void List::ListTraverse()
{for(int i=0;i<length;i++)
{cout<<setw(8)<<elem[i].name;
cout<<setw(10)<<elem[i].stuno;
cout<<setw(9)<<elem[i].age;
cout<<setw(8)<<elem[i].score<<endl;}
}
void List::GetElem(int i,ElemType *e)
{ *e=elem[i];}
bool List::EqualList(ElemType *e1,ElemType *e2)
{ if(strcmp(e1->name,e2->name)==0) return true;
else return false;}
bool List::Less_EqualList(ElemType *e1,ElemType *e2) { if(strcmp(e1->name,e2->name)<=0) return true;
else return false;
}
bool List::LocateElem(ElemType e,int type)
{ int i;
switch (type)
{ case EQUAL:
for(i=0;i<length;i++)
if(EqualList(&elem[i],&e))
return true;
break;
default:break;}
return false;
}
bool List::UpdateList(ElemType& e,ElemType e1) {for(int i=0;i<length;i++)
if(strcmp(elem[i].name,)==0) {
elem[i]=e1;return true;}
return false;
}
void List::MergeList(List *La,List *Lb)
{ ElemType *pa,*pb,*pc,*pa_last,*pb_last;
pa=La->elem;pb=Lb->elem;//pa pb 分别指向表a 和表b 的第一个节点
listsize=length=La->length + Lb->length; //总表长为a+b
pc=elem=(ElemType *)malloc(listsize*sizeof(ElemType));//为pc分配为总表长的空间if(!elem) exit(OVERFLOW);//?
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(Less_EqualList(pa,pb)) *pc++=*pa++;//pa<pb pa表头都向前移一位pa赋予pc else *pc++=*pb++;}//否则pb表头向前移一位pb赋予pc
while(pa<=pa_last) *pc++=*pa++; //最后如果只剩pa 则把pa附加到pc
while(pb<=pb_last) *pc++=*pb++;//最后如果只剩pb 则把pb附加到pc
}
bool List::ListInsert(int i,struct STU e)//在i前插入e
{ struct STU *p,*q;
if (i<1||i>length+1) return false;//如果插入位置不合理
q=&elem[i-1];//将q指向原表中位置i
for(p=&elem[length-1];p>=q;--p)//对q之后的元素操作
*(p+1)=*p;//q之后的所有元素向后移一位
*q=e;//把e给q
++length;//长度加一
return true;
}
void List::UnionList(List *La, List *Lb)
{ int La_len,Lb_len;
int i;
ElemType e;
La_len=ListLength();Lb_len=Lb->ListLength();
for(i=0;i<Lb_len;i++)
{Lb->GetElem(i,&e);
if(!LocateElem(e,EQUAL))
ListInsert(++La_len,e);}
}
void List::printlist(int mark)
{int* b=new int[length];
int i,k;
cout<<" 姓名学号年龄成绩\n";
if(mark!=0) {
for(i=0; i<length;i++) b[i]=i;
for(i=0; i<length;i++) {k=i;
for(int j=i+1;j<length;j++) {
if(mark==1&&elem[b[j]].score<elem[b[k]].score) k=j;
if(mark==-1&&elem[b[k]].score<elem[b[j]].score) k=j;} if(k!=i) {int x=b[i];b[i]=b[k];b[k]=x;}}
for(int i=0;i<length;i++)
{cout<<setw(8)<<elem[b[i]].name;
cout<<setw(10)<<elem[b[i]].stuno;
cout<<setw(9)<<elem[b[i]].age;
cout<<setw(8)<<elem[b[i]].score<<endl;}}
else {
for(int i=0;i<length;i++)
{cout<<setw(8)<<elem[i].name;
cout<<setw(10)<<elem[i].stuno;
cout<<setw(9)<<elem[i].age;
cout<<setw(8)<<elem[i].score<<endl;}}
}
测试部分:
//MyList.cpp
#include<iostream>
#include<iomanip>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#include "List.h"
using namespace std;
void main()
{ cout<<"linelist2m.cpp运行结果:\n";
ElemType e,e1,e2,e3,e4,e5,e6;
List La,Lb,Lc;
int k;
cout<<"首先调用插入函数.\n";
La.init(&La);
strcpy(,"stu1");
strcpy(e1.stuno,"100001");
e1.age=22;
e1.score=88;
La.ListInsert(1,e1);
strcpy(,"stu2");
strcpy(e2.stuno,"100002");
e2.age=21;
e2.score=79;
La.ListInsert(2,e2);
strcpy(,"stu3");
strcpy(e3.stuno,"100003");
e3.age=19;
e3.score=87;
La.ListInsert(3,e3);
La.printlist(0);
cout<<"表La长:"<<La.ListLength()<<endl; cin.get();
Lb.init(&Lb);
strcpy(," stu12");
strcpy(e4.stuno,"100001");
e4.age=20;
e4.score=94;
Lb.ListInsert(1,e4);
strcpy(," stu13");
strcpy(e5.stuno,"100002");
e5.age=23;
e5.score=69;
Lb.ListInsert(2,e5);
strcpy(,"stu1");
strcpy(e6.stuno,"100001");
e6.age=22;
e6.score=88;
Lb.ListInsert(3,e6);
Lb.printlist(0);
cout<<"表Lb长:"<<Lb.ListLength()<<endl; cin.get();
cout<<"表La与Lb合并为表Lc:\n";
Lc.init(&Lc);
Lc.MergeList(&La,&Lb);
Lc.printlist(0);
cout<<"表Lc长:"<<Lc.ListLength()<<endl; cin.get();
cout<<"表La与Lb联合为表La:\n";
La.UnionList(&La,&Lb);
La.printlist(0);
cout<<"表La长:"<<La.ListLength()<<endl; cin.get();
k=Lc.ListDelete(-1,e);
if(k==0) cout<<"删除失败!\n";
else cout<<"删除成功!\n";
cout<<"输出表Lc:\n";
Lc.printlist(0);
cin.get();
strcpy(,"NoName");
La.PriorElem(e2,e);
if(strcmp(,"NoName")==0) cout<<"e2无前驱!\n"; else cout<<"e2的前驱="<<<<endl; strcpy(,"NoName");
La.NextElem(e3,e);
if(strcmp(,"NoName")==0) cout<<"e3无后继!\n"; else cout<<"e3的后继="<<<<endl;
cin.get();
cout<<"按成绩升序输出表Lc\n";
Lc.printlist(1);cin.get();
cout<<"按成绩降序输出表Lc\n";
Lc.printlist(-1);cin.get();
}
测试结果:
linelist2m.cpp运行结果:
首先调用插入函数.
姓名学号年龄成绩
stu1 100001 22 88
stu2 100002 21 79
stu3 100003 19 87
表La长:3
姓名学号年龄成绩
zmofun 100001 20 94
bobjin 100002 23 69
stu1 100001 22 88
表Lb长:3
表La与Lb合并为表Lc:
姓名学号年龄成绩
stu1 100001 22 88
stu2 100002 21 79
stu3 100003 19 87
zmofun 100001 20 94
bobjin 100002 23 69
stu1 100001 22 88
表Lc长:6
表La与Lb联合为表La:
姓名学号年龄成绩
stu1 100001 22 88
stu2 100002 21 79
stu3 100003 19 87 zmofun 100001 20 94 bobjin 100002 23 69 表La长:5
删除成功!
输出表Lc:
姓名学号年龄成绩
stu1 100001 22 88
stu2 100002 21 79
stu3 100003 19 87 zmofun 100001 20 94 bobjin 100002 23 69 e2的前驱=stu1
e3的后继=zmofun
按成绩升序输出表Lc
姓名学号年龄成绩bobjin 100002 23 69
stu2 100002 21 79
stu3 100003 19 87
stu1 100001 22 88 zmofun 100001 20 94 按成绩降序输出表Lc
姓名学号年龄成绩zmofun 100001 20 94
stu1 100001 22 88
stu3 100003 19 87
stu2 100002 21 79 bobjin 100002 23 69。