数据结构---抽象数据类型Triplet的表示和实现

抽象数据类型Triplet的表示和实现

**定义**
ADT ElemType{
	数据对象:D = { e1,e2,e3|e1,e2,e3∈Elemset(定义了关系运算的某个集合) }
	数据关系:R = {<e1,e2>,<e2,e3>}
}ADT ElemType

基本结构:

//------采用动态分配的顺序存储结构------//
typedef ElemType *Triplet; //由InitTriplet分配3个元素存储结构
//------基本操作的函数原型说明------//
Status InitTriplet (Triplet &T, ElemType v1, ElemType v2, ElemType v3);
//操作结果:构造三元组T,并为元素e1,e2,e3分别复赋参数v1,v2,v3的值
Status DestoryTriplet(Triplet &T);
//操作结果:三元组T被销毁
Status Get(Triplet &T,int i,ElemType &e);
//初始条件:三元组T已存在,1≤i≤3
//操作结果:用e返回三元组T中第i元的值
Status Put(Triplet &T,int i,ElemType &e);
//初始条件:
//操作结果:


//------基本操作的实现------//

Status InitTriplet (Triplet &T, ElemType v1, ElemType v2, ElemType v3){
	T=(ElemType )malloc(3*sizeof(ElemType));
	if(!T)
	exit(OVERFLOW);//分配存储空间失败
	T[0]=v1;
	T[1]=v2;
	T[2]=v3;
	return OK;
}

Status DestoryTriplet(Triplet &T){
	free(T);
	T=NULL;
	return OK; 
}

Status Get(Triplet T, int i, ElemType &e) {
	if(i<1||i>3)
		return ERROR;
	e=T[i-1];
	return OK;
}

抽象数据类型-复数Complex

ADT Complex{
	数据对象:D={r,i|r,i是实数} 
	数据关系:R={<r,i>|} 
	基本操作:
		InitComplex(&C,r,i)
			操作结果:构造一个复数C,实部为r,虚部为i 
		DestoryComplex(&C)
			操作结果:销毁复数C 
		Get(&C,k,&e)
			初始条件:C存在,且1<=k<=2; 
			操作结果 :用e返回C的第k元的值
		Set(&C,k,e)
			初始条件:C存在,且1<=k<=2;
			操作结果:将C的第k元的值设置或改变为e
		IsAscending(&C)
			初始条件:C存在
			操作结果:如果复数C的两个元素按照升序排列,则返回OK,否则返回ERROR
		IsDescending(&C)
			初始条件:C存在
			操作结果:降序?
		Max(&C,&e) 
			初始条件:C存在
			操作结果:用e返回复数C中最大的元素 
		Min(&C,&e)
		
		
}ADT Complex 

抽象数据类型:实数-RationalNumber

ADT RationalNumber{
数据对象:D = {s,m|s,m为有理数,且m不等于0} //分子,分母为实数且分母≠0
数据关系:R={<s,m>}
基本操作:
InitReationalNumber(&R,s,m)
操作结果:构造一个有理数,分子为s,分母为m

...... 

}

抽象数据类型:线性表


