[英]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
在while
循环中,您正在检查current->next
是否为null
您需要检查current
是否为null
。
while(current)
{
c++;
s.push(current->data);
current=current->next;
}
您没有将最后一个数字添加到stack
此方法可以工作...声明一个函数以获取linkList的大小
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)不包含最后一个元素。
在电流上进行迭代将是更好的方法,因为它将在最后一个节点之后停止。
还要注意,这将对您的中点计算产生影响,因为它从一开始就偏离了一个。
它并不会完全编译,但这会减少一些行:
// 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());
}
此处的工作代码: 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
为偶数时两次打印中间位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.