单链表反转(C++)

单链表是很基础的算法题
有至少三种方法可以实现:

1:将单链表储存为数组,然后按照数组的索引逆序进行反转。
2:使用三个指针遍历单链表,逐个链接点进行反转。
3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。

方法1的问题是浪费空间。方法2和方法3效率相当。一般方法2较为常用。
在这里只贴出前两种方法。
方法1:

bool List::printListFromTailToHead() {
      	Node* temp = m_pList;               //m_pList即为头节点
        int lengthOfList=0,len=0;
        while( temp !=NULL)
            {
           	 lengthOfList ++;               //算出链表长度
           	 temp=temp->next;
        	}
        vector<int> n(lengthOfList) ;       //申请合适大小的容器vector
        len = lengthOfList;                 //记录以便打印
        temp=m_pList;
        while(lengthOfList>0)
        {
            n[lengthOfList-1] =temp->data; //倒序放入数据
            temp=temp->next;
            lengthOfList--;
        }    
		 for(int i=0;i<len;i++)            //正序打印
		 cout << n[i]<<endl;               //若要得到新链表此处要修改为正序创建新链表
        return true;
    }

方法2:

bool List::listReversal()
{
	    Node* p=NULL;
        Node* q=NULL;
        Node* r=NULL;
        p=m_pList;                    //头节点
        q=p->next;                    //用来判断循环停止的条件
        while(q)                                    //原则是要用先保存,存完才能用,以免被覆盖
        {
            r=q->next;                //保存下一个指向
            q->next=p;                // 修改指向 
            p=q;                      //保存当前结点,以便下次循环使用时能够找到
            q=r;                      //向下循环
        }
        m_pList->next=NULL;	          //最后修改原头指针为尾指针
        while(p)
        {
        	cout<<p->data<<endl;
        	p=p->next;
		}
        return true;
}

提示:

以上两段代码需要配合以前笔记中单链表部分中Node.cpp以及List.cpp文件中代码,此外,为了可以使用容器vector,不要忘记加入#include<vector>
为了便于验证,在函数内打印出data,此非明智之举。

验证代码domo.cpp:

#include<iostream>
#include"List.h" 
using namespace std;

int main(void)
{
	Node node1;
	node1.data=3;
	node1.next=NULL;
	Node node2;
	node2.data=4;
	node2.next=NULL;
	Node node3;
	node3.data=5;
	node3.next=NULL;
	Node node4;
	node4.data=6;
	node4.next=NULL;
	Node node5;
	node5.data=7;
	node5.next=NULL;
	List *pList = new List();
	cout<<"insert from tail:"<<endl; 
	pList->ListInsertTail(&node1);
	pList->ListInsertTail(&node2);
	pList->ListInsertTail(&node3);
	pList->ListInsertTail(&node4);
	pList->ListInsertTail(&node5);
	pList->ListTraverse();
		
	cout<<"after reversal by way1:"<<endl;
	pList->printListFromTailToHead();	
   //cout<<"after reversal by way2:"<<endl;
   //pList->listReversal();
	
	delete pList;
	pList = NULL;
	
	return 0;
}

运行结果:
这里写图片描述
这里写图片描述
注明:如有错误,还请指出。
本文借鉴自博客
http://blog.csdn.net/sicofield/article/details/8850269
该博客还有第三种方法的实现代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值