说明:转载请注明出处http://blog.csdn.net/yuanwei1314/article/details/40740027
题目:
给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5,用程序实现。
思路:
在网上也看过很多写法,要么感觉稍显复杂,要么对于不足的没有处理。这里实现的方式都统一处理,不区分以上情况。按照顺序表翻转方式,只考虑局部翻转,然后将翻转后的链表添加到尾结点即可。
#include <stdio.h>
#include <stdlib.h>
typedef int elem;
typedef struct node
{
elem data;
struct node *next;
}LNode, *LINKLIST;
/*不带头结点的单链表,返回反转过后链表的头结点*/
LNode* reverseNode(LNode* begin, LNode* end)
{
LNode* node = begin;
LNode* pre = NULL;
LNode* next;
LNode* head = NULL;
while (node != end)
{
next = node->next;
if (next == end)
{
head = node;
}
node->next = pre;
pre = node;
node = next;
}
return head;
}
/*带头结点的单链表*/
void reverseList(LINKLIST list, int k)
{
int i;
LNode* node = list->next;
LNode* begin;
LNode* end;
LNode* tail = list;
LNode* head = NULL;
while (node != NULL)
{
i = 0;
begin = node;
while (i<k && node)
{
node = node->next;
i++;
}
end = node;
head = reverseNode(begin, end);
tail->next = head; /*将获取到的翻转链表插入到尾结点*/
tail = begin; /*此时链表尾部应该是翻转过后的链表尾结点*/
}
}
/*采用尾插法,创建单链表*/
void createList(LINKLIST list, elem data)
{
LNode* p = list;
LNode* newNode;
while (p->next != NULL)
{
p = p->next;
}
newNode = (LNode*)malloc(sizeof(LNode));
newNode->next = NULL;
newNode->data = data;
p->next = newNode;
}
/*打印单链表*/
void printList(LINKLIST list, void(*print)(elem))
{
LNode* p = list->next;
while (p != NULL)
{
print(p->data);
p = p->next;
}
printf("\n");
}
/*打印结点值*/
void printElem(elem data)
{
printf("%d\t", data);
}
int main()
{
LINKLIST list = NULL;
elem data[] = {1,2,3,4,5,6};
int i;
list = (LINKLIST)malloc(sizeof(LNode));
list->next = NULL;
list->data = 0;
for (i=0; i<6; i++)
{
createList(list, data[i]);
}
printList(list, printElem);
reverseList(list, 2);
printList(list, printElem);
return 0;
}
结果如下:
1 2 3 4 5 6
2 1 4 3 6 5
Press any key to continue...
当k=4结果如下:
1 2 3 4 5 6
4 3 2 1 6 5
Press any key to continue...