c++试题(1)

递归的本质就是栈!!!

一、用递归方式、非递归方式写函数将一个字符串反转

非递归:

char* reverse(char *str){  
    if(str != NULL){  
        int length=strlen(str);  
        int i;  
        char temp;  
        //中间即停止,len=1的情况直接返回,奇数的情况中间不动
        for(i=0;i<length/2;i++){  
            temp=str[i];  
            //尾=len-1-i
            str[i] = str[length-1-i];  
            str[length-1-i] = temp;  
        }  
    }  
    return str;  
}  

递归:由外向里递归执行
将A和I交换,此时变成 IBCDEFGHA,此时递归的字符串应该变成其子串“BCDEFGH”

void reverse(char* p, int N){ 
{
    if(p != NULL && N != 0){
        if (N == 1)
            return;
        else
        {
            char ch = p[0];
            p[0] = p[N-1];
            p[N - 1] = ch;
            reverse(p+1, N - 2);
        }
    }
}
二、用递归方式、非递归方式写函数将链表反转

递归:
可以反序输出链表,不改变结构

void oppdisplay(node* head){  
    if(head==NULL || head->next==NULL) 
        return head;  
    else{  
        oppdisplay(head->next); 
        //从后往前输出 
        printf("%d ",head->data);  
    }  
}  

也可以递归反转

void Inversion_Recursion(ListNode* p,ListNode* Head)  
{  
    if(p->next==NULL)  
    {  
        Head->next=p;  
        return;//找到最后一个节点作为头结点的后继  
    }  
    Inversion_Recursion(p->next,Head);  
    //从后往前开始反转
    p->next->next=p;//反转节点  
    p->next=NULL;//第一个节点反转后其后继应该为NULL  
}  

非递归:

ListNode* ReverseList(ListNode *pHead){
    ListNode *pReverseHead = NULL;
    ListNode *pNode = NULL;
    ListNode *pPre = NULL;
    while(pNode != NULL){
       ListNode *pNext = pNode->next;
       if(pNext == NULL)
           pReverseHead = pNode;
       pNode->next = pPre;
       pPre = pNode;
       pNode = pNext;
    }
    return pReverseHead;
}

另一种解法
http://blog.csdn.net/kangroger/article/details/20237081

三、未知长度的单链表,快速找到中间节点的位置

依然是常用的双指针技巧

node* find_middle(node *head){  
    node *v,*v2;  
    if(!head){  
        return NULL;  
    }  
    v2=v=head;  
    while(v2->next && v2->next->next){  
        v=v->next;  
        v2=v2->next->next;  
    }  
    return v;  
}  
四、单向链表的倒数第n个节点
node* lastnode(node* head,int n){  
    int i;  
    if(head==NULL || head->next==NULL) return head;
    node *p=head;  
    node *res=head;  
    for(i=0; i<n; i++){  
        if(p->next!= NULL)  
            p=p->next;  
        else 
            return NULL;  
    }  
    while(p){  
        p=p->next;  
        res=res->next;  
    }  
    return res;  
}  
五、判断链表是否循环

依然使用双指针,一个每次移动一格,一个移动两格,若有循环一定会在某处相遇

bool isloop(node *head){  
    node* v,*v2;  
    v=v2=head;  
    //处理特殊输入
    if(!head){  
        return NULL;  
    }  
    if(head->next){  
        v2=head->next;  
    }else{  
        return false;  
    }  
    //移动
    while(v2->next && v2->next->next){  
        v=v->next;  
        v2=v2->next->next; 
        if(v==v2)  
            return true;  
        else  
            return false;    
    }  
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值