C实现 LeetCode->Merge Two Sorted Lists (双指针大法)(单链表swap合并反转)



Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

   给定一个链表,每两个相邻节点交换并返回它的头。

   

   你的算法应该只使用固定的空间。你可能不修改列表中的值,只有节点本身可以改变。


        题目要求不能改变链表的值,所以只能通过调整指针来达到目的。




//
//  SwapNodesinPairs.c
//  Algorithms
//
//  Created by TTc on 15/6/19.
//  Copyright (c) 2015年 TTc. All rights reserved.
//
/**
 *  Swap Nodes in Pairs 
 Given a linked list, swap every two adjacent nodes and return its head.
 For example, Given 1->2->3->4, you should return the list as 2->1->4->3.
 Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed
 
   给定一个链表,每两个相邻节点交换并返回它的头。
   
   你的算法应该只使用固定的空间。你可能不修改列表中的值,只有节点本身可以改变。

 题目要求不能改变链表的值,所以只能通过调整指针来达到目的。
 */
#include "SwapNodesinPairs.h"

#include "List.h"
#include <string.h>
#include <stdlib.h>


struct ListNode {
    int val;
    struct ListNode *next;
};

/**
 *  双指针大法
 *
 */
struct ListNode*
swapPairs(struct ListNode* head) {
    
    if(head == NULL || head->next == NULL) return head;
    
    struct ListNode *curr = head->next;
    struct ListNode *prev = head;
    struct ListNode *prevParent = NULL;
    
    while(curr != NULL){
        
        prev->next = curr->next;
        curr->next = prev;
        
        struct ListNode *tmp = curr;
        
        curr = prev;
        prev = tmp;
        
        if(prevParent) prevParent->next = prev;
        else head = prev;
        
        curr = curr->next;
        prev = prev->next;
        if(prevParent) prevParent = prevParent->next;
        else prevParent = head;
        
        if(curr) curr = curr->next;
        else break;
        
        prev = prev->next;
        prevParent = prevParent->next;
    }
    
    return head;
}

/**
 *   双指针大法
 *
 */
ListElmt*
tt_swapPairs(ListElmt* head) {
    if(head == NULL || head->next == NULL) return head;
    
    ListElmt *curr = head->next;
    ListElmt *prev = head;
    ListElmt *prevParent = NULL;
    
    while(curr != NULL){
        
        prev->next = curr->next;
        curr->next = prev;
        //swap node 交换节点
        ListElmt *tmp = curr;
        curr = prev;
        prev = tmp;
        
        //重新设置头节点 headnode
        if(prevParent) prevParent->next = prev;
        else head = prev;
        
        curr = curr->next;
        
        prev = prev->next;
        if(prevParent) prevParent = prevParent->next;
        else prevParent = head;
        
        if(curr) curr = curr->next;
        else break;
        
        prev = prev->next;
        prevParent = prevParent->next;
    }
    return head;
}

/**
 *  双指针大法
 *
 */
ListElmt*
tt01_swapPairs(ListElmt* head) {
    if(head == NULL || head->next == NULL) return head;
    
    ListElmt *curr = head->next;
    ListElmt *prev = head;
   //重新设置 头节点 headnode
    head = curr;
    //根据当前节点遍历
    while (curr) {
        
        ListElmt *next = curr->next;//获取当前节点的  下一位置的 节点元素
        curr->next = prev; //将当前节点的 next指针  指向 当前节点的前一个元素
        
        //判断next节点 以及next节点的 next指针指向的 节点 是否存在,有一个不存在则返回head
        if(next == NULL || next->next == NULL){
            prev->next = next;
            return head;
        }
        //交换元素 ,为了下一次继续遍历
        prev->next = next->next;
        prev = next;
        curr = prev->next;
    }
    return head;
}

void
test_swapPairs(){
    List l1;
    list_init(&l1, free);
    int *data ;
    int array[15] = {100,200,300,4000,5000,600,700,800,900,100000};
    for (int i = 0; i< 10; i++) {
        if ((data = (int *)malloc(sizeof(int))) == NULL)
            return ;
        *data = array[i];
        if (list_ins_next(&l1, NULL, data) != 0)  //逐个插入元素
            return;
    }
    print_list(&l1);

    ListElmt *result = tt01_swapPairs(list_head(&l1));
    printf("result->val===%d\n",*(int *)result->data);

    print_listNode(result);

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值