给定一个单链表和一个整数k,要求每隔k个元素翻转链表一次
struct node{
int key;struct node* next;
};
typedef node* List;
实现函数:List kReverse(List head,int k)
比如:原始链表为:1—>2—>3—>4—>5—>6
k=2 翻转为:2—>1—>4—>3—>6—>5
k=3 翻转为:3—>2—>1—>6—>5—>4
k=4 翻转为:4—>3—>2—>1—>5—>6
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* next;
}node, *List;
List kReverse(List head,int k)
{
List oldHead = NULL;
List newHead = NULL;//链表翻转完之后的第一个节点
List previousGroupTail = NULL;
int n = 0;
int num = 0;
int count = 1;
int reverseNum;
//链表为空或链表中只有一个元素,则不需要翻转
if (head == NULL || head->next == NULL)
return head;
oldHead = head;
//链表长度
while (head != NULL)
{
head = head->next;
n++;
}
reverseNum = n / k;//需要翻转的链表的个数
newHead = head = oldhead;
while (head != NULL && num < reverseNum)
{
List groupTail = head;//groupTail记录分组内的头结点,即为翻转后分组内的尾节点
List prev = NULL;
List next = NULL;
int i;
//翻转具有k个元素的链表分组,每循环一次后,pre指向翻转前分组内最后一个节点,head指向下一个分组的第一个节点
for (i = 1; i <= k && head != NULL; i++)
{
next = head->next;
head->next = prev;
prev = head;
head = next;
}
//newHead指向第一个分组翻转之后的第一个节点
if (count == 1)
{
newHead = prev;
count++;
}
if(previousGroupTail != NULL)
{
previousGroupTail->next = prev;
}
previousGroupTail = groupTail;
num++;
}
//处理最后的不组K个的元素节点,此时head指向剩下的元素的第一个节点
if (head != NULL)
{
if (previousGroupTail != NULL)
{
previousGroupTail->next = head;
}
}
return newHead;
}
void push(List* head_ref, int new_data)
{
List new_node = (List) malloc(sizeof(node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
int main()
{
List head = NULL;
List head1 = NULL;
push(&head, 8);
push(&head, 7);
push(&head, 6);
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
head1 = kReverse(head, 3);
printf("翻转后:");
while (head1 != NULL)
{
printf("%d ",head1->data);
head1 = head1->next;
}
printf("\n");
return 0;
}
方法2:
ListNode *reverseKGroup(ListNode *head, int k)
{
if (head == nullptr || head->next == nullptr || k < 2)
{
return head;
}
ListNode *next_group = head;
for (int i = 0; i < k; ++i)
{
if (next_group)
{
next_group = next_group->next;
}
else
{
return head;
}
}
// next_group is the head of next group
// new_next_group is the new head of next group after reversion
ListNode *new_next_group = reverseKGroup(next_group, k);
ListNode *prev = NULL, *cur = head;
while (cur != next_group)
{
ListNode *next = cur->next;
cur->next = prev ? prev : new_next_group;
prev = cur;
cur = next;
}
return prev; // prev will be the new head of this group
}