倒序单链表

 
倒序单链表
作者: 异域の蜗牛  联系方式: 425131593@qq.com
 
近来一些公司笔试时有这题,随手写一下
算法:
A.      首先保存1的next(即链表前进一个位置到2),然后1的next指向空作为倒序后的最后一个,从此时此刻1起,1相邻右边成员的next指向的地址与前一个(左边一个)成员的地址交换.交换后1的地址被3替换(即1到3的位置),变成3,2的next指向1的地址.
B.      此时再将2与3地址互换,再次形成A部份的情况.
用此方法反转链表,看起来似间隔一个链表成员交换地址,形像表示如下:
1 2-3-4-5-6   1与3交换
1-2 3-4-5-6   2与4交换
1-2-3 4-5-6   3与5交换
1-2-3-4 5-6   4与6交换
1-2-3-4-5 6   2与4交换
C.      最后一步将6的next人工指向5,完工.
 
结果如下图所示:
 
D.     总结下,要是链表长为1000,那么会调用swap1996次,效率较低占用时间较多,而且伴随大量的强制类型转换与异或运算,虽然只用了一个变量,但效率明显不高,权当学习了使用指针的指针的强制类型转换来参与的地址的异或运算.对函数传参,地址的处理,链表的运用有了更为深入的了解.
E.      附代码:
// 单链表倒序.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
 
struct list{int data;list* next;};
list* createlist()
{
       list *head=new list,*p=head;
       for(int temp=1;temp<1000;temp++)
       {
              p->data=temp;
              p->next=new list;
              p=p->next;
              p->data=temp+1;
              p->next=0;
       }
return head;
}
 
void swap(list** a,list** b)
{
       *a=(list*)((int)*a^(int)*b);
       *b=(list*)((int)*a^(int)*b);
       *a=(list*)((int)*a^(int)*b);//head=rehead^head;rehead=rehead^head;//swap
}
 
list* ReverseList(list* head)
{
       list *rehead=head;
       head=head->next;
       rehead->next=0;
       while(head->next)
       {
              swap(&rehead,&head->next);
              swap(&rehead,&head);
       }
       head->next=rehead;
       return head;
}
 
 
  list* head=createlist();
  list* rehead=ReverseList(head);
 
### C++ 单链表倒序输出 #### 一、基本概念 单链表是一种线性的数据结构,每个节点包含两部分:一部分用于存储数据元素;另一部分是指向下一个结点的指针。由于其灵活性,在许多应用场合都有广泛的使用。 对于“**C++单链表倒序输出**”,我们通常有两种常用的方法: --- #### 方法1 - 使用栈 (Stack) 倒叙打印 通过遍历整个列表并将所有值压入一个辅助的数据结构——如`std::stack`,然后再从该堆栈弹出所有的项并依次输出即可实现逆序显示的效果。 ```cpp #include <iostream> #include <stack> using namespace std; // 定义链表节点结构体 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; void printReverse(ListNode* head) { stack<int> stk; // 创建一个空栈 while(head != nullptr){ stk.push(head->val); // 将当前节点存入栈内 head = head->next; // 移动到下一节点 } cout << "反转后的结果:" << endl; while(!stk.empty()){ cout << stk.top() << ' '; // 输出栈顶元素 stk.pop(); // 弹出栈顶元素 } } int main(){ // 测试样例: 构建简单链表 {5 -> 4 -> 8} auto n3 = new ListNode(8); auto n2 = new ListNode(4); auto n1 = new ListNode(5); n1->next=n2;n2->next=n3; printReverse(n1); return 0; } ``` 这种方法的优点在于它不会改变原始链表,并且只需要O(N)的时间复杂度就能完成操作。缺点是需要额外的空间来保存节点信息。 --- #### 方法2 - 修改原链表顺序后再正向打印 如果你不需要保持原有的链接关系,则可以直接修改实际存在的链表使其成为反向排列的形式再进行正常遍历读取。 ```cpp ListNode *reverseList(ListNode *head) { if (!head || !(head->next)) return head; ListNode *prevNode = NULL; while (head != NULL) { ListNode *tempNext = head->next; head->next = prevNode; prevNode = head; head = tempNext; } return prevNode; // 返回新的头指针 } /* 简化main函数 */ int main() { /*...初始化同上 */ reverseHead = reverseList(n1); for(auto curr=reverseHead ;curr!=nullptr ;curr=curr->next ) printf("%d ",curr->val ); return 0 ; } ``` 此方法直接对链表进行了翻转,使得原来的最后一个元素成为了新序列的第一个成员。但是请注意这样做会破坏原有链条间的关系连接! --- 无论选择哪种方式处理这个问题都要考虑到内存管理和边界条件检查等问题以保证程序健壮性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值