取單鏈表中第 i 個元素值


知識點回顧:

單鏈表類型定義:

//類型定義
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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM