设计实现locate运算函数。设有一个带头节点的双向链表L,每个节点有4个数据成员:prior,next,data,freq。每进行一次locate操作,preq加1,并将该节点前移,保持频率是递减关系的。
bool locate(LinkList List, int x)
{
LinkList Head = List;
//找元素
LinkList p_target = findData(List, x);
if (p_target == NULL)return false;
p_target->freq++;
//移动
if (p_target->prior == Head)return false;//如果找到的这个数据是最前面的那个数据,或者这张表只有这一个数据。因为这个表本身就是递减序列,所以最前头不移动
if (p_target->prior->freq >= p_target->freq)return false;//如果数据前面的频率大于等于目标的频率,则表保持递减,不移动
//当且仅当目标节点不是开始节点,并且频率大于前面的频率时,才移动。
LinkList now = p_target->prior;//目标节点的前一个节点
while (now != Head)//在头节点处结束
{
if (p_target->freq > now->freq)//目标节点的频率大于当前节点
{
now = now->prior;
}
else
{
break;
}
}
//断开操作!!!!末尾操作不一样!!!
p_target->prior->next = p_target->next;
if(p_target->next)p_target->next->prior = p_target->prior;
//经过循环操作后。如果频率为最大值,那么now==head,否则now等于大于等于它的那一位的地址,其插入操作都相同。
p_target->prior = now;
p_target->next = now->next;
now->next->prior = p_target;
now->next = p_target;
return true;
}
LinkList findData(LinkList List, int data)
{
List = List->next;//指向开始节点
while (List)
{
if (List->data == data)
{
return List;
}
List = List->next;
}
return NULL;
}
顺便复习了下一些双链表的基本操作
建立双链表:
void createList(LinkList *List, int data[], int length)
{
//建立头结点
LinkList s = (LinkList)malloc(sizeof(Node));
s->freq = -1;
s->data = -1;
s->prior = NULL;
s->next = NULL;
*List = s;
//基本的定义
LinkList head = s;
LinkList now = s;
//开始插入
for (int i = 0; i < length; i++)
{
//基本赋值
s = (LinkList)malloc(sizeof(Node));
s->freq = 0;
s->data=data[i];
//连接前端
s->prior = now;
now->next = s;
//移动指针
now = now->next;
}
now->next = NULL;
}
正向遍历,反向遍历:
void show_go(LinkList List)
{
List = List->next;
cout << "正向:";
while (List)
{
cout << List->data << " ";
List=List->next;
}
cout << endl;
}
void show_back(LinkList List)
{
LinkList head = List;
//处理空链表
if (List->next == NULL)return;
//走到表尾
while (List->next != NULL)
{
List = List->next;
}
//回来
cout << "反向:";
while (List)
{
if (List == head)break;
cout << List->data << " ";
List = List->prior;
}
cout << endl;
}