数据结构5.6+5.7

设有一头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred(前驱指针)、data(数据)和next(后继指针)域外,还有一个访问频度域freq。在链表被起用前,其值均初始化为零。每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点的最后,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

typedef struct DNode{
	int data,freq=0;
	struct DNode *next,*prior;
}DNode,*DLinkList;

DLinkList Locate(DLinkList &L,ElemType x){
	DNode *p=L->next,*pre;
	while(p!=NULL&&p->data!=x){    //找到x节点
		p=p->next;
	}
	if(p==NULL) exit(0);
	else{
		p->freq++;
		if(p->next!=NULL) p->next->prior=p->prior;    //摘出p节点
		p->prior->next=p->next;
		pre=p->prior;
		while(pre!=L&&pre->freq<=p->freq){    //找到第一个频度大于p节点频度的节点
			pre=pre->prior;
		}
		p->next=pre->next;    //插入p节点
		p->next->prior=p;
		pre->next=p;
		p->prior=p;
	}
	return p;
}

 

typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList;//单链表 
typedef struct DNode{
	int data;
	struct DNode *next,*prior;
}DNode,*DLinkList;//双链表
 
//将两个升序链表结合成一个降序链表,头插法。 
void MergeSort(LinkList &L1,LinkList &L2){
	LNode *p=L1->next,*q=L2->next,*r;
	L1->next=NULL;
	while(p!=NULL&&q!=NULL){
		if(p->data<q->data){
			r=p->next;
			p->next=L1->next;
			L1->next=p;
			p=r;
		}
		else{
			r=q->next;
			q->next=L1->next;
			L1->next=q;
			p=r;
		}
	}
	if(p) q=p;
	while(q!=NULL){
		r=q->next;
		q->next=L1->next;
		L1->next=q;
		q=r;
	}
	free(L2);
} 

//将两个有序链表的公共元素结合成一个链表,要求不破坏原有链表结构。
LinkList Get_Common(LinkList A,LinkList B){
	LNode *p=A->next,*q=B->next,*r;
	LinkList C=(LinkList)malloc(sizeof(LNode));
	r=C;
	while(p!=NULL&&q!=NULL){
		if(p->data<q->data){
			p=p->next;
		}
		else if(p->data>q->data){
			q=q->next;
		}
		else{
			s=(LNode*)malloc(sizeof(LNode));
			s->data=p->data;	//尾插 
			r->next=s;
			r=s;
			p=p->next;
			q=q->next;		
		}
		r->next=NULL;
	}
}

//判断一个带头双链表是否对称。 
int Symmetry(DLinkList L){
	DNode *p=L->next,*q=L->prior;
	while(p!=q){	//循环结束退出是链长为奇数的情况 
		if(p.data==q.data){
			if(p->next==q)	//链长为偶数的情况 
			return 1;
			else{
				p=p->next;
				q=q->prior;
			}
		}
		else return 0; 
	}
	return 1;
} 

//将两个循环单链表头指针为L1和L2,将L2连接到L1之后,仍然保持循环链表形式。
LinkList LinkList(LinkList &L1,LinkList &L2) {
	LNode *p=L1,*q=L2;
	while(p->next!=L1){
		p=p->next;
	}
	while(q->next!=L2){
		q=q->next;
	}
	p->next=L2;
	q->next=L1;
	return L1;
}

//重复删除一个带头结点的链表中节点值最小的节点并输出其节点值,直到链表为空。
void Del_Min(LinkList &L){
	LNode *p,*minp,*pre,*minpre;
	while(L->next!=L){	//循环链表判空条件 
		p=minp=L->next;
		pre=minpre=L;
		while(p!=L){
			if(p->data<minp->data){
				minp=p;
				minpre=pre;
			}
			pre=p;
			p=p->next;
		}
		printf(minp->data);
		minpre->next=minp->next;
		free(minp);
	}
	free(L);
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值