单链表

来源:互联网 发布:昭通市2017旅游数据 编辑:程序博客网 时间:2024/06/15 20:54

********************************************

实验二:单链表的基本操作

 

编写一个完整的程序,实现单链表的建立、插入、删除、输出等基本操作。

1)建立一个带头结点的单链表。

2)计算单链表的长度,然后输出单链表。

3)查找值为x的直接前驱结点q

4)删除值为x的结点。

5)把单向链表中元素逆置(不允许申请新的结点空间)。

6)已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意:minkmaxk是给定的两个参变量,他们的值可以和表中的元素相同,也可以不同)。

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;
}

 

原创粉丝点击