知識點回顧:
單鏈表類型定義:
//類型定義 typedef struct Lnode{ ElemType data; struct Lnode *next; }Lnode, *LinkList //變量定義 LinkList L;//注意此處是不加 * 的,原因看類型變量的結構體變量形式 Lnode *p,*s;//注意此處是加 * 的。原因如上 //重要操作 p=L;//p指向頭結點 s=L->next;//s指向首元結點 p=p->next;//p指向下一結點 //單鏈表的基本操作: //單鏈表的銷毀 Status DestroyList_L(LinkList &L){ //用於指向要銷毀的結點 Lnode *p; //循環條件,鏈表L非空(這是傳入的參數) while(L){ //讓 指針p 用於指向要銷毀的鏈表的頭結點 p = L; //讓原本指向頭結點的 指針L 指向下一個結點 L = L->next; //釋放 指針p 指向結點的內存。 delete p; } return OK; } //清空單鏈表 Status ClearList(LinkList &L){ Lnode *p, *q; //讓指針p指向首元結點,即從首元結點開始清理,而非頭結點! p = L->next; while(p){ //指針q 指向 指針p 所指向結點的下一個結點 q = p->next; delete p; p=q; } L->next = NULL; return OK; } //求單鏈表的表長 int ListLength_L(LinkList L){ //定義一個 指針p 用以指向傳入的單鏈表 LinkList p; p=L->next; i=0; while(p){ i++; p=p->next; } return i; }
取值:取單鏈表中第 i 個元素的內容。
思考:順序表里如何找到第i個元素?L->elem[i-1];
算法思路(分別取出表中第3個元素和第15個元素)
① 先找到首元結點,定義一個指針p,讓其指向首元結點,即L->next,同時定義變量 j=1;
② 一直循環往下走,然后 j++,直到 j=3 時,獲取 p->data ,也就是指針P所指向結點的數據域;
鏈表查找數據時,從鏈表的頭指針出發,順着鏈域next逐個結點往下搜索,直至搜索到第i個結點為止,
因此鏈表不是隨機存取結構。
③ 如果要找第15個元素,再繼續的話,將指向空的,即沒有元素,因此不需要繼續向下尋找。
④ 注意 第幾個元素 限制,初始值只能為 1 ,小於這個,肯定就是錯的
算法步驟:
① 從第一個結點(L->next)順鏈掃描,用 指針p 指向當前掃描到的結點,p初值 p=L->next;
② j 做計數器,累計當前掃描過的結點數,j 初值為1;
③ 當 指針p 指向掃描到的下一結點時,計數器 j 加1;
④ 當 j == i 時,指針p 所指的結點就是要找的第 i 個結點。
代碼部分:
//獲取線性表 L 中的某個數據元素的內容,通過變量 e 返回 //為什么要用&,這里要改變指針 變量e 本身的值, //而非改變 e 所指內容的值! //從鏈表 L 中獲取第 i 個元素,元素的值由變量 e 返回。 Status GetElem_L(LinkList L, int i, ElemType &e){ //初始化,給 指針p 賦值,跳過頭結點,指向首元結點 p = L->next; //初始化,定義一個計數器,初始值為1 j = 1; //向后掃描,直到 指針p 指向第 i 個元素或 指針p 為空 //當 j==i 時,即找到此元素,因此 j<i 不再成立,循環停止 //當 i<1 時,即傳入 i 不合法,因此無法找到,也不成立 //當 p為NULL 時,即找到最后都沒找到,循環也停止 while(p && j<i){ p = p->next; //這里 j++ 和 ++j 都可以,對代碼功能不會造成影響 ++j; } //當指針為空,或者計數變量j大於i時,就證明運行出現了錯誤 if(!p || j>i){ return ERROR; } e = p->data; return OK; }
個人感覺以上代碼部分有點魔性,特此找到如下具有相同功能的代碼:
LNode *GetElem(LinkList L, int i){ //計數,初始值為1 int j=1; //頭指針L所指向結點的鏈域,也就是首元結點的地址賦值給 指針p LNode *p=L->next; //若i=0則返回頭結點 if(i==0){ return L; //若 i 無效,則返回NULL }else if(i<1){ return NULL; } //從首元結點開始找,查找到第 i 個結點。 while(p&&j<i){ p=p->next; j++; } //返回第 i 個結點的地址,若 i 大於表長則返回NULL return p; }