单链表的基本操作

也就是一些关于单链表的基本操作,不多说上代码:

#include <stdio.h>
#include <stdlib.h>
struct node{
int res;
struct node *next;
};
struct node *Creat_link_list(int n){//用尾插法建立一个带有头结点的单链表
 struct node *head,*p,*q;
 int i;
 q=head=(struct node *)malloc(sizeof(struct node));
 for(i=1;i<=n;i++){
  p=(struct node *)malloc(sizeof(struct node));
  p->res=rand()%1000+1;
  q->next=p;
  q=p;
 }
 p->next=NULL;
 return head;
}
void Read_link_list(struct node *head){//遍历单链表并输出每个节点
	while(head->next){
	 printf("%d ",head->next->res);
	 head=head->next;
	}
	printf("\n");
}
struct node *Opposite_link_list(struct node *head){//倒置带有头结点的单链表,不开辟新内存
	struct node *Newhead,*tmp,*q;
    Newhead=NULL;
    q=head;//由于带有头结点需要额外的指针指向头结点(存放头结点)
    head=head->next;//首元结点
	while(head){
     tmp=head->next;
     head->next=Newhead;
     Newhead=head;
     head=tmp;
	}
	q->next=Newhead;
	Newhead=q;
  return Newhead;
}
struct node *Delete_even(struct node *head){//删除单链表中为偶数的全部节点
  struct node *q,*tmp;
   tmp=head;
  while(head->next){
   if(head->next->res%2==0)
   {
    q=head->next;
    head->next=q->next;//删除节点后,相当于后移了一个节点
    free(q);
   }
   else
    head=head->next;
  }
  return tmp;
}
struct node *Creat_up_list(int n){//创建一个递增的单链表
    struct node *head,*p,*tmp;
    int i;
    head=(struct node *)malloc(sizeof(struct node));
    head->next=NULL;
    for(i=1;i<=n;i++){
     if(i==1)
     {
      p=(struct node *)malloc(sizeof(struct node));
      p->res=rand()%1000+1;
       p->next=head->next;
       head->next=p;
     }
     else
     {
      p=(struct node *)malloc(sizeof(struct node));
      p->res=rand()%1000+1;
      tmp=head;
     while(tmp->next&&(tmp->next->res<=p->res)){//两个判断条件不能交换顺序
        tmp=tmp->next;
     }
      p->next=tmp->next;
      tmp->next=p;
     }
    }
  return head;
}
struct node *Merge_up_list(struct node *head_a,struct node *head_b){//将两个递增的单链表,合并成一个递增的单链表
   struct node *head_c,*la,*lb,*lc;
   lc=head_c=head_a;
   la=head_a->next;
   lb=head_b->next;
   while(la&&lb){
    if(la->res<=lb->res){
      lc->next=la;
      lc=la;
      la=la->next;
    }
    else{
     lc->next=lb;
     lc=lb;
     lb=lb->next;
    }
   }
   lc->next=la?la:lb;
    free(head_b);
  return head_c;
}
struct node *Merge_down_list(struct node *head_a,struct node *head_b){//合并两个递减的单链表,合并合并成一个递减的单链表
   struct node *head_c,*la,*lb,*lc;
   lc=head_c=head_a;
   la=head_a->next;
   lb=head_b->next;
   while(la&&lb){
    if(la->res>=lb->res){
      lc->next=la;
      lc=la;
      la=la->next;
    }
    else{
     lc->next=lb;
     lc=lb;
     lb=lb->next;
    }
   }
   lc->next=la?la:lb;
    free(head_b);
  return head_c;
}
struct node *Divide(struct node *head){//将一个单链表分解成两个链表,一个节点全为奇数,另一个全为偶数
    struct node *Newhead,*q,*p;
    q=Newhead=(struct node *)malloc(sizeof(struct node));
    while(head->next){
     if(head->next->res%2==0){
       p=head->next;
       head->next=p->next;
       q->next=p;
       q=p;
     }
     else
      head=head->next;
    }
    q->next=NULL;
  return Newhead;
}
int main(){
 struct node *p,*q,*t,*r,*s,*u,*tmp;
 printf("下列链表节点个数都以直接给出\n");
 printf("节点中的数由1000以内的随机数产生\n");


 printf("创建单链表并且遍历该链表然后逆置单链表并遍历输出,该单链表有10个节点\n");
 p=Creat_link_list(10);
 Read_link_list(p);
 q=Opposite_link_list(p);
 Read_link_list(q);

 printf("删除单链表中的偶数节点\n");
 t=Delete_even(p);
 Read_link_list(t);

 printf("建立两个非递减的单链表,节点数为9和15\n");
 r=Creat_up_list(9);
 Read_link_list(r);
 s=Creat_up_list(15);
 Read_link_list(s);

 printf("将两链表合并成非递减链表\n");
 u=Merge_up_list(r,s);
 Read_link_list(u);

 printf("建立两个非递减的单链表,节点数为11和17\n");
 r=Creat_up_list(11);
 Read_link_list(r);
 s=Creat_up_list(17);
 Read_link_list(s);


 printf("将两链表合并成非递增链表\n");
 r=Opposite_link_list(r);
 s=Opposite_link_list(s);
 u=Merge_down_list(r,s);
 Read_link_list(u);



 printf("将一个单链表分解成两个链表,一个节点全为奇数,另一个全为偶数,节点数为20\n");
 p=Creat_link_list(20);
 Read_link_list(p);
 tmp=Divide(p);
 printf("分解后的链表\n");
 Read_link_list(tmp);
 Read_link_list(p);
 return 0;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值