1、假设在长度大于1的单循环链表中,既无头结点也无头指针。s为指向某个结点的指针,试编写算法删除结点*s的直接前驱结点。
2、已知由单链表表示的线性表中,含有三类字符的数据元素(如:字母、数字和其它字符),设计算法构造三个以循环链表示的线性表,使每一个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的空间。(头结点可以另辟空间)
3、有一双链表,每个结点中除有prior、data和next域外,还有一访问频度域freq,在链表被启用前,其值均初始化为零。每当在链表上进行一次LOCATE(L,x)运算,元素值为x的结点中freq域的值增1,并使此链表中结点保持按freq递减的顺序排列,以便使频繁访问的结点总是靠近表头。设计满足上述要求的LOCATE算法。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct CList//循环链表结构体
{
char data;
struct CList* next;
} Clist,*Clinklist;
int initList(Clinklist &L)//初始化循环链表
{
L=new Clist;
L->next=NULL;
return 1;
}
void create(Clinklist &L,int num)
{
Clinklist r=L,p;
char x;
cout<<"请输入值:(按回车结束输入)"<<endl;
while(cin>>x)//尾插法建立链表
{
p=new Clist;
p->data=x;
r->next=p;
r=p;
if(cin.peek()=='\n') break;
}
if(num==2)//创建单链表
{
r->next=NULL;
}
else//创建循环链表
{
r->next=L->next;//没有首元结点
L=L->next;//返回头结点
}
}
void print(Clinklist &L)
{
Clinklist r=L;
if(r->next)
do
{
cout<<r->data<<" ";
r=r->next;
}
while(r!=L);
cout<<endl;
}
void delete_s(Clinklist &L)
{
Clinklist p,s,q;
s=L;
char x;
cout<<"请输入要删结点的后继:";
cin>>x;
while(s->data!=x) s=s->next;
p=s;//找到要删结点的后继
while(p->next->next!=s)
p=p->next;
if(p->next==L)
L=L->next;
q=p->next;
p->next=s;
delete q;
}
void text1()
{
Clinklist L;
initList(L);
cout<<"建立单循环链表"<<endl;
create(L,1);
delete_s(L);
print(L);
}
void text2()
{
Clinklist L,A,B,C,pa,pb,pc,p,q;
int a_A=0;int b_B=0;int c_C=0;
initList(L);
initList(A);
initList(B);
initList(C);
pa=A;
pb=B;
pc=C;
cout<<"请建立一个含字符的单链表"<<endl;
create(L,2);//建立单链表;
cout<<"分类后"<<endl;
p=L->next;
while(p)
{
if(p->data>=48&&p->data<=59)
{
q=p;
p=p->next;
q->next=NULL;
pa->next=q;
pa=pa->next;
a_A=1;
}
else if((p->data>=65&&p->data<=90)||(p->data>=97&&p->data<=122))
{
q=p;
p=p->next;
q->next=NULL;
pb->next=q;
pb=pb->next;
b_B=1;
}
else
{
q=p;
p=p->next;
q->next=NULL;
pc->next=q;
pc=pc->next;
c_C=1;
}
}
if(a_A) {
pa->next=A->next; A=A->next;
cout<<"数字有:"<<endl;
print(A);
}
if(b_B) {
pb->next=B->next; B=B->next;
cout<<"字母有:"<<endl;
print(B);
}
if(c_C) {
pc->next=C->next;C=C->next;
cout<<"其他字符有:"<<endl;
print(C);
}
}
//双向链表
typedef struct BList
{
int num;
struct BList* prior,*next;
int freq;
}Blist,*Blinklist;
void initBlist(Blinklist &B)
{
B=new Blist;
B->prior=B->next=B;
}
void Bprint(Blinklist &B)
{
Blinklist p=B->next;
while(p!=B)
{
cout<<p->num<<" "<<p->freq<<endl;
p=p->next;
}
cout<<endl;
}
void Bcreate(Blinklist &B)
{
int x;
Blinklist p,q=B;
cout<<"请输入数据(按回车键结束)"<<endl;
while(cin>>x)//尾插法
{
p=new Blist;
p->num=x;
p->freq=0;
q->next=p;
p->prior=q;
p->next=B;
B->prior=p;
q=q->next;
if(cin.peek()=='\n')
break;
}
Bprint(B);
}
void locate(Blinklist &B,int x)
{
Blinklist p=B->next;
bool flag=1;
while(p!=B)
{
if(p->num==x){
p->freq++;
cout<<"访问成功!"<<endl;
flag=0;
break;
}
p=p->next;
}
if(flag){
cout<<"我的天,你难道不知道没有这个数字!"<<endl;
return;
}
p->prior->next=p->next;
p->next->prior=p->prior;
//排序
Blinklist q=B->next;
while(q!=B&&q->freq>p->freq) q=q->next;
p->prior=q->prior;
q->prior->next=p;
p->next=q;
q->prior=p;
Bprint(B);
}
void text3()
{
Blinklist B;
initBlist(B);
Bcreate(B);
int x;
while(1){
cout<<"请输入要访问的数(输入0回到主菜单)"<<endl;
cin>>x;
if(x==0) break;
locate(B,x);
}
}
void menu()
{
int n;
while(1)
{
cout<<"\n\n\t\t _____________________________________"<<endl;
cout<<"\t\t$ $"<<endl;
cout<<"\t\t$ 菜单栏 $"<<endl;
cout<<"\t\t$_____________________________________$"<<endl;
cout<<"\t\t$ $"<<endl;
cout<<"\t\t$________① 【删除前驱】___________$"<<endl;
cout<<"\t\t$________② 【字符分类】___________$"<<endl;
cout<<"\t\t$________③ 【访问额度】___________$"<<endl;
cout<<"\t\t$________④ 【 退出 】___________$"<<endl;
cout<<"\t\t$_____________________________________$"<<endl;
cout<<"\t\t$注释:请根据您的需求输入序号 $"<<endl;
cout<<"\t\t$_____________________________________$"<<endl;
cin>>n;
switch(n)
{
case 1:text1();
break;
case 2:text2();
break;
case 3:text3();
break;
case 0:exit(0);
}
}
}
int main()
{
menu();
return 0;
}