关于链表的递归操作

不带头结点链表翻转

思路: 假设有1,2,3,4,5,6,这样6个数构成一个链表,要进行翻转操作,结果应为6,5,4,3,2,1,

假设要翻转1 ,那就要先翻转2,,要翻转2,就要翻转3,直到要翻转6,就是当剩下一个元素或者链表为空时作为结束条件

假设2,3,4,5,6,已经翻转,此时结果为1,6,5,4,3,2,可见,我们只需将1移到2后面就行了,还可以看到1一直是指向2的,所以找到2的位置并不难。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef struct linklist
{
    int data;
    struct linklist *next;
}node;
node *create()
{
    node *head=NULL,*q,*p;
    int x;
    scanf("%d",&x);
    while(x!=0)
    {
        q=(node*)malloc(sizeof(node));
        q->data=x;
        if(!head)
            head=p=q;
        else
            p->next=q,p=p->next;
        scanf("%d",&x);
    }
    p->next=NULL;
    return head;
}
node *create_head()
{
    node *head,*q,*p;
    int x;
    head=(node*)malloc(sizeof(node));
    p=head;
    scanf("%d",&x);
    while(x!=0)
    {
        q=(node*)malloc(sizeof(node));
        q->data=x;
        p->next=q;
        p=p->next;
        scanf("%d",&x);
    }
    p->next=NULL;
    return head;
}
void display(node *head)
{
    node *p=head;
    if(!head)
    {
       printf("error!\n");
       return;
    }
    while(p)
    {
        printf("%-5d",p->data);
        p=p->next;
    }
    printf("\n");
}
void display_head(node *head)
{
    node *p=head->next;
    if(!p)
    {
        printf("error!\n");
        return ;
    }
    while(p)
    {
        printf("%-5d",p->data);
        p=p->next;
    }
    printf("\n");
}
void display2(node* head)//递归逆序输出链表的值
{
    if(head==NULL) return ;
    display2(head->next);
    printf("%-5d",head->data);
}
node *rever(node *head)//不带头结点的链表翻转
{
    if(head==NULL||head->next==NULL) return head;//空表或者只剩一个节点,直接返回
    node *newhead = rever(head->next);//要翻转第一个,首先要翻转后面那些,把后面的看成一个整体
    head->next->next=head;//假设后面的部分已经翻转完成,则要翻转点的后继要指向翻转点
    head->next=NULL;//翻转后这个点指向为空
    return newhead;
}
void rever_head(node *head,node *h)//带头结点的链表翻转
{
    if(h==NULL||h->next==NULL)//若链表为空或者只有一个元素
    {
        head->next=h;//将头结点指向这个元素
        return ;
    }
    rever_head(head,h->next);
    h->next->next=h;
    h->next=NULL;
}
node *delallx(node *head,int x)
{
    node *p=head,*pre=NULL;
    if(!head) return head;
    while(p&&p->data!=x) pre=p,p=p->next;//找到第一个等于x的节点
    if(p)
    {
        if(!pre) //若为头结点,继续找,返回第一个不为x点的地址
           head=delallx(head->next,x);
        else
           pre->next=delallx(p->next,x);
        free(p);
    }
    return head;
}
void delallx_head(node *head,int x)//删除带头接节点链表的所有x
{
    node *p=head->next,*pre=head;
    if(p==NULL) return;
    while(p&&p->data!=x) pre=p,p=p->next;
    if(p) pre=delallx(p->next,x),free(p);
}
int main()
{
    node *head;
   // head=create_head();
   // display_head(head);
    //rever_head(head,head->next);
    //display_head(head);
    //delallx(head,4);
    //display_head(head);
    head=create();
    display2(head);
    printf("\n");
    display(head);
    /*head=rever(head);
    display(head);
    head=delallx(head,3);
    display(head);*/
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值