```css
ADT List{
	数据对象:D={ ai|ai∈ElemSet,i=1,2...n,n≥0 }
	数据关系:R={<ai-1,ai>|ai-1,ai∈D,i=1,2,...,n}
	基本操作:
		InitList(&L) 
			操作结果:构造一个空的线性表L
		DestoryList(&L)
			初始条件:线性表L已存在 
			操作结果:销毁线性表L
		ClearList(&L)
			初始条件:线性表L已存在
			操作结果:将L重置为空表
		ListEmpty(L)
			初始条件:线性表L已存在
			操作结果:若L为空表则返回TRUE,否则返回FALSE
		ListLength(L)
			初始条件:线性表L已存在 
			操作结果:返回L中数据元素个数 
		GetElem(L,i,&e)
			初始条件:线性表L已存在
			操作结果:用e返回L的第i个元素 
		LocateElem(L,e,compare())
			初始条件:线性表L已存在,compare()是数据元素判定函数 
			操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。若这样的数据元素不存在,则返回0 
		PriorElem(L,cur_e,&pre_e)
			初始条件:线性表L已存在
			操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱 ,否则操作失败,则返回0 
		NextElem(L,cur_e,&next_e)
			初始条件:线性表L已存在
			操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
		ListInsert(&L,i,e)
			初始条件:线性表L已存在,1<=i<=ListLength(L)+1 
			操作结果:在L中第i个位置之前插入新的属于元素e,L的长度+1
		ListDelete(&L,i,&e)
			初始条件:线性表L已存在且非空,1<=i<=ListLength (L)
			操作结果:删除线性表L的第i个数据元素,并用e返回其值,L长度-1
		ListTraverse(L,vist()) 
			初始条件:线性表L已存在 
			操作结果:依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败 
}ADT List 


归并应用
eg:已知两个线性表LA,LB,求A∪B 存放在LA中
方法:从线性表LB依次取数据元素,遍历LA,若LA中没有则插入。 

```css
算法如下:
//将所有在Lb中但不在La中的元素插入到La中
void union(List &La,list Lb){
	//求线性表长度 
	La_len=ListLength(La);
	Lb_len=ListLength(Lb);
	//在Lb中取元素
	for(i=1;i<=Lb_len;i++){
		GetElem(Lb,i,e);
		if(!LocateElem(La,e,equal))
			ListInsert(La,++La_len,e);
	} 
}//union 

线性表的动态分布顺序存储结构

#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量 
#define LISTINCRMENT 10 //线性表存储空间的分配增量 

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

//构造一个空的线性表 
Status InitList_Sq(&L){
	L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if(!L.elem)
		exit(OVERFLOW);
	L.length = 0;
	L.Listsize = LIST_INIT_SIZE;
	return OK; 
}
/*
注意:数组是从0开始的,第i个元素 就是elem[i-1] 
*/ 
//顺序表的插入操作
//在顺序表Sq的第i-1和i个位置中间插入元素e:需要将Sq的第i——n个元素后移 ,再将元素e插入到对应位置 
//可在表头、表中、表尾插入元素 
Status ListInsert_Sq(SqList &L,int i,ElemType e){
	if(i<1||i>L.length+1) 
		return ERROR;
	if(L.length >= L.listsize){//存储空间已满,需要增加分配 (一般只会等于,不会大于) 
		newbase = (ElemType *)realloc(L.elem,(LIST_INIT_SIZE + LISTINCREMENT)*sizeof(ElemType));
		if(!newbase)
			exit(OVERFLOW);
		L.elem = newbase;
		L.listsize += LISTINCREMENT;//增加容量后的大小 
	}
	q = &(L.elem[i-1]);//q为插入位置
	for(p=&(L.elem[L.length-1]), p>=q;--p)//元素后移 
		*(p+1) = *p;
	*p=e;//插入e 
	++L.length;//表长+1 
	return OK;
} 
//顺序表的删除操作
//取出对应位置元素赋值给e,元素前移,表长-1 
Status ListDelet_Sq(SqList &L,int i,ElemType &e) {
	if(i<1||i>L.length)
		return ERROR;
	p = &(L.elem[i-1]);
	e=*p;//取出第i个元素 
	q = L.elem+L.length-1;//表尾元素位置 
	for(p;p<q;p++)//该元素之后的元素往前移
		*p = *(p+1);
	--L.listsize;//表长-1 
	return OK;
}

归并线性表

**归并线性表**
//线性表La和Lb中的数据元素按值非递减有序排列,合并La和Lb到Lc中,使得Lc中的数据元素也是非递减有序排列 
void MergeList(List La,List Lb,List &Lc){
	InitList(Lc);
	i=j=1;
	k=0;
	La_len=ListLength(La);
	Lb_List=ListLength(Lb);
	while(i<=La_len&&j<=Lb_len){
		GetElem(La,i,a);
		GetElem(Lb,j,b);
		if(a<=b)
			ListInsert(Lc,++k,a);
		else
			ListInsert(Lc,++k,b);
	} 
	while(i<=La_len)
		ListInsert(Lc,++k,a);
	while(j<=Lb_len)	
		ListInsert(Lc,++k,b);
	
} //MergeList

