链表后半部分反转(2016亚信实习生笔试题)

Posted 阳安子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表后半部分反转(2016亚信实习生笔试题)相关的知识,希望对你有一定的参考价值。

题目(2016亚信实习生笔试题):
将链表后半部分反转,编写功能函数。函数头类似于本代码中reList()。
只记得一个大概了,具体规则在代码注释中提到了。

#define NULL 0
#include <stdio.h>
typedef struct LNode

    char value;
    struct LNode *next;
LNode;

int initLi(LNode **head)//头插法

    LNode *th=*head;
    char c=getchar();
    while(c!='$')
    
        if(c!=' ')
        
             LNode *temp=malloc(sizeof(LNode));
            if(temp)
            
                temp->value=c;
                temp->next=th;
                th=temp;
            
            else
            
                free(temp);
                return -1;
            
        
        c=getchar();
    
    *head=th;
    return 0;


void visit(LNode **head)

    LNode *th=*head;
    for(LNode *p=th;p!=NULL;p=p->next)
    
        printf("%c->",p->value);
    
    printf("NULL\\n");


/*
*regular
*1 2 3 4 5--1 2 5 4 3
*1 2 3 4-- 1 2 4 3
*/
LNode* reList(LNode *List)

    int n=0;
    for(LNode *p=List;p!=NULL;p=p->next)
    
        ++n;
    
    if(n%2)
    
        n=(n+1)/2;//奇数个情况,如果有5个,则从第3个开始。
    
    else
    
        n/=2+1;//偶数个情况,如果有4个,则从第3个开始。
    
    LNode *reHead,*flag;
    int i=0;
    for(LNode *p=List;p!=NULL;p=p->next)
    
        ++i;
        if(i==n-1)
        
            flag=p;
        
        else if(i==n)
        
            reHead=(LNode *)malloc(sizeof(LNode));
            reHead->next=NULL;
            reHead->value=p->value;
        
        else if(i>n)
        
            LNode *temp=(LNode *)malloc(sizeof(LNode));
            temp->value=p->value;
            temp->next=reHead;
            reHead=temp;
        
    
    delLi(&(flag->next));
    flag->next=reHead;
    return List;


void delLi(LNode **head)


    LNode *th=*head;
    for(LNode *temp=th;temp!=NULL;)
    
        LNode *p=temp;
        temp=temp->next;
        free(p);
    
    *head=NULL;

int main()

    LNode *head=NULL;
    if(initLi(&head))
    
        printf("error\\n");
        return 0;
    
    printf("LinkedList\\n");
    visit(&head);
    head=reList(head);
    printf("LinkedList which has dealt\\n");
    visit(&head);
    delLi(&head);
    printf("hello world\\n");
    return 0;

结果图:

由于初始化用的头插法,所以创建时候倒序,并且加入了结束标志’$’。
下面是1 2 3 4

注:由于在笔试的时候这个题目半天没有调出来,很是气愤,所以就好好的折腾了一下,主要是实现功能函数,对于其余部分,随便加强了学习。水平有限,如果有更好的方法,可以随时交流。


2016.7.14更新


reList函数更改说明:之前的方法使用了额外的空间,现在进行修改,简洁化代码,减少空间复杂度。利用pre(初始化为空),cur指针进行链表指针修改。增加了空链表检查,结果测试正确。

/*
*regular
*1 2 3 4 5--1 2 5 4 3
*1 2 3 4-- 1 2 4 3
*/
LNode* reList(LNode *List)

    int n=0;
    for(LNode *p=List;p!=NULL;p=p->next)
    
        ++n;
    
    if(n==0)
    
        return List;
    
    else if(n%2)
    
        n=(n+1)/2;//奇数个情况,如果有5个,则从第3个开始。
    
    else
    
        n=n/2+1;//偶数个情况,如果有4个,则从第3个开始。
    
    LNode *flag,*pre=NULL,*cur=List,*nextNode;
    int i=0;
    while(cur!=NULL)
    
        ++i;
        nextNode=cur->next;
        if(i==n-1)
        
            flag=cur;
        
        else if(i>=n)
        
           cur->next=pre;
           pre=cur;
        
        cur=nextNode;
    
    flag->next=pre;
    return List;

以上是关于链表后半部分反转(2016亚信实习生笔试题)的主要内容,如果未能解决你的问题,请参考以下文章

笔试题集锦(编程题)

[11道链表经典笔试题]优化的算法思想:反转链表链表相交快慢指针

<转>网易2016实习生前端笔试题部分总结

(转载)c++笔试题汇总

程序员面试需要的C++笔试题汇总

数值游戏(360 2016实习生招聘笔试题)