单链表的逆转:(头尾互换)

单链表的逆转:(头尾互换)
 1 迭代反转(适用于反转不带头节点的链表)

    从当前链表的首元节点开始,一直遍历到链表的最后一个节点,这期间逐个改变所遍历到的节点的指针域,另其指向前一个节点。
    方法是借用三个指针,
    首先三个指针 begin mid end
    分别指向 null  第一个节点 第二个节点
    然后遍历就是各向后移动一个节点,直至mid指向链表中最后一个节点(此时end 为null)。

代码:head为无头节点链表的头指针
    link * iteration_reserve (link * head){

    	if(head == null || head->next == null ){
    	 return head;
    	}
    	else{

    	link * begin = null;
    	link*  mid = head;
    	link* end = head->next;

    	// 遍历
    	while(1){

    		mid->next = begin;
    		if(end == null){
    			break;
    		}
    		begin = mid ;
    		mid = end;
    		end = end->next;
    	}
    		// 最后修改head头指针的指向
    		head = mid ;

    		return head;
    	}

2 递归反转链

    和迭代反转法相反
    实现思想是从链表的尾节点开始
    依次向前遍历
    遍历过程依次改变各节点的指向,即令其指向前一个节点

link * recursive_reverse(link *head)
	{
		if(head == NULL || 
			head->next == NULL)
		{
			return head;
		}// 递归的出口,空链或只有一个结点,直接返回头指针
		else
		{
			//一直递归 找到链表中最后一个节点
			link * new_head = recursive_reverse(head->next);

			//当逐层退出时,new_head 的指向都不变,一直指向原链表中最后一个节点;
 			//递归每退出一层,函数中 head 指针的指向都会发生改变,都指向上一个节点。
			//每退出一层,都需要改变 head->next 节点指针域的指向,同时令 head 所指节点的指针域为 NULL。

			head->next->next = head;
			head->next = NULL;
			return new_head;

		}
	}

3 头插法 反转链表

是指在原有链表基础上,依次将位于链表头部的节点摘下,然后采用从头部插入的方式生成一个新链表,则此链表即为原链表的反转版。

link * head_reverse(link*head)
		{
			link * new_head = NULL;
			link * temp = NULL;
			if(head == NULL ||
				head->next == NULL )
			{
				return head;
			}

			while(head != NULL)
			{
				temp = head;
				//将temp从head中摘除
				head = head->next;

				//将temp插入到new_head的头部
				temp->next = new_head;
				new_head = temp;
			}
			return new_head;
		}

4 就地逆置法 反转链表

 和头插法的实现思想类似 ,唯一区别在于,头插法是通过建立一个新链表实现的,而就地逆置法则是直接对原链表做修改,从而实现将原链表反转。

      在原链表的基础上做修改,需要额外借助2个指针(假设分别为beg end)

link * local_reverse(link * head)
	  {
	  	link * begin = NULL;
	  	link * end = NULL;
	  	if(head == NULL ||
	  	 head->next == NULL )
	  	 {
	  	 	return head;
	  	 }

	  	 begin = head;
	  	 end = head->next;

	  	 while(end != NULL )
	  	 {
	  	 	//将 end 从链表中摘除
	  	 	begin->next = end->next;

	  	 	//将 end 移动至链表头
	  	 	end->next = head;
	  	 	head = end;

	  	 	//调整 end 的指向,另其指向 beg 后的一个节点,为反转下一个节点做准备
	  	 	end = begin->next;
	  	 }

	  	 return head;

	  }

上述代码仅仅以 无头节点的链表为例

      对于有头节点的链表反转:
      迭代反转法:
          初始状态忽略头节点(直接将 mid 指向首元节点),仅需在最后一步将头节点的 next 改为和 mid 同向即可;
      头插法或者就地逆置:
          仅需将要插入的节点插入到头节点和首元节点之间即可;

     递归法并不适用反转有头结点的链表(但并非不能实现),该方法更适用于反转无头结点的链表。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值