实现链表任意反转

前言:

在上一篇博客实现链表的创建后,我们对其创建的链表进行反转以及任意反转。

分析:

假设我们对链表每三个节点进行一次反转,有如下链表:

若对其反转,则我们想要的结果为:

思路:

我们可以用头插法的方式对其进行反转,头插法的方式:

一开始链表只有一个Head头节点,现加入节点1

如果此时加入加入节点2那么节点2的next信息为Head头的next信息,即2指向1,Head头的next信息更新为节点2的地址

以此类推,当加入节点4时,我们应该把4接在节点1的后面,这时就应该移动链表的插入位置,在开始时插入位置为头节点,加入节点4时插入位置为节点3,相当于

一个新的目标头节点。

若要实现简单的反转,直接按照头插法插入即可

实现代码:

Node *ReverseList(Node *head) {
    Node *L = NULL, *tmp = NULL, *newH = NULL;
    int count = 0;
    L = (Node *)malloc(sizeof(Node) );
    L -> next = NULL;
    newH = L;
    head = head -> next;
    while(head != NULL) {
        ++count;                              // 对节点进行计数,
        tmp = (Node *)malloc(sizeof(Node) );  //  头插法的实现
        tmp -> data = head -> data;           //
        tmp -> next = L -> next;              //
        L->next = tmp;                        //
        head = head->next;
        if(count%3==0) while(L->next!=NULL) L = L -> next; // 移动头节点
    }
    return newH;
}

完整代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <map>
#include <list>
#include <utility>
#include <set>
#include <algorithm>
#include <deque>
#include <vector>
#define mem(arr,num) memset(arr,0,sizeof(arr))
#define _for(i, a, b) for(int i = a; i <= b; i++)
#define __for(i, a, b) for(int i = a; i >=b; i--)
#define IO ios::sync_with_stdio(false);\
        cin.tie(0);        cout.tie(0);
using namespace std;
typedef long long ll;
typedef vector<int > vi;
const ll INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 5000 + 5;
typedef struct node {
    int data;
    struct node *next;
}Node;
Node *CreateList() {
    Node *L, *head, *tmp;
    int num;
    L = (Node *)malloc(sizeof(Node));
    L -> next = NULL;
    head = L;
    while(scanf("%d", &num) && num) {
        tmp = (Node *)malloc(sizeof(Node) );
        tmp -> data = num;
        tmp -> next = NULL;
        L -> next = tmp;
        L = tmp;
    }
    return head;
}
Node *ReverseList(Node *head) {
    Node *L = NULL, *tmp = NULL, *newH = NULL;
    int count = 0;
    L = (Node *)malloc(sizeof(Node) );
    L -> next = NULL;
    newH = L;
    head = head -> next;
    while(head != NULL) {
        ++count;                              // 对节点进行计数,
        tmp = (Node *)malloc(sizeof(Node) );  //  头插法的实现
        tmp -> data = head -> data;           //
        tmp -> next = L -> next;              //
        L->next = tmp;                        //
        head = head->next;
        if(count%3==0) while(L->next!=NULL) L = L -> next; // 移动头节点
    }
    return newH;
}
void ReadList(Node *head) {
    head = head -> next;
    while(head != NULL) {
        printf("%d\n",head -> data);
        head = head -> next;
    }
}
int main() {
    Node *head = CreateList();
    Node *newH = ReverseList(head);
    ReadList(newH);
    return 0;
}

原文地址:https://www.cnblogs.com/GHzz/p/9201806.html

时间: 2024-08-30 04:41:54

实现链表任意反转的相关文章

链表的反转思路及代码实现

Node* reverse_list(Node *head){ Node *cur=head; //链表的反转需要3个状态指针,分别是当前状态指针*cur,前一个状态指针*pre,后一个状态指针*post. //初始化时,当前状态指针从head出发,前一个状态没有,则定为NULL,后一个状态指针为当前状态的下一个cur-〉next: Node *pre = NULL; Node *post = cur->next; // Node *reverse_head = cur; while(post)

秒懂单链表及其反转(reverse)

什么是链表,这种数据结构是由一组Node组成的,这群Node一起表示了一个序列.链表是最普通,最简单的数据结构,它是实现其他数据结构如stack, queue等的基础. 链表比起数组来,更易于插入,删除. Node可以定义如下: typedef int element_type; typedef struct node *node_ptr; struct node { element_type element; node_ptr next; }; 另外关于要不要头节点这个问题,我建议加上头节点,

单链表的反转

如何把一个单链表进行反转? 方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转. 方法2:使用3个指针遍历单链表,逐个链接点交替使用指针改变链表的指向进行反转. 方法3:从第3个节点到第N-1个节点,依次逐节点插入到第1个节点(head节点)之后,再将第N个节点指向head(成环),然后将此时head的下一个节点设为head,最后将原head指向NULL. 方法4:   递归(没搞懂~) 方法2: ActList* ReverseList2(ActList* head) {   //Ac

26、输入一个链表,反转链表后,输出链表的所有元素。

输入一个链表,反转链表后,输出链表的所有元素. 思路:  ListNode next = null;//用来保存待反序的第一个节点(head 和 next节点) ListNode pre = null;//用来保存已经反序的第一个结点 next = head.next;//首先记录当前节点的下一个节点,(保存起来) //先用next保存head的下一个节点的信息,保证单链表不会因为失去head节点的原next节点而就此断裂 head.next = pre;//让当前节点指向前一个节点,因为要反序

单链表的反转问题

单链表的反转问题 单链表反转问题经常会遇到.在此记录一下,以便查阅方便. 如果反转一个有头结点的使用下面的方法比较合适. //反转单链表,此单链表带有头节点. //思想:使用tmp临时指针保存头结点与链表的关系 typedef struct ListNode  { int data; struct ListNode * next; }ListNode,*LinkList; void ReverseList(ListNode* Head) { ListNode *current,*tmp; cur

【链表】反转链表

输入一个链表,反转链表后,输出链表的所有元素. 1 /* 2 public class ListNode { 3 int val; 4 ListNode next = null; 5 6 ListNode(int val) { 7 this.val = val; 8 } 9 }*/ 10 public class Solution { 11 public ListNode ReverseList(ListNode head) { 12 13 if (null == head || null ==

用两种递归思路与循环实现单链表的反转

typedef struct ListNode{ int data; struct ListNode *next; }ListNode; //递归一 ListNode *ReverseList (ListNode *pHead, ListNode *nHead = NULL) { //每次取下第一个节点头插法创建新链表 //nHead为反转后链表的头节点 if(pHead == NULL) return NULL; ListNode *pNext = pHead -> next; pHead -

看图理解单链表的反转

如何把一个单链表进行反转? 方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转. 方法2:使用3个指针遍历单链表,逐个链接点进行反转. 方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾. 方法4:   递归(相信我们都熟悉的一点是,对于树的大部分问题,基本可以考虑用递归来解决.但是我们不太熟悉的一点是,对于单链表的一些问题,也可以使用递归.可以认为单链表是一颗永远只有左(右)子树的树,因此可以考虑用递归来解决.或者说,因为单

快慢指针和链表原地反转

1,制作环型链表 2.检測链表中是否存在环(參考文章) 3.计算链表中环的长度 4, 计算链表中环起始的位置 5,推断一个链表是否存在回文,要求O(n)时间和O(1)空间的复杂度(推断链表是否是回文,要求O(n)时间.O(1)空间) 6.计算链表中间位置 7,链表原地反转(链表原地反转) 8,測试code #include <iostream> using namespace std; /* @1: detect if there is a circule in a list -> de