王道数据结构第42页第20题

题目要求:
在这里插入图片描述

我在一开始的代码实现:

#include<stdio.h>
#include<stdlib.h>

#define ElemType int
typedef struct DNode{
	ElemType data;
	int freq;
	struct DNode* pred;
	struct DNode* next;
}DNode,*DinkList;

//先用尾插法构造非循环双链表:
DinkList List_TailInsert(DinkList &L)
{
	int x;
	L=(DinkList)malloc(sizeof(DNode));
    L->next=NULL;
    L->pred=NULL;
	DNode *s,*r=L;
	scanf("%d",&x);
	while(x!=9999)
	{
		s=(DNode*)malloc(sizeof(DNode));
		s->data=x;
		s->freq=0;
		s->next=r->next;
		s->pred=r;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
}

//本题的的解答: 
void BubbleSort(DinkList &L,ElemType x)
{
	DNode *p,*q=NULL;
	int f,d;
	while(1)
	{
		if(L->next==q)return;
		for(p=L->next;p->next!=q;p=p->next)
		{
			if(p->freq<=p->next->freq)
			{
				if(p->next->data==x)
				{
				  d=p->data;
				  p->data=p->next->data;
				  p->next->data=d;
			    }
				f=p->freq;
				p->freq=p->next->freq;
				p->next->freq=f;
			}
		}
		q=p;
	}
	return;
}

DNode* Locate(DinkList &L,ElemType x)
{
	DNode *p=L->next;
	while(p!=NULL)
	{
		if(p->data==x)
		{
			p->freq++;
			break;
		}
		p=p->next;
	}
	BubbleSort(L,x); //经过改进的链表冒泡排序,要考虑到最后一次访问的值 
	return p;
}
//.............................................. 

void ShowList(DinkList L)
{
    printf("\n输出处理之后的链表:\n");
    DNode* p=L->next;
    while(p!=NULL)
    {
    	printf("%d ",p->data);
    	p=p->next;
	}
	printf("\n");
	return;
} 

int main()
{
	DinkList L;
	int x;
	
	printf("构造非循环双向链表L:\n");
    L=List_TailInsert(L);
    printf("现在开始随机访问各个节点:\n\n");
    while(1)
	{
		printf("输入想要访问的元素:\n");
	    scanf("%d",&x);
	    if(x==9999)
	    {
	       printf("\n访问结束!\n");
	       break;
	    }
		DNode *p=Locate(L,x);
		if(p!=NULL)
		   if(p->data==x)printf("\n查询正确\n");
		ShowList(L);	
	}
	return 0;
}

能够运行,但问题是这代码实在太长了,看了王道的视频之后再写一次:

#include<stdio.h>
#include<stdlib.h>

#define ElemType int
typedef struct DNode{
	ElemType data;
	int freq;
	struct DNode* pred;
	struct DNode* next;
}DNode,*DinkList;

//先用尾插法构造非循环双链表:
DinkList List_TailInsert(DinkList &L)
{
	int x;
	L=(DinkList)malloc(sizeof(DNode));
    L->next=NULL;
    L->pred=NULL;
	DNode *s,*r=L;
	scanf("%d",&x);
	while(x!=9999)
	{
		s=(DNode*)malloc(sizeof(DNode));
		s->data=x;
		s->freq=0;
		s->next=r->next;
		s->pred=r;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
}

//本题的的解答: 
DNode* Locate(DinkList &L,ElemType x)
{
    DNode *p=L->next,*q;
	while(p&&p->data!=x)p=p->next;
	 
	if(!p)
	{
	   printf("\n不存在值为%d的节点!\n",x);
	   return NULL;
	}
	else{
	   p->freq++;
	   if(p->next!=NULL)
	   {
	   	  p->next->pred=p->pred;
	   }
	   p->pred->next=p->next;
	   q=p->pred;
	   while(q!=L&&q->freq<=p->freq)q=q->pred;
	   p->next=q->next;
	   q->next->pred=p;
	   p->pred=q;
	   q->next=p;
	}
	return p;
}
//.............................................. 

void ShowList(DinkList L)
{
    printf("\n输出处理之后的链表:\n");
    DNode* p=L->next;
    while(p!=NULL)
    {
    	printf("%d ",p->data);
    	p=p->next;
	}
	printf("\n");
	return;
} 

int main()
{
	DinkList L;
	int x;
	
	printf("构造非循环双向链表L:\n");
    L=List_TailInsert(L);
    printf("现在开始随机访问各个节点:\n\n");
    while(1)
	{
		printf("输入想要访问的元素:\n");
	    scanf("%d",&x);
	    if(x==9999)
	    {
	       printf("\n访问结束!\n");
	       break;
	    }
		DNode *p=Locate(L,x);
		if(p!=NULL)
		   if(p->data==x)printf("\n查询正确\n");
		ShowList(L);	
	}
	return 0;
}

不过这代码里有个小bug。在执行p->next->pred=p->pred;这一句操作的时候,如果p是最后一个节点,不做判断就直接执行这个操作就会导致段错误,当然对考试应该没啥影响,但如果是做开发,还是防着点吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值