我想打印链表的元素,首先按顺序打印,然后,一旦我到达中间,按相反顺序打印(从最后一个向后)。例如:
如果元素是: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';
}
答案 0 :(得分:1)
假设列表只包含一个元素。在这种情况下,这个循环
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
答案 1 :(得分:0)
在while
循环中,您正在检查current->next
是否null
,您需要检查current
是否为null
。
while(current)
{
c++;
s.push(current->data);
current=current->next;
}
您没有将最后一个号码添加到stack
答案 2 :(得分:0)
此方法可以工作...声明一个函数来获取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;
然后初始化和数组并反向打印它们......尝试一下可能会有效:)
答案 3 :(得分:0)
在典型的链表实现中,最后一个节点指向空(通常为nullptr)。因此,将现有元素(current-&gt; next!= nullptr)添加到堆栈的停止条件不包括最后一个元素。
迭代当前将是一种更好的方法,因为它会在最后一个节点之后停止一个。
另请注意,这会对您的中点计算产生影响,因为它从一开始就被一个关闭。
答案 4 :(得分:0)
这不太适合编译,但是线条要少一些:
// 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());
}
答案 5 :(得分:0)
这里的工作代码: 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
为偶数时打印中间位置两次。