C++算法之 反转单链表

题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点,链表节点定义为:

struct ListNode

int    m_nValue;

ListNode* m_pNext;

};

算法思路:

链表  1-->2-->3-->4-->5

建立一个 pPrev节点,而且为空节点;  pPrev = NULL;再建立一个节点pNode = pHead; 再建立第三个节点pNext = pNode->m_pNext;

pNext的作用:用来保存pNode后面一个的节点,防止链表在中间断开,然后pPrev与pNode往下遍历:

看代码:

ListNode* ReverseList(ListNode* head)
{

	ListNode* pNode = head;
	ListNode* pPrev = NULL;

	while (pNode != NULL)
	{
		ListNode* pNext = pNode->m_pNext;//保存下一个节点的值

		pNode->m_pNext = pPrev;//把当前pNode的下一个节点指向pPrev
		pPrev = pNode;//此时pPrev向后移动指向此时的pNode

		pNode = pNext;//而pNode也向后移动,指向刚才保存的pNext;
	}

	return pPrev;
//	return pReversedHead;

}

完整代码:

// ReverseList.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;
struct ListNode
{
	int         m_nValue;
	ListNode*   m_pNext;

	ListNode()
	{

	}

	ListNode(int i):m_nValue(i),m_pNext(NULL)
	{

	}
};

void AddToTail(ListNode* pHead, int value)
{
	ListNode* pNew = new ListNode();
	pNew->m_nValue = value;
	pNew->m_pNext  = NULL;

	if (pHead == NULL)
	{
		pHead = pNew;
	}
	else
	{
		ListNode* pNode = pHead;
		while (pNode->m_pNext!=NULL)
		{
			pNode = pNode->m_pNext;
		}

		pNode->m_pNext = pNew;
	}
}
void Print(ListNode* head)
{
	ListNode* pNode = head;

	while (pNode!=NULL)
	{
		cout<<pNode->m_nValue<<endl;
		pNode = pNode->m_pNext;
	}
}
ListNode* ReverseList(ListNode* head)
{

	ListNode* pNode = head;
	ListNode* pPrev = NULL;

	while (pNode != NULL)
	{
		ListNode* pNext = pNode->m_pNext;

		pNode->m_pNext = pPrev;
		pPrev = pNode;

		pNode = pNext;
	}

	return pPrev;
//	return pReversedHead;

}
int _tmain(int argc, _TCHAR* argv[])
{

	/*
	ListNode* head  = new ListNode(1);
	ListNode* node1 = new ListNode(2);
	ListNode* node2 = new ListNode(3);
	ListNode* node3 = new ListNode(4);
	ListNode* node4 = new ListNode(5);

	head->m_pNext  = node1;
	node1->m_pNext = node2;
	node2->m_pNext = node3;
	node3->m_pNext = node4;
	node4->m_pNext = NULL;
	*/

	ListNode* pNode1 = new ListNode(1);
	//Print(pNode1);

	AddToTail(pNode1,2);
	AddToTail(pNode1,3);
	AddToTail(pNode1,4);
	AddToTail(pNode1,5);
	cout<<"反转以前:"<<endl;
	Print(pNode1);

	//Print(head);

	ListNode* pNode = ReverseList(pNode1);
	cout<<"反转以后"<<endl;
	Print(pNode);

	getchar();
	return 0;
}

代码可以运行测试通过!

时间: 2024-11-04 19:47:42

C++算法之 反转单链表的相关文章

【LeetCode-面试算法经典-Java实现】【092-Reverse Linked List II(反转单链表II)】

[092-Reverse Linked List II(反转单链表II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->

算法题:反转单链表

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:存在一个单链表,头指针为head,实现单链表的反转Node *Reverse(Node *head).  该算法的求解办法有很多,如: 方法1:先顺序变量单链表,将结点保存到栈中,在从栈中弹出结点,重新建立一个新的单链表: 方法2:用<剑指offer>里面给出的算法,用三个指针来实现: 方法3:采用递归实现,是方法2的递归实现形式. 本文主要给出方法2和方法3,在给出具体的代码之前,先要注意几个问题:          (1)如果hea

递归、非递归 反转单链表

定义链表结构 struct ListNode { int val; ListNode *next; ListNode(int v) : val(v), next(NULL) {} }; 非递归反转单链表 ListNode* reverse(ListNode *root) { if (root == NULL || root->next == NULL) return root; ListNode *cur = root->next; root->next = NULL; while (c

C语言:【单链表】逆置反转单链表

#include<stdio.h> #include<assert.h> #include<stdlib.h> typedef int DataType; typedef struct SListNode {     DataType data;     struct SListNode* next; }SListNode; SListNode* BuyNode(DataType x) {     SListNode* next = (SListNode*)malloc

009实现一个算法来删除单链表中的一个结点,只给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点,因为是单链表,不知道前驱,只知道 后继结点,直接删除会使链表断开.不过我们可以删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =

cc150:实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针. 例子: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不需要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你只有一个指向要删除结点的指针,如果直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这种情况下, 你只能另觅他径.重新审视一下这个问题,我们只能获得从c结点开始后的指针, 如果让你删除c结点后的某个结点,那

反转单链表并验证(详解)

单链表优点: 可以动态增加和删除. 不需要定义初始大小. 点链表缺点: 不能随机访问.需要逐个遍历直到找到目标项. 用到动态内存分配和指针,代码复杂度提升,内存泄漏和内存段错误风险提升. 开销大较大,因为是动态分配内存.而且每项需要存储一个额外的指针. 定义单链表: ------------------------------ ------------------------------ | | | \ | | | | val | next |--------------| val | next

cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你仅仅有一个指向要删除结点的指针,假设直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这样的情况下, 你仅仅能另觅他径.又一次审视一下这个问题,我们仅仅能获得从c结点開始后的指针, 假设让你删除c结点后的