您的位置:首页 > 其它

每K个元素翻转一次链表,若最后剩余元素不足K个,不进行翻转(美团2014校招试题)

2013-09-11 15:52 591 查看
给定一个单链表和一个整数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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: