剑指offer-链表

单向链表的结构定义

typedef int DataType; 
struct ListNode
{
    DataType value;
    ListNode *next;
}

问题1、往链表的末尾添加一个结点

//给定头结点,往末尾插入一个结点
void InsertNode(ListNode **head,DataType key){
    ListNode *q=new ListNode;
    q->next=NULL;
    q->value=key;
    if(*head==NULL){
        *head=q;
        return ;
    }   
    ListNode *p=*head;
    while(p->next!=NULL){
        p=p->next;
    }
    p->next=q;
}

问题2、找到第一个含有某值的结点并删除该结点

void DeletNode(ListNode **head, DataType key){
    ListNode *p = *head;
    ListNode *q = NULL;
    ListNode *pre = NULL;
    if ((*head)->value == key){
        *head = (*head)->next;
        delete p;
        return ;
    }
    while (p->next){
        pre = p;
        if (p->next->value == key)
        {
            q = p->next;
            break;
        }
        p=p->next;
    }
    cout<<q->value<<endl;
    pre->next = q->next;
    delete q;
}

问题3、从尾到头打印链表

void  ReversePrint(ListNode *head){
    if (head->next !=NULL){
        ReversePrint(head->next);
    }
    cout<<"<-"<<head->value;
}

问题4、找到链表中的倒数第k个结点

//找到倒数第k个结点
ListNode* FindLastKNode(ListNode *head, int k){
    if (head==NULL||k==0)   return NULL;   
    ListNode *p1=head;
    int i=0;
    while (i<k-1&&p1!=NULL)
    {
        p1=p1->next;
        i++;
    }
    if (i!=k-1)
            return NULL;
    ListNode *p2=head;
    while (p1->next)
    {
        p1=p1->next;
        p2=p2->next;
    }
    return p2;
}

问题5、反转链表

//非递归实现
ListNode  *ReveseNode(ListNode *head){
    ListNode *p=head;
    ListNode *pre=NULL;
    while(p){
        ListNode  *q=p->next;
        p->next=pre;
        pre=p;
        p=q;
    }
    return pre;
}

//递归实现
ListNode *ReverseNode (ListNode *oldHead,ListNode *newHead){
    ListNode *next=oldHead->next;
    oldHead->next= newHead;
    newHead=oldHead;
    if(next==NULL)     return newHead;
    else
        return Reverse(next,newHead);
}

问题6、复杂链表的深度复制
这里写图片描述

//1.先复制一个指针next并将对应的结点保存在map中,之后遍历mp指针连接对应的mp
//map保存A-A',B-B'.......
map<ListNode*,ListNode*>     NodeMap;
ListNode * CopyList(ListNode *head)
{
    if(head==NULL)    return NULL;
    ListNode *newHeat=new ListNode;
    root->next=NULL;
    root->mp=NULL;
    root->data=head->data;
    NodeMap.insert(pair<ListNode*,ListNode*>(head,newHead));
    ListNode *p1=head->next;
    ListNode *p2=newHead;
    while(p1){
        ListNode *q=new ListNode;
        q->next=NULL;
        q->mp=NULL;
        q->data=p->data;
        p2->next=q;
        p2=p2->next;
        NodeMap.insert(pair<ListNode*,ListNode*>(p1,p2));
        p1=p1->next;
    }
    return root;
}
void CompleteList(ListNode *root,ListNode *head){
    ListNode *p1=head;
    while(p1){
        if(p1->mp){
            NodeMap[p1]->mp=NodeMap[p1->mp];
        }
        p1=p1->next;
    }
}


//2.剑指offer给出的方案:将原来链表扩大一倍,A->A’->B->B'->C->C'->D->D'->E->E',然后进行操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值