********************************************
实验二:单链表的基本操作
编写一个完整的程序,实现单链表的建立、插入、删除、输出等基本操作。
(1)建立一个带头结点的单链表。
(2)计算单链表的长度,然后输出单链表。
(3)查找值为x的直接前驱结点q。
(4)删除值为x的结点。
(5)把单向链表中元素逆置(不允许申请新的结点空间)。
(6)已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,他们的值可以和表中的元素相同,也可以不同)。
(7)同(6)的条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法时间复杂度。
(8)利用(1)建立的链表,实现将其分解成两个链表,其中一个全部为奇数,另一个全部为偶数(尽量利用已知的存储空间)。
(9)在主函数中设计一个简单的菜单,分别测试上述算法。
*******************************************************************************
#include<stdio.h>
#include<iostream>
using namespace std;
typedef struct node{
int data;
struct node *next;
}link,*linklist;
linklist head,end;//头结点和为节点
linklist create()//1
{
linklist p;
p=(linklist)malloc(sizeof(node));
p->next=NULL;
return p;
}
void linkendcreate()//1尾插法建立链表
{
cout<<"请输入一个整数"<<endl;
linklist q;
int data;
q=create();
scanf("%d",&data);
q->data=data;
end->next=q;
end=end->next;
}
void linkprint()//2输出点链表
{
linklist p;
p=head->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
}
void linklength()//2计算长度
{
int count=0;
linklist p;
p=head->next;
while(p)
{
count++;
p=p->next;
}
cout<<"单链表的长度为:"<<count<<endl;
linkprint();//输出链表
}
void linkpre()//3查找值为x的直接前驱结点q
{
int x;
cout<<"请输入x: ";
scanf("%d",&x);
linklist p;
p=head->next;
if(p->data==x)
{
cout<<"x的前驱结点是head"<<endl;
return ;
}
while(p->next)
{
if(p->next->data==x)
{
cout<<"x的前驱结点的值是"<<p->data<<endl;
return ;
}
p=p->next;
}
}
void linkdelete()//4 删除值为x的结点
{
int x;
cout<<"请输入x:";
scanf("%d",&x);
linklist p,q;
p=head->next;
if(p==NULL)//判断链表是否为空
{
cout<<"该链表为空"<<endl;
return ;
}
if(p->data==x)//如果第一个结点为x
{
head->next=p->next;
free(p);
linklength();
return;
}
q=p;
p=p->next;
while(p)//本算法默认一定有x
{
if(p->data==x)
{
if(p->next==NULL)//判断是否是最后一个结点
{
end=q;//尾结点发生了变化
q->next=NULL;
free(p);
linklength();
return;
}
else
{
q=p->next;
free(p);
linklength();
return ;
}
}
q=p;
p=p->next;
}
}
void ReverseList()//5 把单向链表中元素逆置
{
if(head->next == NULL || head->next->next == NULL)
{
return ;
}
linklist t = NULL;
linklist p =head->next;
linklist q = head->next->next;
while(q != NULL)
{
t = q->next;
q->next = p;
p = q;
q = t;
}
head->next->next = NULL;
head->next = p;
linklength();
}
/*void link_k()//6已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素
{
int mink,maxk;
cout<<"请输入mink和maxk的值:";
cin>>mink>>maxk;
linklist p,q;
p=head->next;
while(p)//小于mank的元素
{
q=p;end=p;
if(p->data<mink)
{
head->next=p->next;
p=q->next;
free(q);
}
else
break;
}
while(p)//大于maxk的元素
{
if(p->next->data>maxk)
{
end=p;break;
}
p=p->next;
}
while(p)
{q=p;p=p->next;free(q);}
end->next=NULL;
linklength();
}*/
/* 删除大于x小于y的值*/
void delete_L()//6已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素
{
int mink,maxk;
cout<<"请输入mink和maxk的值:";
cin>>mink>>maxk;
linklist p,q;
p=head;
q=p;
p=p->next;
if(p==NULL) printf("ERROR:链表为空");
while(p!=NULL)
{
if((p->data >mink) && (p->data <maxk))
{ q->next=p->next;
free(p);
p=q->next;
}
else
{ q=p;
p=p->next;
}
}
linklength();
} /* delete_L */
void delete_same()//7同(6)的条件,试写一高效的算法,删除表中所有值相同的多余元素
{
linklist p,q;
p=head->next;
q=p;
p=p->next;
if(p==NULL) printf("ERROR:链表为空");
while(p->next!=NULL)
{
if(p->data==q->data)
{ q->next=p->next;
free(p);
p=q->next;
}
else
{
q=p;p=p->next;
}
}
linklength();
} /* delete_L */
void linkfen()
{
linklist head1,head2;
linklist p,q,r,t;
head1=create();
head2=create();
q=head1;
r=head2;
p=head->next;
while(p)
{
t=create();
if(p->data%2==1)
{
t->data=p->data;
q->next=t;
q=q->next;
}
else
{
//t=create();
t->data=p->data;
r->next=t;
r=r->next;
}
p=p->next;
}
q=NULL;
r=NULL;
cout<<"奇数链表为:"<<endl;
p=head1->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl<<"偶数链表为:"<<endl;
p=head2->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
}
void tip()
{
printf("***************菜单栏*****计科*陈东东**********\n");
printf("1 建立一个带头结点的单链表\n");
printf("2 计算单链表的长度,然后输出单链表\n");
printf("3 查找值为x的直接前驱结点q\n");
printf("4 删除值为x的结点\n");
printf("5 把单向链表中元素逆置\n");
printf("6 已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素\n");
printf("7 同(6)的条件,试写一高效的算法,删除表中所有值相同的多余元素\n");
printf("8 利用(1)建立的链表,实现将其分解成两个链表,其中一个全部为奇数另一个全部为偶数(尽量利用已知的存储空间)\n");
printf("0 退出程序\n");
printf("请输入你的选择:");
}
int main()
{
head=create();
end=create();
end=head;
int k;
tip();
while(scanf("%d",&k),k)
{
switch(k)
{
case 1:linkendcreate();
cout<<"操作完毕"<<endl;
tip();
break;
case 2:linklength();
cout<<"操作完毕"<<endl;
tip();
break;
case 3:linkpre();
cout<<"操作完毕"<<endl;
tip();
break;
case 4:linkdelete();
cout<<"操作完毕"<<endl;
tip();
break;
case 5:ReverseList();
cout<<"操作完毕"<<endl;
tip();
break;
case 6:delete_L();
cout<<"操作完毕"<<endl;
tip();
break;
case 7:delete_same();
cout<<"操作完毕"<<endl;
tip();
break;
case 8:linkfen();
cout<<"操作完毕"<<endl;
tip();
break;
}
}
return 0;
}