单链表的反转(逆序)在笔试与面试的场合中出现的频率很高,说明这个对我们掌握单链表有很大的帮助。
那么什么是单链表的反转呢?
反转通常指将一组数据全部按与原来相反的顺序排列,例如1,2,3,4反转后就是4,3,2,1了,这个不难理解。可是对于单链表来说,就不像堆积木一样这么简单了,但也不是很难。
魔站上对于单链表的反转有很详细的代码与说明,我觉得写的很好,我在这就不再写了,直接附上链接
我在看完后心血来潮,想了想,何不写一个反转任意长度的单链表函数呢?下面附上我的代码
.h文件里的部分定义:
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef struct node{
ElemType data; //数据
struct node *next; //后继
}Node, *LinkList;
单链表反转/逆序任意长度函数:
/*
单链表反转任意长度
例如: ListReverse_s(list, 3, 6)
反转list的第三至六个元素,left和right一定要在规定范围内
*/
int ListReverse_s(LinkList L, int left, int right)
{
LinkList head = L, current, current_next;//头,当前元素,当前下一个元素指针
int Llength = ListLength(L);//链表长度为Llength
//如果链表为空或者左右边界不在链表的长度范围内则返回FALSE
if (IsEmpty(L) || left < 1 || left > Llength - 1 ||
right < 2 || right > Llength || left >= right)
return FALSE;
//先移动头指针至需要反转的左边界前一个位置
for (int i = 0 ; i < left - 1; i++)
head = head->next;
current = head->next;//当前指针指向头指针的下一个位置
//进行反转
for (int i = 0; i < right - left; i++)
{
current_next = current->next;
current->next = current_next->next;
current_next->next = head->next;
head->next = current_next;
}
return TRUE;
}
主函数:
int main(int argc, char *argv[]) {
LinkList list;
ListInit(&list);//初始化一个单链表
//给单链表连续插入节点,按顺序值为0~9的10个节点
for (int i = 0; i < 10; i++)
Push(list, i);
printf("反转前单链表为:\n") ;
PirntAllList(list);
ListReverse_s(list, 3, 6);//反转单链表的3至6个节点
printf("反转后单链表为:\n") ;
PirntAllList(list);
return 0;
}
程序的输出是:
这个函数的核心其实就是移动头指针,其它的操作和正常的没有太大区别。