單鍊表逆置

單鍊表逆置

單鍊表逆置,是一種輸入命令。單鍊表是一種鏈式存取的數據結構,用一組地址任意的存儲單元存放線性表中的數據元素。單鍊表逆置在程式設計中經常用到。

需求分析

1、本程式由用戶輸入運行命令和數據,運行結果顯示在其後。

2、程式執行的命令包括:

1)創建一個鍊表;2)執行鍊表的逆置;3)結束。

2、測試數據

鍊表:abc123

概要設計

1、鍊表的抽象數據類型定義為:

ADTNumber{

數據對象:D={ai|ai∈(0,1,…,9),i=0,1,2,…,n,n≥0}

數據關係:R={<ai-1,ai>|ai-1,ai∈D,i=1,2,…,n}

基本操作:

CreateList(&L)

操作結果:創建一個鍊表L。

PrintList(L)

初始條件:鍊表L已存在。

操作結果:在螢幕上輸出鍊表的值。

InverseList(L)

初始條件:鍊表L已存在。

操作結果:將鍊表逆置。

DestroyList(&L)

初始條件:鍊表L已存在。

操作結果:銷毀鍊表L。

} ADTNumber

2、本程式包含五個模組:

(1)主程式模組:

int main(){

定義變數;

接受命令;

處理命令;

退出(return 0);

}

(2)創建鍊表模組——產生一個鍊表;

(3)輸出鍊表模組——把鍊表輸出;

(4)鍊表逆置模組——將鍊表逆置;

(5)銷毀鍊表模組——程式結束後釋放鍊表開闢的空間。

各模組之間的調用關係如下:

主程式模組 創建鍊表模組

創建鍊表模組 輸出鍊表模組 鍊表逆置模組

輸出鍊表模組 創建鍊表模組 銷毀鍊表模組

詳細設計

#include<iostream>

using namespace std;

struct Number //鍊表的類型

{

char data; //鍊表當前結點的值

struct Number *next; //鍊表當前結點指向下一結點的指針

}*number;

void CreateList(Number *&L) //創建鍊表

{

Number *s,*r; //定義兩個鍊表類型的臨時指針

char x; //定義一個臨時字元變數

L=(Number *)malloc(sizeof(Number)); //為頭結點開闢空間

L->next=NULL; //此時頭結點的後繼指針和前驅指針賦值為空

r=L; //是r指針指向頭結點

x=getchar(); //用x接受一個從鍵盤輸入的字元

while(x!="\n") //控制當輸入回車鍵時結束

{

s=(Number *)malloc(sizeof(Number)); //開闢下一結點的空間

s->data=x;

r->next=s; //r的後繼指針指向s

r=s; //是s指向r

x=getchar(); //用x接受一個從鍵盤輸入的字元

}

r->next=NULL; //當創建結束時,r的後繼指針為空

}

void PrintList(Number *L) //輸出鍊表

{

Number *p=L->next; //定義一個臨時指針並指向鍊表的第一個結點

while(p!=NULL) //判斷結點是否為空,空就結束

{

cout<<p->data; //輸出結點的值

p=p->next; //指向下一個結點

}

cout<<endl; //換行

}

void InverseList(Number *L) //鍊表的逆置

{

Number *p=L->next,*q=L->next;

q=q->next;

p->next=NULL;

p=q;

while(p!=NULL)

{

q=q->next;

p->next=L->next;

L->next=p;

p=q;

}

}

void DestroyList(Number *&L) //銷毀鍊表

{

Number *p=L,*q=p->next;

while(q!=NULL)

{

free(p); //釋放p的空間

p=q;

q=p->next;

}

cout<<"釋放鍊表"<<endl;

}

int main()

{

cout<<"請輸入一個鍊表:";

CreateList(number); //調用創建鍊表

cout<<"********************************************************************************";

cout<<"輸入的鍊表為:"<<endl;

PrintList(number); //調用輸出鍊表

InverseList(number); //調用逆置鍊表

cout<<"此鍊表的逆置為:"<<endl;

PrintList(number); //調用輸出鍊表

cout<<"********************************************************************************";

DestroyList(number); //調用銷毀鍊表的函式

return 0;

}

調試分析

1、在創建長整數時,沒有使用getchar()來接受字元,而用C++中的cin>>來輸入,這樣使得每一次輸入之後都要按回車鍵,而且在輸入結束時控制也不方便,使用getchar()函式解決了這一問題。

2、首先,遇到的問題就是if條件中的“= =”中少了一個“=”導致編譯正確,但是一運行就錯誤,這個問題不該錯的,以後一定重視每一個細節。還有就是鍊表的使用過程中,指針太多,一會兒指向這個,一會兒又指向那個,如果思路不清楚的話,很容易弄暈的;有時候一個指針指向空的時候根本就不知道,編譯沒錯誤,檢查不出來,一運行就不正確,有時候運行正確了,但是結果卻不正確,這還好點,有時候指針指向空了,運行就彈出錯誤要終止程式。經過一步一步的測試,一步一步的運行,花了不少時間終於弄出來了。

3、在銷毀鍊表的時候,也遇到過一個問題,還沒弄明白是為什麼。在銷毀鍊表的函式中,如果參數接受兩個鍊表來銷毀的話,如:void DestroyList(Number *&L1,Number *&L2),運行會出錯,或許是我寫的代碼不正確;但是,當用void DestroyList(Number *&L)來一個鍊表一個鍊表的銷毀就沒問題。

運行環境

(1)Windows 7系統下

(2)編程環境:VC6.0++ ,TC2.0

相關詞條

熱門詞條

聯絡我們