这也是学校的一道OJ题目,题目如下:
题目描述:
按数字输入顺序创建单链表。不可借助数组、容器,不可开辟新结点空间。编写函数,在原链表上实现单链表的反转。例如单链表10->20->30,反转后变为单链表30->20->10。
注:不符合题目要求,使用上述逆序输出不计分。
输入:
测试次数t
每组测试数据一行,格式如下:
数据个数n,后跟n个整数
输出:
对每组测试数据,输出反转后的单链表。
输入样例:
2
10 1 2 3 4 5 6 7 8 9 10
4 19 20 15 -10
输出样例:
10 9 8 7 6 5 4 3 2 1
-10 15 20 19
AC代码:
#include <iostream>
using namespace std;
typedef struct node{
node*before;
int data;
node*next;
}node;
node* createlist(node*&head,int n)
{
head=new node;
head->before=NULL;
node*pre=head;
for(int i=0;i<n;i++)
{
node*p=new node;
cin>>p->data;
p->next=NULL;
p->before=pre;
pre->next=p;
pre=p;
}
return pre;
}
void print(node*&end)
{
for(node*p=end;p->before;p=p->before)
{
cout<<p->data<<" ";
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
node*head;
node*end;
end=createlist(head,n);
print(end);
}
return 0;
}
这道题有许多思路,可以从输出控制的层面解决,也可以从输入层面进行思考,也可能有方法可以先初始化链表再对链表进行反序,在这道题中我用的是从输出的层面来思考的方法。
这里使用的是创建双头链表的方法,即在原本尾插法创建单链表的方法上加上了一个before结构体指针。
所以重点就是如何创建并输出链表。
下面是链表的创建:
typedef struct node{
node*before;//创建指向前一个节点的指针
int data;
node*next;
}node;
node* createlist(node*&head,int n)
{
head=new node;
head->before=NULL;//头节点的before指针相当于单链表的尾指针
node*pre=head;//与之前的尾插法创建单链表相同,头节点里面不装载数据
for(int i=0;i<n;i++)
{
node*p=new node;
cin>>p->data;
p->next=NULL;
p->before=pre;//多了一步,新节点的before指针需指向上一个节点,依然只需要定义两个指针即可完成初始化的推进
pre->next=p;
pre=p;
}
return pre;//返回指向end节点的指针,之后作为初始节点进行输出
}
创建好双向链表之后,就只需选择逆序方式进行输出即可:
void print(node*&end)//初始节点为尾节点
{
for(node*p=end;p->before;p=p->before)//因为head->before为NULL,所以选取head->before作为跳出的条件
//若选取head作为条件,则此时遍历已经过头节点,而头节点是无数据装载的,所以要选取head->next
{
cout<<p->data<<" ";
}
cout<<endl;
}
所以最后代码总结为;
#include <iostream>
using namespace std;
typedef struct node{
node*before;//创建指向前一个节点的指针
int data;
node*next;
}node;
node* createlist(node*&head,int n)
{
head=new node;
head->before=NULL;//头节点的before指针相当于单链表的尾指针
node*pre=head;//与之前的尾插法创建单链表相同,头节点里面不装载数据
for(int i=0;i<n;i++)
{
node*p=new node;
cin>>p->data;
p->next=NULL;
p->before=pre;//多了一步,新节点的before指针需指向上一个节点,依然只需要定义两个指针即可完成初始化的推进
pre->next=p;
pre=p;
}
return pre;//返回指向end节点的指针,之后作为初始节点进行输出
}
void print(node*&end)//初始节点为尾节点
{
for(node*p=end;p->before;p=p->before)//因为head->before为NULL,所以选取head->before作为跳出的条件
//若选取head作为条件,则此时遍历已经过头节点,而头节点是无数据装载的,所以要选取head->next
{
cout<<p->data<<" ";
}
cout<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
node*head;
node*end;
end=createlist(head,n);
print(end);
}
return 0;
}