您的位置:首页 > 理论基础 > 数据结构算法

数据结构作业-5

2011-03-22 18:40 281 查看
题目:试设计一个实现下述要求的Locate运算的函数。设有一个带头结点的双向链表L,每个结点有4个数据成员:指向前驱结点的指针prior、指向后继结点的指针next、存放数据的成员data和访问频度freg。所有结点的freg初始都为0。每当在链表上进行一次Locate(L,x)操作时,令元素值为x的结点的访问频度freg加1,并将该结点前移,链接到与它的访问频度相等的结点后面,使得链表中所有结点保持按访问频度递减的顺序排列,以使频繁访问的结点总是靠近表头。

1.需求分析
假设双向连表中没有元素值重复的节点。
用户输入链表中的元素,然后访问元素。
程序计算每个元素所在节点被访问的此时,并按此排序,输出给用户。
 
2.概要设计
节点定义

    Node*
prior;//指向前一个节点的指针

    Node*
next;//只想后一个节点的指针

    DataType
data;//数据域
   
int freq;//访问频度
   
链表定义
   
    Node*
head;//头结点
        

总体流程为:
 

 

 



3.详细设计
创建双向链表:
 



关键函数和代码:

int
locate(dnodetype*
head,DatType
x)

{

    dnodetype *p=head;//p是目标点,它de阈值为x。调整的也是它

    while(p!=NULL &&
x!=p->data)

    {

       p=p->next;

    }

    if (p==NULL)

    {

       return 0;//未找到

    }

    p->freq++;//频度加

    dnodetype *q=p->prior;//向左找。q是指针,p指向的节点需要前挪

    while(q!=head &&
q->freq<p->freq)

    {

       p->prior=q->prior;

       p->prior->next=p;

       q->next=p->next;

       if (q->next!=NULL)

       {

           q->next->prior=q;

       }

       p->next=q;

       q->prior=p;

       q=p->prior;

    }

    return 1;
}
 
4.调试分析
链表的元素以0开始,出现异常。
只能处理int型和char型。
 
5.使用说明
   
运行程序,按照提示。
 
6.测试结果
单位数整数:

建立双向连表,元素类型为int,以0结束输入,不能以0开始

输入第1个节点值:1

输入第2个节点值:2

输入第3个节点值:3

输入第4个节点值:4

输入第5个节点值:5

输入第6个节点值:6

输入第7个节点值:7

输入第8个节点值:0

链表创建完毕

 

输入要访问的值:9

未找到x节点

 

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:3
,访问频度=0

元素值为:4
,访问频度=0

元素值为:5
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:5

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:5
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:3
,访问频度=0

元素值为:4
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:3

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:5
,访问频度=1

元素值为:3
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:4
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:3

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:4
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:4

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:4
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:4

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:3
,访问频度=2

元素值为:4
,访问频度=2

元素值为:5
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:4

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:4
,访问频度=3

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:

4

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:4
,访问频度=4

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:1
,访问频度=0

元素值为:2
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:2

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:4
,访问频度=4

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:2
,访问频度=1

元素值为:1
,访问频度=0

元素值为:6
,访问频度=0

元素值为:7
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:7

链表重排后从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:4
,访问频度=4

元素值为:3
,访问频度=2

元素值为:5
,访问频度=1

元素值为:2
,访问频度=1

元素值为:7
,访问频度=1

元素值为:1
,访问频度=0

元素值为:6
,访问频度=0

 

继续查找吗?(1继续,其他退出)

多位数整数:

建立双向连表,元素类型为int,以0结束输入,不能以0开始

输入第1个节点值:632

输入第2个节点值:753

输入第3个节点值:693

输入第4个节点值:419

输入第5个节点值:355

输入第6个节点值:810

输入第7个节点值:478

输入第8个节点值:0

链表创建完毕

 

输入要访问的值:466

未找到x节点!! 
排序也没有发生变化

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:419

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:419
,访问频度=1

元素值为:632
,访问频度=0

元素值为:753
,访问频度=0

元素值为:693
,访问频度=0

元素值为:355
,访问频度=0

元素值为:810
,访问频度=0

元素值为:478
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:419

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:419
,访问频度=2

元素值为:632
,访问频度=0

元素值为:753
,访问频度=0

元素值为:693
,访问频度=0

元素值为:355
,访问频度=0

元素值为:810
,访问频度=0

元素值为:478
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:753

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:419
,访问频度=2

元素值为:753
,访问频度=1

元素值为:632
,访问频度=0

元素值为:693
,访问频度=0

元素值为:355
,访问频度=0

元素值为:810
,访问频度=0

元素值为:478
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:478

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:-1
,访问频度=0

元素值为:419
,访问频度=2

元素值为:753
,访问频度=1

元素值为:478
,访问频度=1

元素值为:632
,访问频度=0

元素值为:693
,访问频度=0

