反轉鏈表:輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉後的鏈表的頭結點。

題目:定義一個函數,輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉後的鏈表的頭結點。ios

    爲了正確的反轉一個鏈表,須要調整鏈表中指針的方向【指針反向】。注意,在單鏈表中,將一個節點的指向後繼的指針指向它的前驅,將會致使鏈表的斷裂。致使沒法在單鏈表中遍歷它的後繼節點,所以,在調整某一節點的next 指針時,須要首先將其的後繼節點保存下來。函數

    也就是說,在調整節點 i 的 next 指針時,除須要知道節點自己以外,還須要節點 i 的前一個節點 h,由於,咱們把 i 的 next 指向其前驅結點 h,所以還事先須要保存節點 i 的後繼節點 j,以防鏈表斷裂。因此,相應的咱們須要 3 個指針,分別指向當前遍歷節點,其前驅結點 和 後繼結點。spa

    注意,有 3 個問題:指針

    1) 當輸入鏈表的頭指針爲空時,或者是當鏈表中,只有一個節點的狀況,要防止程序崩潰ci

    2)反轉後的鏈表不能出現斷裂it

    3) 反轉後的頭結點應該是原來鏈表的頭結點io

 

//反轉單鏈表:定義一個函數,輸入一個鏈表的頭結點反轉該鏈表,並輸出反轉後鏈表的頭結點。【這裏咱們使用的是帶有頭結點的單鏈表】
#include<iostream>
using namespace std;
stream

typedef int ElemType;
typedef struct LNode
{
 ElemType data;
 struct LNode *next;
}ListNode, *LinkList;
List

LinkList InitializeLinkList(LinkList L)
{
 if(L == NULL)
 {
  L = new ListNode();
  L->next = NULL;
 }
 return L;
}
遍歷

void InsertLinkList(LinkList L, int e)
{
 if(L == NULL)
  return;
 ListNode *p, *s;
 s = L;
 while(s->next != NULL)
  s = s->next;
 p = new LNode();
 p->data = e;
 p->next = NULL;
 s->next = p; 
 s = p;
}

void PrintLinkList(LinkList L)
{
 if(L == NULL)
  return;
 ListNode *p = L->next;
 while(p != NULL)
 {
  cout << p->data << " ";
  p = p->next;
 }
 cout << endl;
}

//反轉單鏈表:須要改變指針的方向
LinkList ReverseLinkList(LinkList L)
{
 ListNode *pPrev, *pNode, *pReverseHead;
 pNode = L;
 pPrev = NULL;
 pReverseHead = NULL;

 while(pNode != NULL)
 {
  ListNode *pNext;
  pNext = pNode->next;
  if(pNext == NULL)
   pReverseHead = pNode;
  pNode->next = pPrev;
  pPrev = pNode;
  pNode = pNext;
 }
 return pReverseHead;
}

int main()
{
 LinkList L, ReverseL;
 L = NULL;
 ReverseL = NULL;
 L = InitializeLinkList(L);
 int e;
 while(cin >> e)
 {
  InsertLinkList(L, e);
 }

 cout << "反轉前的鏈表:"<< endl;
 PrintLinkList(L);

 cout << "反轉後的鏈表:" << endl;
 ReverseL = ReverseLinkList(L);
 //PrintLinkList(ReverseL);
 while(ReverseL->next != NULL)
 {
  cout << ReverseL->data << " ";
  ReverseL = ReverseL->next;
 }
 cout << endl;

 system("pause"); return 0;}

相關文章
相關標籤/搜索