【整理自用】单链表问题(一)

单链表LeetCode上的定义:struct ListNode 单链表的结构体{ int val; 节点值 ListNode *next; 节点下一个地址 ListNode(int x):val(x),next(NULL){}; 构造函数};从头到尾打印单链表思路: 1.由于递归相当于是堆栈结构,后进先...
摘要由CSDN通过智能技术生成

单链表

LeetCode上的定义:

struct ListNode 单链表的结构体
{  
        int val;    节点值
        ListNode *next; 节点下一个地址
        ListNode(int x):val(x),next(NULL){};    构造函数
};

从头到尾打印单链表

思路
1.由于递归相当于是堆栈结构,后进先出。因此可以考虑不停调用函数进行递归。递归结束的条件为IF(HEAD==NULL)。此时返回一次指针就指向单链表的最后一个元素上,开始执行打印操作即可;
2.对单链表进行遍历,将节点内的值存入堆栈中。
3.对单链表进行遍历,将节点内的值存入VECTOR中,利用STL的REVERSE()函数对VECTOR容器进行反转;
4.参见1.3单链表就地反转。
代码1

vector<int> vec;
vector<int> printListFromTailToHead(ListNode* head) 
{
        if(head==NULL)
        return vec;
        vec=printListFromTailToHead(head->next);
        vec.push_back(head->val);       
        return vec;
}

代码2

vector<int> vec;
vector<int> printListFromTailToHead(ListNode* head)
{
    if(head==NULL)
        return vec;
    while(head)
    {
       vec.push_back(head->val);
       head=head->next;
    }
     reverse(vec.begin(),vec.end());
     return vec;
}

找到单链表中点(倒数第N个点)

思路
这种题目可以从数组角度去考虑,但是这样就意味着需要先搜索一般得到单链表的长度,再利用类似数组的方式去搜索某个特定位置的数,时间复杂度较高。对于这种搜索特定位置的题目,可以依靠两个指针(快慢指针)来进行。此时则最多仅需遍历一次单链表。

寻找单链表中点:设置两个指针(快慢指针),快指针每次走两步,慢指针每次走一步。当快指针走到头时,慢指针刚好在中点的位置。(这里是偶数个时中点选择靠右边的那个)

代码段:

ListNode* findMidNode(ListNode* head)  
{  
       ListNode *slow, *fast;  
       slow = head;  
       fast = head;  
       while (fast && fast->next)  
       {  
              slow = slow->next;  
              fast = fast->next->next;  
       }
      return slow;  
}

寻找单链表倒数第N个点:设置快慢指针,快指针先走N步,然后一起出发速度相同。当快指针走到头时,慢指针刚好在倒数第N个位置。

代码段

ListNode* findMidNode(ListNode* head)  
{  
       ListNode *slow, *fast;  
       slow = head;  
       fast = head; 
       for(int i=1;i<N;++i)
       { 
            if (fast->next!=NULL)
            {   
                throw new Exception("单链表元素个数小于 "+n+" !");
            }
            fast = fast->next;
       }
       while (fast->next)  
       {  
            slow = slow->next;  
            fast = fast->next;  
       }
       return slow;  
}

单链表原地反转

即不改变节点内部值和不增加额外链表就地实现整张链表的反转,其辅助空间复杂度为O(1)。

思路
头插法:包含有头结点!!逆置链表初始为空,表中节点从原链表中依次“删除”,再逐个插入逆置链表的表头(即“头插”到逆置链表中),使它成为逆置链表的“新”的第一个结点,如此循环,直至原链表为空。
单链表反转

代码:

void  converse (ListNode *head)
{  
    ListNode *p,*q;
    if(head==NULL||head->next==NULL) //如果头结点后没有元素或者仅有一个元素,则无需反转。 
        return
    p=head->next; 
    head->next=NULL;
    while(p) 
    { 
        /*向后挪动一个位置*/ 
        q=p;
        p=p->next;  
        /*头插*/
        q->next=head->next;
        head->next<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值