元素值为:355
,访问频度=0

元素值为:810
,访问频度=0

 

继续查找吗?(1继续,其他退出)

Char型

建立双向连表,元素类型为char,以#结束输入,不能以#开始

输入第1个节点值:q

输入第2个节点值:w

输入第3个节点值:g

输入第4个节点值:l

输入第5个节点值:;

输入第6个节点值:#

链表创建完毕

 

输入要访问的值:r

未找到x节点!! 
排序也没有发生变化

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:l

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:
,访问频度=0

元素值为:l
,访问频度=1

元素值为:q
,访问频度=0

元素值为:w
,访问频度=0

元素值为:g
,访问频度=0

元素值为:;
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:W

未找到x节点!! 
排序也没有发生变化

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:;

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:
,访问频度=0

元素值为:l
,访问频度=1

元素值为:;
,访问频度=1

元素值为:q
,访问频度=0

元素值为:w
,访问频度=0

元素值为:g
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:;

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:
,访问频度=0

元素值为:;
,访问频度=2

元素值为:l
,访问频度=1

元素值为:q
,访问频度=0

元素值为:w
,访问频度=0

元素值为:g
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:w

找到了,链表重排后

从左往右,双向链表的元素为:

元素值为:
,访问频度=0

元素值为:;
,访问频度=2

元素值为:l
,访问频度=1

元素值为:w
,访问频度=1

元素值为:q
,访问频度=0

元素值为:g
,访问频度=0

 

继续查找吗?(1继续,其他退出)1

 

输入要访问的值:W

未找到x节点!! 
排序也没有发生变化

 

继续查找吗?(1继续,其他退出)

 
 
7.附录
源程序文件清单。
// 第题.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <malloc.h>
using namespace std;
//typedef int DatType;
typedef char DatType;
typedef struct linknode
{
DatType data;
int freq;
struct linknode *prior,*next;
}dnodetype;
//创建一个双向连表,用户输入节点的data域值,输入结束
dnodetype *create()
{
DatType d;
dnodetype *head=NULL,*s,*t;
int i=1;
//如果开始符和结束符一样,那么就是无头链表了,不符合本题的意思
//	cout<<"建立双向连表,元素类型为int,以结束输入,不能以开始"<<endl;
cout<<"建立双向连表,元素类型为char,以#结束输入,不能以#开始"<<endl;
while(1)
{
cout<<"输入第"<<i<<"个节点值:";
cin>>d;
//		if (d==0)
if (d=='#')
{
break;
}
if (i==1)
{
head=(dnodetype*)malloc(sizeof(dnodetype));
head->data=d;
head->prior=NULL;
head->next=NULL;
t=head;
}
else
{
s=(dnodetype*)malloc(sizeof(dnodetype));
s->data=d;
s->next=NULL;
t->next=s;
s->prior=t;
t=s;
}
i++;
}
return head;
}
//输出所有节点的data域值
void show(dnodetype *head)
{
dnodetype *p=head;
cout<<"从左往右,双向链表的元素为:"<<endl;
if (p==NULL)
{
cout<<"空表"<<endl;
}
while(p!=NULL)
{
cout<<"元素值为:"<<p->data<<" ,访问频度="<<p->freq<<endl;
p=p->next;
}
cout<<endl;
}
//令元素值为x的结点的访问频度freg加
//调整node,使得链表中的节点按照访问频度,降序排列
int locate2(dnodetype* head,DatType x)
{
dnodetype *p=head;//p是目标点,它de阈值为x。调整的也是它
while(p!=NULL && x!=p->data)
{
p=p->next;
}
if (p==NULL)
{
return 0;//未找到
}
p->freq++;//频度加
dnodetype *q=p->prior;//向左找。q是指针,p指向的节点需要前挪
while(q!=head && q->freq<p->freq)
{
p->prior=q->prior;
p->prior->next=p;
q->next=p->next;
if (q->next!=NULL)
{
q->next->prior=q;
}
p->next=q;
q->prior=p;
q=p->prior;
}
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
dnodetype *head,*p,*s;
DatType x;
int ans;
head=create();
s=(dnodetype* )malloc(sizeof(dnodetype));
s->data=-1;//哨兵
s->prior=NULL;
s->next=head;
head->prior=s;
head=s;
p=head;
while(p!=NULL)
{
p->freq=0;
p=p->next;
}
cout<<"链表创建完毕"<<endl;
//	disp(head);
while(1)
{
cout<<endl<<"输入要访问的值:";
cin>>x;
if (locate2(head,x)==0)
{
cout<<"未找到x节点!! 排序也没有发生变化"<<endl<<endl;
}
else
{
cout<<"找到了,"<<"链表重排后"<<endl;
show(head);
}
cout<<"继续查找吗?(1继续,其他退出)";
cin>>ans;
if (ans!=1)
{
break;
}
}
return 0;
}


 

 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息