陣列是將元素在記憶體中連續存放,由於每個元素占用記憶體相同,可以通過下標迅速訪問陣列中任何元素。鍊錶恰好相反,鍊錶中的元素在記憶體中不是順序儲存的,而是通過存在元素中的指標聯絡到一起。
單鏈表是線性表鏈式儲存的一種,其儲存不連續。它的資料結構中包含兩個變數:資料和指向下乙個結點的指標。每個結點(尾結點除外)都只知道它的下乙個結點的儲存位址。乙個單鏈表必須有乙個頭指標,用來指向單鏈表中的第1個元素結點(或頭結點);否則鍊錶會在記憶體中丟失。
#include
#include
using
std::cin;
using
std::cout;
using
std::endl;
struct listnode
};//不帶頭結點,從頭部插入
listnode* createlist_head(int n)
else
//第1個結點}}
return phead;
}
//不帶頭結點,從尾部插入
listnode* createlist_tail(int n)
else
//第1個結點}}
pnext->next=null;
return phead;
}
//帶頭結點,從頭部插入
listnode* createlisthead_head(int n)}}
return phead;
}
//帶頭結點,從尾部插入
listnode* createlisthead_tail(int n)
}pnext->next=null;
}return phead;
}
【注:】當單鏈表不帶頭結點時,頭指標指向鍊錶的第1個元素結點;當單鏈表帶頭結點時,頭指標指向鍊錶的頭結點。
//反轉整個鍊錶
listnode* revlistnode(listnode* phead)
phead->next=
null;
return prevhead;
}
//反轉鍊錶的某一區間結點[startid,endid],結點下標從1開始
listnode* revpartlistnode(listnode* phead,int startid,int endid)
else
//反轉起始下標為1時鍊錶的頭指標才會改變
break;
}pprev=pnext;
pnext=ptemp;}}
else
}return prevparthead;
}
//列印鍊錶的所有結點值
void printlistnode(listnode* phead)
cout<
}
接著測試上述**的正確性
#define listnodelen 10
int main()
輸入測試用例(單鏈表)為,測試結果為
從上圖可知,除了列印初始單鏈表和列印全部反轉後的單鏈表的結果符合預期外,列印部分反轉後的單鏈表的結果顯得比較奇怪,都只有乙個元素0值。
原因:在這5個列印操作中,鍊錶結點指標phead沒有改變,它始終指向元素值為0的鍊錶結點。自從第2個列印中單鏈表全部反轉操作後,元素值為0的鍊錶結點成為了新鍊錶的尾結點;此時phead指向的「單鏈表」只包含元素值為0的這乙個結點。故後面的3個部分反轉後的列印結果只有乙個元素0值。
更改測試程式重新測試
#define listnodelen 10
int main()
測試結果如下所示
從上可知,單鏈表順利地完成了全部反轉和部分反轉。例如第3個列印操作將初始單鏈表的前4個結點反轉。由於phead始終指向元素值為0的結點,故在第4個列印操作時「單鏈表」只有7個結點,接著反轉它的第[2,5]個結點。由於「單鏈表」長度只有7,故最後的反轉操作在第[6,7]個結點上。
1.單鏈表帶頭結點&不帶頭結點
2.資料結構(四)——單鏈表 、帶頭結點的單鏈表、迴圈鍊錶 及其實現
單鏈表(帶頭結點)
按照自己的想法和思路寫了一下帶頭結點的單鏈表,並進行了測試,畢竟自己能力有限,可能有的地方沒有測試到,還可能存在一些潛在的錯誤。標頭檔案 include using namespace std typedef struct node node,link typedef struct list lis...
單鏈表 帶頭結點
typedef struct lnodelnode,linklist 頭插法 linklist list headinsert linklist l returnl 尾插法 linklist list tailinsert linklist l r next null 尾結點指標置空 returnl...
資料結構 單鏈表 帶頭結點和不帶頭結點
1 單鏈表 通過各結點的鏈結指標來表示結點間的邏輯關係,長度可擴充,遍歷或查詢 2 只能從指標的指示的首元結點開始,跟隨鏈結指標逐個結點進行訪問,進行刪除或插 4 5 6 單鏈表的結構定義 7 typedef int datatype 8 typedef struct node 9 linknode...