算法与数据结构----反转链表(整体反转、部分反转)

1. 问题 : 链表的整体反转

题目 : 将链表整体进行反转
例如 : 链表 1 --> 2 --> 3 --> 4 --> 5 反转为 5 --> 4 --> 3 --> 2 --> 1

//算法思想 : 记录 当前遍历结点的前一个结点和后一个结点 确保每次向后遍历能够找到
//当前结点的前一个结点 以此完成链表的反转 同时时间复杂度最小 为O(n)
listNode * listReverse_all(listNode * list) {
	listNode * nextNode = list->next;	
	listNode * rNode = list;
	listNode * beforeNode = NULL;

	while (nextNode != NULL) {
		rNode->next = beforeNode;
		beforeNode = rNode;
		rNode = nextNode;
		nextNode = nextNode->next;
	}

	rNode->next = beforeNode;
	
	return rNode;
}

2. 链表的部分反转

题目 : 将链表的部分进行反转
输入 : 给定一个链表和一个数字 按照数字大小 对链表的部分进行反转

如将链表 1–>2–>3–>4–>5 的每两位进行反转 给定该链表 和 数字2, 部分反转后得到链表
2–>1–>4–>3–>5

listNode * listReverse_part(listNode * list, int k) {

	if (k <= 1 || list == NULL) {
		return list;
	}

	listNode * cur = list;	//指向当前遍历到的结点
	listNode * newHead = NULL;	//部分反转后的链表的头结点
	listNode * sectionHead = NULL;	//反转部分的表头
	listNode * sectionTail = NULL;	//反转部分的表尾
	listNode * preTail = NULL;	//前一部分的表尾(用于和下一个部分表头进行连接)
	int sectionNum = 0;	//记录反转到第几部分


	while (cur != NULL) {
		int count = k;	//记录反转数
		preTail = sectionTail;
		sectionTail = cur;

		while (count-- && cur != NULL) {	
			listNode * tmp = cur;	//tmp表示当前结点
			cur = cur->next;	//有tmp保存 我们将cur指向下一个结点
			tmp->next = sectionHead;	//将tmp指向的结点进行反转
			sectionHead = tmp;	//sectionHead用来记录下一个将要反转结点的前一个结点
		}

		sectionNum++;
		if (sectionNum == 1) {
			newHead = sectionHead;
		}
		else {
			preTail->next = sectionHead;
		}
	}

	sectionTail->next = NULL;

	return newHead;
}

输入

10	//链表长度    
1 2 3 4 5 6 7 8 9 10	   //链表中数
4	//部分翻转长度

输出

4 3 2 1 8 7 6 5 10 9

你可能感兴趣的:(算法笔记)