以相反的顺序打印链表的后半部分
Printing the second half of a linked list in reverse order
我想打印链表的元素,首先按它们的顺序打印,然后,一旦我到达中间,就以相反的顺序(从最后一个向后(。例如:
如果元素是:1 2 3 4 5 6
它应该打印:1 2 3 6 5 4
但它正在打印:1 2 3 5 4
为什么不打印最后一个元素?如何解决这个问题?
void reverse()
{
int c=1;
node *current,*prev,*temp;
current=head;
prev=NULL;
std::stack<int>s;
while(current->next!=NULL)
{
c++;
s.push(current->data);
current=current->next;
}
int mid=0;
if((c%2)==0)
{
mid=c/2;
}
else
{
mid=(c+1)/2;
}
current=head;
for(int i=0;i<mid;i++)
{
cout<<current->data<<"t";
current=current->next;
}
for(int i=mid;i>1;i--)
{
std::cout<<s.top()<<"t";
s.pop();
}
std::cout << 'n';
}
假设列表只包含一个元素。在这种情况下,此循环
while(current->next!=NULL)
{
c++;
s.push(current->data);
current=current->next;
}
永远不会执行,因此堆栈将为空。此外,当列表依次为空时,该函数最初具有未定义的行为,因此head
等于 NULL,您可能无法访问current->next
数据成员。
现在让我们假设列表正好包含两个元素。循环将只执行一次,变量 c
得到值 2。 变量mid
的计算值将等于 1。
所以这个循环
for(int i=0;i<mid;i++)
{
cout<<current->data<<"t";
current=current->next;
}
仅执行一次迭代,并输出第一个元素。
然而下一个循环
for(int i=mid;i>1;i--)
{
std::cout<<s.top()<<"t";
s.pop();
}
将; 永远不会执行,因为它的条件i > 1
产生false
,因为 mid 等于 1。
所以程序有两个错误的循环,应该重写。
下面是一个演示程序,显示了如何实现该功能。
#include <iostream>
#include <stack>
struct node
{
int data;
node *next;
} *head = nullptr;
void append( int data )
{
node **current = &head;
while ( *current ) current = &( *current )->next;
*current = new node { data, nullptr };
}
void clear()
{
while ( head )
{
node *tmp = head;
head = head->next;
delete tmp;
}
}
void reverse()
{
std::stack<int> s;
for ( node *current = head; current; current = current->next )
{
s.push( current->data );
}
std::stack<int>::size_type middle = ( s.size() + 1 ) / 2;
std::stack<int>::size_type i = 0;
for ( node *current = head; i < middle; i++ )
{
std::cout << current->data << 't';
current = current->next;
}
for ( i = s.size() - i; i != 0; i-- )
{
std::cout << s.top() << 't';
s.pop();
}
std::cout << std::endl;
}
int main()
{
const int N = 10;
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; j <= i; j++ ) append( j );
reverse();
clear();
std::cout << std::endl;
}
return 0;
}
程序输出为
0
0 1
0 1 2
0 1 3 2
0 1 2 4 3
0 1 2 5 4 3
0 1 2 3 6 5 4
0 1 2 3 7 6 5 4
0 1 2 3 4 8 7 6 5
0 1 2 3 4 9 8 7 6 5
工作代码在这里:http://ideone.com/bbzsSy
2 期:
-
while(current->next!=NULL)
应该是:while(current!=NULL)
这样,您可以确保可以取消引用指针,并且还可以推送最后一个节点。 -
for(int i=0;i<mid;i++)
应该是:for(int i=0;i<lastFordward;i++)
lastFordward=(c%2)?mid-1:mid;
在哪里这样可以避免在c
均匀时两次打印中间位置。
在while
循环中,您正在检查current->next
是否null
您需要检查current
是否null
。
while(current)
{
c++;
s.push(current->data);
current=current->next;
}
您没有将最后一个数字添加到stack
这种方法可以工作...声明一个函数以获取链接列表的大小
public int size()
{
int counter = 0;
node *nodePtr = head;
while (nodePtr)
{
if (nodePtr->next != null)
{
counter++;
}
}
return counter;
}
那么如果返回的大小是偶数...
int c = size()/2;
还。。。
int c = (size()+1)/2;
然后初始化和数组并反向打印它们....尝试一下可能会:)
在典型的链表实现中,最后一个节点不指向任何内容(通常为 nullptr(。因此,将现有元素(current->next!=nullptr(添加到堆栈的停止条件不包括最后一个元素。
遍历电流将是一种更好的方法,因为这会在最后一个节点之后停止一个节点。
另请注意,这将对您的中点计算产生影响,因为它从一开始就偏离了 1。
它不会完全编译,但这行更少:
// assert myList is sorted before called
// if it's not, add
// std::sort(myList.begin(), myList.end());
// as the first line of the function
void reverseLatterHalf(std::vector& myList) {
auto it = myList.begin() + myList.size() / 2;
std::reverse(it, myList.end());
}
- 在C++中删除双向链表的头节点后出现访问冲突异常
- 为什么将函数的返回类型从结构节点*更改为void后,链表的元素没有显示create_ll和显示?
- 链表 - 元素在删除后出现
- 为什么T是未定义的?我正在尝试实现一个用于双链表的节点类,它不喜欢我使用友元运算符后的T
- 使用迭代从链表向后打印字符串
- 如何使我的链表在C++中向后打印
- ASAN:将二叉树平展为链表时释放后堆使用
- 以相反的顺序打印链表的后半部分
- 在 for 循环(链表)中删除两次后,变量不可用
- 排序后将数据添加到链表
- 试图用c++编写我自己的链表实现,在点击列表中的3个元素后编写segfault代码
- 从后到前显示使用链表实现的队列
- 如何向后显示有序的双向链表
- 链表堆栈类的复制构造函数:我的正在向后复制
- 第15次循环后出现链表运行时错误
- 添加到链表的节点在函数后恢复为 NULL
- 如何在链表中遍历后得到列表的头
- 链表只打印添加新节点后的最后一个元素
- 我的程序在将节点读入链表后不断循环,只重复显示一个节点
- 将项插入链表后进行排序