左神的书——《程序员代码面试指南》之逆置单链表的部分节点 c++实现
2017-01-05 14:33
393 查看
//给定一个单向链表的头节点head,以及两个整数from和to,在单向链表上把第from个节点到to个节点这一部分进行反转。
//例如:
//1->2->3->4->null,from = 2,to = 4
//调整结果为:1->4->3->2->5->null
//再如:
//1->2->3->null,from = 1,to = 3
//调整结果为:3->2->1->null
//要求1.链表长度为N,时间复杂度要求为O(N),额外空间复杂度为O(1)。
// 2.如果不满足1<= from <= to <= N,则不用调整。
//思路:
//先找到第from个节点的前一个节点fpos,第to个节点的后一个节点tpos,fpos是反转部分的前一个节点,tpos是反转部分的后一个节点,
//把反转部分先反转,然后正确地连接fpos和tpos,
//注意:当from为1时,说明要将头部逆转,所以参数类型为一级指针的引用,修改头指针的指向。如果from不为1,则返回旧的节点。
#include<iostream>
using namespace std ;
#include <cassert>
struct Node
{
int value;
struct Node * Next;
Node(int data):value(data),Next(NULL) { }
};
void ReversePart(Node* & pHead,int from,int to)
{
assert(pHead && from > 0 && to > 0);
Node *pCur = pHead;
int size = 0;
while (pCur)
{
size++;
pCur = pCur->Next;
}
if (from >= to || to > size ) //不满足1<= from <= to <= N,则不用调整。
{
return;
}
Node *tpos = pHead;
while (to--) //while循环遍历后tpos要指向这个节点的后一个节点。
{
tpos = tpos->Next;
}
if (from == 1) //说明要逆置的范围包括头节点,要修改PHead的指向。
{
Node *pCur = pHead->Next;
Node *pPre = pHead;
while (pCur != tpos)
{
Node * pNext = pCur->Next;
pCur->Next = pPre;
pPre = pCur;
pCur = pNext;
}
pHead->Next = tpos;
pHead = pPre;
}
else
{
Node *fpos = pHead;
while (--from != 1) //while循环遍历后fpos要指向这个节点的前一个节点。
{
fpos = fpos->Next;
}
Node *pCur = fpos->Next->Next;
Node *pPre = fpos->Next;
//这里都用到逆置函数,可以将这些代码封装成一个函数的。
while (pCur != tpos)
{
Node * pNext = pCur->Next;
pCur->Next = pPre;
pPre = pCur;
pCur = pNext;
}
fpos->Next->Next = tpos;
fpos->Next = pPre;
}
}
int main()
{
//这里只是单纯的分配节点,不释放节点,要不然篇幅太长了。毕竟节点的分配和释放不是重点。
Node *n1 = new Node(1);
Node *n2 = new Node(2);
Node *n3 = new Node(3);
Node *n4 = new Node(4);
Node *n5 = new Node(5);
Node *n6 = new Node(6);
Node *pHead1 = n1;
n1->Next = n2;
n2->Next = n3;
n3->Next = n4;
n4->Next = n5;
n5->Next = n6;
ReversePart(pHead1,1,2);
Node *pCur = pHead1;
while (pCur)
{
cout << pCur->value <<endl;
pCur = pCur->Next;
}
cout << "hello..." <<endl;
system("pause");
return 0;
}
//例如:
//1->2->3->4->null,from = 2,to = 4
//调整结果为:1->4->3->2->5->null
//再如:
//1->2->3->null,from = 1,to = 3
//调整结果为:3->2->1->null
//要求1.链表长度为N,时间复杂度要求为O(N),额外空间复杂度为O(1)。
// 2.如果不满足1<= from <= to <= N,则不用调整。
//思路:
//先找到第from个节点的前一个节点fpos,第to个节点的后一个节点tpos,fpos是反转部分的前一个节点,tpos是反转部分的后一个节点,
//把反转部分先反转,然后正确地连接fpos和tpos,
//注意:当from为1时,说明要将头部逆转,所以参数类型为一级指针的引用,修改头指针的指向。如果from不为1,则返回旧的节点。
#include<iostream>
using namespace std ;
#include <cassert>
struct Node
{
int value;
struct Node * Next;
Node(int data):value(data),Next(NULL) { }
};
void ReversePart(Node* & pHead,int from,int to)
{
assert(pHead && from > 0 && to > 0);
Node *pCur = pHead;
int size = 0;
while (pCur)
{
size++;
pCur = pCur->Next;
}
if (from >= to || to > size ) //不满足1<= from <= to <= N,则不用调整。
{
return;
}
Node *tpos = pHead;
while (to--) //while循环遍历后tpos要指向这个节点的后一个节点。
{
tpos = tpos->Next;
}
if (from == 1) //说明要逆置的范围包括头节点,要修改PHead的指向。
{
Node *pCur = pHead->Next;
Node *pPre = pHead;
while (pCur != tpos)
{
Node * pNext = pCur->Next;
pCur->Next = pPre;
pPre = pCur;
pCur = pNext;
}
pHead->Next = tpos;
pHead = pPre;
}
else
{
Node *fpos = pHead;
while (--from != 1) //while循环遍历后fpos要指向这个节点的前一个节点。
{
fpos = fpos->Next;
}
Node *pCur = fpos->Next->Next;
Node *pPre = fpos->Next;
//这里都用到逆置函数,可以将这些代码封装成一个函数的。
while (pCur != tpos)
{
Node * pNext = pCur->Next;
pCur->Next = pPre;
pPre = pCur;
pCur = pNext;
}
fpos->Next->Next = tpos;
fpos->Next = pPre;
}
}
int main()
{
//这里只是单纯的分配节点,不释放节点,要不然篇幅太长了。毕竟节点的分配和释放不是重点。
Node *n1 = new Node(1);
Node *n2 = new Node(2);
Node *n3 = new Node(3);
Node *n4 = new Node(4);
Node *n5 = new Node(5);
Node *n6 = new Node(6);
Node *pHead1 = n1;
n1->Next = n2;
n2->Next = n3;
n3->Next = n4;
n4->Next = n5;
n5->Next = n6;
ReversePart(pHead1,1,2);
Node *pCur = pHead1;
while (pCur)
{
cout << pCur->value <<endl;
pCur = pCur->Next;
}
cout << "hello..." <<endl;
system("pause");
return 0;
}
相关文章推荐
- 单链表的逆置-C++实现
- 单链表的逆置-C++实现
- 左神的书——《程序员代码面试指南》之逆置单链表或双链表 c++实现
- 单链表的逆置-C++实现
- 单链表的逆置-C++实现(ok)
- C++实现单链表删除倒数第k个节点的方法
- 左神的书——《程序员代码面试指南》之打印两个有序链表的公共部分 c++实现
- 单链表的逆置-C++实现
- C++实现删除单链表节点的功能(源代码+截图)
- 用C++实现单链表的创建、逆置和输出
- 17_7_14:逆置单链表+查找单链表的倒数第K个节点+非常规方法实现Add函数
- 单链表的逆置-C++实现
- 单链表的逆置-C++实现
- 单链表的逆置-C++实现
- 用C++实现单链表的创建、逆置和输出 的两种方法
- 左神的书——《程序员代码面试指南》之删除链表的中间节点或a/b节点 c++实现
- 单链表的逆置-C++实现
- 【c++版数据结构】之单链表的实现(带头结点以及尾节点)
- 单链表的逆置-C++实现
- 单链表的逆置-C++实现