归并顺序表

void MergeList_Sq(SqList La,SqList Lb,SqList &Lc){
	pa = La.elem;
	pb = Lb.elem;
	Lc.listsize = Lc.length = La.length + Lb.length;
	pc = Lc.elem = (ElemType*)malloc(Lc.listsize*sizeof(ElemType));
	if(!Lc.elem)
		exit(OVERFLOW);//存储失败
	pa_last = La.elem + La.length - 1;//pa最后一个元素地址 
	pb_last = Lb.elem + Lb.length -1;//pb最后一个元素地址
	
	while(pa<=pa_last&&pb<=pb_last){
		if(*pa<=*pb){
			pc=pa;
			pc++;
			pa++
		}//*pc++ = *pa++;
		else{
			pc=pb;
			pc++;
			pb++;
		}//*pc++ = *pb++;
	} 
//插入剩余元素 
	while(pa<pa_last)
		*pc++ = *pa++;
	while(pb<pb_last)
		*pc++ = *pb++;
} 

**归并单链表 **

//La,Lb,Lc都为有头结点的单链表 
用//pa,pb指向当前待插入的节点,pc指向最后一个节点
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
	pa = La->next;//第1个节点 
	pb = Lb->next;
	Lc = pc = La;//用La的头结点作为Lc的头结点 
	
	while(pa&&pb){
		if(pa->data<=pb->data){
			pc->next = pa;
			pc=pa;
			pa=pa->next;
		}
		else{
			pc->next = pb;
			pc=pb;
			pb=pb->next;
		}
	} 
	
	pc->next = pa?pa:pb;//插入剩余段
	free(Lb);//释放Lb的头结点 

线性表的链式存储结构

//线性链表/单链表
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode, *LinkList; 

//L为带头结点的单链表的头指针 
Status GetElem_L(LinkList L,int i,ElemType &e){
	p = L->next;//头结点
	j = 1;
	while(p&&j<i){//顺着指针向后查找,直到p指向第i个元素,或者p为空 
		p = p->next;
		j++;
	} 
	if(!p || j>i) 
		return ERROR;
	e = p->data;//取第i个元素 
	return OK;
} 

//L是带头结点的链表的指针,以e返回链表的第i个元素 
Status GetElem_L(LinkList L,int i,ElemType &e){
	p = L->next;//p指向第1个节点 
	j = 1;
	while(p&&j<i){
		p=p->next;
		j++;
	}
	if(!p || j>i)
		return ERROR;//第i个元素不存在
	e = p->data;
	return OK; 
}


//将单链表重置为一个空表 
void ClearList(&L){
	while(L->next){
		p=L->next;//p指向L的第1个节点 
		L->next = p->next;//删除p节点(也就是删除第1个结点)
		free(p); 
	} 
}


//单链表的插入操作
//在带头结点的单链线性表L的第 i个位置插入元素e:只需要修改指针 
Status ListInsert_L(LinkList &L,int i,ElemType e){
	p = L;
	j = 0;
	while(p&&j<i-1){//寻找第i-1个节点 -->p
		p = p->next;
		++j; 
	}
	if(!p || j>i-1) //i>表长或者小于1
		return ERROR;
	newNode = (LinkList)malloc(sizeof(LNode));//生成新节点
	newNode->data = e;
	newNode->next = p->next; 
	p->next = newNode;//修改指针,插入结点 
	return OK; 
} 


//单链表的删除指定位置节点的操作
//删除带头结点的单链线性表L的第i个节点 
Status ListDelete_L(LinkList &L,int i,ElemType &e){
	p = L;//p指向头结点
	j = 0;
	while(p->next && j<i-1){
		p=p->next;
		j++;
	} 
	//跳出循环时,p指向第j个节点,j=i-1 
	if(!p||j>i-1)//删除位置不合理 
		return ERROR;
	q=p->next;
	e=q->data;//将要删除的节点数据赋值给e 
	p->next = p->next->next;//删除结点 
	free(q);//释放结点 
	return OK; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luck*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值