day1--反转无头链表

反转链表

day1--反转无头链表_第1张图片

day1--反转无头链表_第2张图片

一、迭代翻转

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
#include 
class Solution {
  public:
    ListNode* ReverseList(ListNode* pHead) {
		if(pHead==NULL||pHead->next==NULL) return pHead;//若为空链表返回
		ListNode *beg, *mid, *end;
		beg=NULL, mid = pHead, end = pHead->next;
		while(1){
			mid->next=beg;//令mid指向与beg相同
			if(end==NULL)break;//判断此时end是否为null
			//不为null,则整体向后移动三个指针
			beg=mid;
			mid=end;
			end=end->next;
		}
		pHead=mid;//只改变表头,结束
		return pHead;
    }
};

二、递归反转

该方法更适用于反转无头结点的链表

class Solution {
  public:
    ListNode* ReverseList(ListNode* pHead) {
		if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
		ListNode *new_head = ReverseList(pHead->next);//new_head一直指向最后一个节点
		//每跳出一层递归,pHead前移一个,且需改变head->next的指向,同时令head指向NULL。
		pHead->next->next=pHead;
		pHead->next=NULL;
		return new_head;
    }
};

三、头插法反转

class Solution {
  public:
    ListNode* ReverseList(ListNode* pHead) {
		if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
		ListNode *new_head = NULL;//新建链表
		ListNode *tmp;
		while (pHead!=NULL) {
			tmp=pHead;
			pHead=pHead->next;//pHead后移
			tmp->next=new_head;//将tmp插入新链表头部
			new_head=tmp;//n_h指向新插入的元素
		}
		return new_head;
    }
};

四、就地逆置

与头插法的区别是,头插法是建立了一个新的链表,就地法在原链表改变。

class Solution {
  public:
    ListNode* ReverseList(ListNode* pHead) {
		if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
		ListNode *beg=pHead;
		ListNode *end=pHead->next;
		while(end!=NULL){
			beg->next=end->next;//将end移出链表
			end->next=pHead;//end指向表头
			pHead=end;//新表头指向end
			end=beg->next;//end后移到下个要反转的节点
		}
		return pHead;
    }
};

参考: 单链表反转详解(4种算法实现) (biancheng.net)

你可能感兴趣的:(数据结构机试复习打卡,链表,数据结构)