您的位置:首页 > 编程语言 > C语言/C++

左神的书——《程序员代码面试指南》之逆置单链表的部分节点 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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: