[英]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.