01-02-5

1、單鏈表中按位置查找

a.原理

通過傳遞的位置,返回該位置對應的地址,放到主函數定義的指針變量中。

我們認為位置從:有數據的節點開始計數

即如下結構:

查找位置,就是返回該位置對應的空間地址。

b.代碼說明

Ⅰ.子函數名的說明

查找指定位置的元素的子函數,返回該位置對應的地址,即指針類型,所以返回值是結構體指針類型。

不需要修改鏈表中的數據,所以形參不需要引用。

用一個整型變量形參接收位置參數。

Ⅱ.定義結構體指針變量,使其指向第一個數據節點

代碼如下

LNode* p = L->next;//此時p指向第一個元素節點。L指向的是頭節點,使用->頭節點內部的next域,得到第一個元素節點的地址

Ⅲ.子函數內部的判斷

如果查找的位置是0,則默認返回的是頭節點,也就不需要操作了,直接將傳來的頭指針返回即可。頭指針內部放的就是頭節點對應的地址。

若是位置小于0,則表示查找的位置不合法,即返回NULL。

代碼如下

if (0 == i)//判斷變量和常量是否相等,通常將常量寫在左側
{return L;
}
if (i < 0)
{return NULL;
}

Ⅳ.利用循環,找到對應的位置

利用while循環,使指針不斷后移動,知道指向指定的位置即可。

循環的條件是:指針不為空,且當前位置小于指定的位置。

循環內執行的操作是:不斷的將指針p重新賦值為當前指針執行的空間中的next值,再進行位置的++操作。

當循環結束后,此時的p剛好指向指定的位置空間。

代碼如下

while (p && j < i)
{p = p->next;j++;
}

Ⅴ.循環結束后,返回指向指定位置的指針

代碼如下

return p;

Ⅵ.整體代碼如下

LinkList GetElem(LinkList L, int i)//我們認為位置從有數據的元素節點開始計數。
{int j = 1;LNode* p = L->next;//此時p指向第一個元素節點。L指向的是頭節點,使用->頭節點內部的next域,得到第一個元素節點的地址if (0 == i)//判斷變量和常量是否相等,通常將常量寫在左側{return L;}if (i < 0){return NULL;}while (p && j < i){p = p->next;j++;}return p;
}

2、單鏈表中按值查找

a.原理

利用循環,便利鏈表,在子函數中定義結構體指針變量,使其指向第一個數據節點,獲取該節點中的數據,與指定的數據進行相比:

若相等則返回該節點對應的地址;

若是不等,則將指針賦值為當前節點的next值,使其指向下一個節點。利用循環,再次比較。

b.子函數代碼說明

Ⅰ.子函數名的說明

最終返回的是該值所在的節點的地址,所以需要返回的是一個結構體指針類型:LinkList

因為不需要修改鏈表中的數據,所以不需要引用。

查找的值的類型必須與傳遞的值的類型一致,所以需要定義一個相同類型的形參進行接收。

代碼如下

LinkList LocateElem(LinkList L, ElemType e)

Ⅱ.在子函數內部定義一個結構體指針類型變量

使該指針變量指向第一個數據元素。

代碼如下

LinkList p = L->next;

Ⅳ.利用while循環進行遍歷鏈表

while循環的條件就是指針不為空。

在循環內判斷該指針對應的data域與指定的值是否相同,相同則返回該指針,不同則將指針賦值為當前指針的next域。再次循環。

代碼如下

while (p)
{if (p->data == e){return p;}p = p->next;
}

3、單鏈表插入元素

α.在中間插入元素

a.原理

申請新的節點空間,將插入的數據放到該空間的數據域中。

然后再找到插入的位置的地址,將申請的節點的next域賦值為找到的地址。(即實現原位置數據后移操作)

最后將存放找到的地址的變量重新賦值為剛申請的節點的地址。(即實現節點插入操作)

利用查找位置的函數,傳入的是該位置對應的下標,所以需要將位置-1,得到下標后再傳入。

查找位置的函數,返回的就是插入位置的前一個節點的地址,將返回的地址放到p指針中,通過p指針訪問next域,才能得到插入位置的地址。

向第i個位置插入數據,利用GetElem函數找到第i-1的位置的地址,而不是找到第i個位置的原因:

若是返回第i個位置地址,此時直接訪問data域,則會覆蓋原來的數據。

b.代碼說明

Ⅰ.子函數名的說明

調用該函數是否插入成功,所以返回一個bool類型,即返回值為bool類型。

不需要改變鏈表中的值,所以不需要引用鏈表。

用一個整型變量,用于存放插入的指定位置。

定義一個與插入類型相同的變量,用于接收插入的數據。

代碼如下

bool ListFrontInsert(LinkList L, int i, ElemType e)

插入到第i個位置,就必須拿到第i個位置的地址,第i個位置的地址放在第i-1節點的next域中。所以需要借助按位置查找函數,找到第i-1位置的節點對應的地址。

所以需要定義一個結構體節點指針,用于接收按位置查找的返回值,即插入位置的前一個位置的地址。

代碼如下:

LinkList p = GetElem(L, i - 1);

Ⅱ.找到插入位置i前一個位置的地址

找到插入位置的前一個節點的地址,利用GetElem函數即可。所以當向第i個位置插入數據時,就需要先找到第i-1位置對應的地址。GetElem函數返回的是指向指定位置的指針,所以我們要找前一個位置的指針時,傳入的數據需要-1

代碼如下

LinkList p = GetElem(L, i - 1);

此時返回的指針p,內部的地址就是插入位置的前一個節點的地址。

Ⅲ.判斷插入位置的前一個節點指針

若是為空,則返回false,不為空后才可以繼續插入。

代碼如下

if (NULL == p)
{return false;
}

Ⅳ.申請節點空間

代碼如下

LinkList s = (LNode*)malloc(sizeof(LNode));//為新插入的節點申請空間

Ⅴ.給新的節點數據域賦值

代碼如下

s->data = e;

Ⅵ.將插入的新節點的next域賦值為找到的地址next域:實現后移操作

代碼如下

s->next = p->next;

Ⅶ.將存放找到的地址的變量重新賦值為申請節點的地址

代碼如下

p->next = s;

Ⅷ.操作成功后返回true

代碼如下

return true;

Ⅸ.整體代碼如下

找到第i個位置,并返回指向該位置的指針

LinkList GetElem(LinkList L, int i)//我們認為位置從有數據的元素節點開始計數。
{int j = 1;LNode* p = L->next;//此時p指向第一個元素節點。L指向的是頭節點,使用->頭節點內部的next域,得到第一個元素節點的地址if (0 == i)//判斷變量和常量是否相等,通常將常量寫在左側{return L;}if (i < 0){return NULL;}while (p && j < i){p = p->next;j++;}return p;
}

向第i個位置插入數據

bool ListFrontInsert(LinkList L, int i, ElemType e)
{LinkList p = GetElem(L, i - 1);//這個p內部的是指向第i-1位置的地址,插入的是第i個位置if (NULL == p){return false;}LinkList s = (LNode*)malloc(sizeof(LNode));//為新插入的節點申請空間s->data = e;s->next = p->next;//實現后移操作p->next = s;//實現插入操作return true;
}

4、單鏈表刪除節點

a.原理

利用GetElem()函數,找到刪除位置的前驅節點,返回該前驅節點的地址,保存該節點中next域的地址。這個地址指向的就是要刪除的節點的地址。備份該節點的地址,將該節點中的next域的地址賦值到前驅節點的next域中,然后釋放保存的節點的地址(即要刪除的節點的地址,也就是前面備份的地址),再將原來用于備份該節點的地址的指針置空即可。

刪除第2個位置的節點,

第一步:先找到指向第一個位置的指針,利用GetElem函數查找即可。

備份第二個節點的地址,

第二步:再將第一個位置的next域賦值為第二個節點的next域值,

第三步:最后將釋放第二個節點即可,利用第一步備份的地址訪問到第二個節點。

若是不備份,則再第二步執行完后,會導致第二個節點的地址丟失,無法訪問和釋放第二個節點。

結構如下

若是不找到前驅節點的地址,則無法訪問到前驅節點的next域,即無法完成第二步操作。所以必須借助GetElem()函數,找到前驅節點的地址。

b.代碼說明

Ⅰ.頭文件的說明

返回一個bool類型,用于說明刪除成功與否。傳入進行刪除的鏈表名,一個記錄刪除位置的變量。

代碼如下

bool ListDelete(LinkList L, int i)

Ⅱ.找到刪除位置的前驅

代碼如下

LinkList p = GetElem(L, i - 1);//找到刪除位置的前驅節點

說明

此時的p指針,內部存放的就是指向刪除節點的前面節點的地址。該指針指向的空間內部的next域,就是要刪除的位置的節點對應的地址。

Ⅲ.判斷前驅節點的指針是否存在

代碼如下

if (NULL == p)//判斷前驅節點是否存在
{return false;
}

說明

只要在后面需要使用指針,訪問對應的域,都需要判斷該指針是否為空。

Ⅳ.判斷刪除的位置是否存在

代碼如下

LinkList q = p->next;//此時q指向的就是刪除位置的節點對應的地址
if (NULL == q)
{return false;//要刪除的位置不存在
}

說明

p指針指向的是前驅節點的地址,p->next指向的就是要刪除的節點的地址。將其放在指針變量q中。若q指針為空,則表示p指向的就是最后一個節點的地址,無法進行刪除操作。

Ⅴ.備份要刪除的節點的地址

代碼如下

LinkList q = p->next;//此時q指向的就是刪除位置的節點對應的地址

Ⅵ.進行斷鏈操作

代碼如下

p->next = q->next;//斷鏈

Ⅶ.釋放要刪除的節點空間

代碼如下

free(q);//釋放q指向的地址,即對應節點的空間 q = NULL;//將q這個指針置空

free()函數只是釋放該指針指向的空間,沒有改變該指針的指向,所以還需要將該指針置空,才算徹底結束。

Ⅷ.返回成功true

代碼如下

return true;

Ⅸ.整體代碼如下

bool ListDelete(LinkList L, int i)
{LinkList p = GetElem(L, i - 1);//找到刪除位置的前驅節點if (NULL == p->next)//預防刪除的位置是否存在{return false;}LinkList q = p->next;//此時q指向的就是刪除位置的節點對應的地址p->next = q->next;//斷鏈free(q);//釋放q指向的地址,即對應節點的空間q = NULL;//將q這個指針置空return true;
}

5、雙向鏈表

a.雙向鏈表的說明

結構如下圖

文字說明

相對于單鏈表,雙鏈表比單鏈表多一個指針,用于指向該節點的前驅節點,即內部放的是前驅節點的地址。

單鏈表中的指針放的是該節點的后繼節點的地址。

b.結構體定義如下

typedef struct DNode
{ElemType data;//數據域struct DNode* prior;//前驅指針struct DNode* next;//后繼指針
}DNode,*DLinkList;//進行重命名結構體和結構體指針

c.插入節點的說明

結構如下

文字說明

申請新的空間,并將該空間的地址放到結構體指針S中。

將新申請的節點,插入到第i個位置,先找到第i-1位置的節點,并將該節點的地址放到結構體指針P中。

①將新申請的節點的next賦值為前驅節點的next中的值,代碼如下:S->next=P->next

②將后繼節點的prior域重新賦值為新申請的節點地址,代碼如下:P->next->prior=S

此時①②,實現了后繼節點可以指向申請的空間,申請的空間也可指向后繼節點:即新申請的空間的next域放的是后繼節點的地址,后繼節點的piror域放的是申請的空間的地址。

③將前驅節點的地址放到新申請的空間的prior域中,代碼如下:S->prior=P

④將新申請的空間的地址放到前驅節點的next域中,代碼如下:P->next=S

此時③④,實現了前驅節點的next域可以指向新申請的空間,新申請的空間的prior域可以指向前驅節點。即前驅節點空間中的next域放的是新申請的空間地址,新申請的空間的prior域放的是前驅節點的地址。

d.頭插法新建雙向鏈表

頭插法的邏輯說明

新的節點的prior指向頭節點;

新的節點的next指向頭節點后面的一個節點;

頭節點的next指向新的節點;

頭節點后面的節點的prior指向新的節點。

即第一個申請的數據節點,再鏈表形成后會放到最后一個。(或者說每一個申請的數據節點,都直接放在頭節點后面)這樣的插入稱為頭插法。

Ⅰ.子函數名的說明

代碼如下

DLinkList Dlist_head_insert(DLinkList& DL)

說明

返回一個結構體指針,函數參數引用主函數中的頭指針DL

Ⅱ.新建結構體指針變量,用于接收申請的新空間地址

代碼如下

DNode* s; int x;

說明

整型變量x用于存放到節點數據域中的數據。

Ⅲ.申請新的節點空間

代碼如下

DL = (DLinkList)malloc(sizeof(DNode));

說明

malloc()函數用于申請空間,sizeof(DNode):用于計算申請的空間大小,單位是字節。內部是結構體名,表示申請和該結構體定義時一樣的空間。將申請的空間強制類型轉換為結構體指針類型,并將其保存在結構體指針變量DL中。

DL是頭指針,此處申請的空間節點是頭節點。

Ⅳ.將新申請的空間置空

代碼如下

DL->prior = NULL; DL->next = NULL;

說明

將指向前驅節點和指向后繼節點的指針域置空。

Ⅴ.讀取數據,利用循環進行申請空間并建立鏈表

代碼如下

scanf("%d", &x);//從標準輸入讀取數據,放到變量中暫時存儲
//3 4 5 6 7 9999
while (x != 9999)
{s = (DLinkList)malloc(sizeof(DNode));//此時申請的節點是數據節點s->data = x;s->next = DL->next;//①if (DL->next != NULL){DL->next->prior = s;//④}s->prior = DL;//使插入的節點指向前一個節點②DL->next = s;//使原來的節點指向新插入的節點③scanf("%d", &x);//繼續讀取數據
}

新申請第一個數據節點時結構如下:

第一個數據節點有三步:

①新的節點的next域放的是前一個節點的next中的內容。

②新的節點的prior域放的是頭節點對應的地址,指向頭節點。

③前一個節點的next域放的是新的節點的地址,指向新的節點對應的空間。

申請第二個及以后的數據節點時的結構如下:

總結:

①新申請的節點的next內是頭節點后面的節點地址,指向頭節點后面的節點

④頭節點后面的一個節點的prior指向新申請的節點

②新申請的節點的prior內是頭節點,

③頭節點的next指向新申請的節點。

Ⅵ.返回頭指針即可

代碼如下

return DL;

Ⅶ.整體代碼如下

DLinkList Dlist_head_insert(DLinkList& DL)
{DNode* s; int x;DL = (DLinkList)malloc(sizeof(DNode));//帶頭節點的鏈表,此處的節點是頭節點,DL指向頭節點DL->prior = NULL;DL->next = NULL;scanf("%d", &x);//從標準輸入讀取數據,放到變量中暫時存儲//3 4 5 6 7 9999while (x != 9999){s = (DLinkList)malloc(sizeof(DNode));//此時申請的節點是數據節點s->data = x;s->next = DL->next;//若是DL->next內部是一個地址,則表示將該地址放到s->next中,即s->next訪問的是存放在DL->next內部的地址對應的空間if (DL->next != NULL){DL->next->prior = s;}s->prior = DL;//使插入的節點指向前一個節點DL->next = s;//使原來的節點指向新插入的節點scanf("%d", &x);//繼續讀取數據}return DL;
}

e.雙鏈表打印

代碼同單鏈表一致

Ⅰ.子函數名的說明

代碼如下

void PrintDList(DLinkList DL)

說明

不需要返回,不需要引用,直接用形參接收即可

Ⅱ.改變頭指針指向,使其指向第一個數據節點

代碼如下

DL = DL->next;//改變頭指針指向,使其指向第一個數據節點 說明

此時的DL指針指向第一個數據節點

Ⅲ.利用循環,先輸出,在改變指針

代碼如下

while (DL != NULL){printf("%3d", DL->data);DL = DL->next;}

說明

因為在開始已經使DL指向用一個數據節點的地址,可以直接訪問,所以循環處直接判斷該指針是否為空即可

不為空時,先輸出,直接訪問進行輸出即可,再改變DL,使其指向下一個節點的地址,訪問當前節點的next域即可。

Ⅳ.整體代碼如下

void PrintDList(DLinkList DL)
{DL = DL->next;//改變頭指針指向,使其指向第一個數據節點while (DL != NULL){printf("%3d", DL->data);DL = DL->next;}printf("\n");
}

f.尾插法

結構說明

尾插法:每次新申請的節點,放在最后。

雙鏈表的尾插法步驟說明:

先申請一個頭節點,定義尾指針變量,初始化時令尾指針指向頭節點。然后借助循環,在循環中申請新的數據節點,存放數據域,然后將尾指針的next域賦值為新的節點,新的節點的prior賦值為尾指針指向的地址,最后將尾指針賦值為新節點即可。離開循環后,將尾指針指向的節點的next域置空即可。

總結:最后形成的鏈表:頭節點的prior為NULL,尾節點的next為NULL。

Ⅰ.子函數名的說明

代碼如下

DLinkList Dlist_tail_insert(DLinkList& DL)

說明

返回一個結構體指針類型,引用主函數的頭指針變量。

Ⅱ.定義變量,用于讀取輸入的數據域的值

代碼如下

int x

Ⅲ.申請頭節點的空間,放到頭指針中

代碼如下

DL=(DLinkList)malloc(sizeof(DNode))

說明

利用malloc()申請新的空間,空間大小利用sizeof()計算一個結構體大小即可。

malloc()申請的空間無類型,需要強制類型轉換為結構體指針類型后再賦值到頭指針變量中。

Ⅳ.定義兩個指針變量

代碼如下

DNode*s,*r=DL;

說明

*s指針,用于接收新申請的節點空間;*r指針,用于記錄尾指針。

注意:最初的尾指針,和頭指針保持一致,指向第一個頭節點。

Ⅴ.將頭節點的prior置空

代碼如下

DL->prior=NULL;

Ⅵ.讀取數據

代碼如下

scanf("%d",&x);

說明

后面將x變量中的數據放到數據域中即可。

Ⅶ.利用循環將數據放到數據域中,并不斷申請新的節點

代碼如下

while (x != 9999)
{s = (DLinkList)malloc(sizeof(DNode));//申請的第一個數據節點s->data = x;r->next = s;s->prior = r;r = s;//r指向新的表尾節點scanf("%d", &x);//繼續讀取新的數據
}

說明

在循環內,先申請一個節點空間,放到指針變量s中。然后給該節點的數據域進行賦值為x變量。

r指針開始指向的是頭節點,給頭節點的next賦值為新申請的節點地址。

將新申請的節點的prior域賦值為前一個節點的地址,也就是r指針保存的。

然后再使r指針指向最后一個節點,也就是新申請的節點s。

Ⅷ.循環結束后,將尾節點的next域賦值為空

代碼如下

r->next = NULL;//尾節點的next指針賦值為NULL

說明

r指針在每次循環結束時,都指向最后一個節點,所以在循環外,借助r指針,直接訪問next域即可。

Ⅸ.最后返回頭指針即可

代碼如下

return DL;

Ⅹ.整體代碼如下

DLinkList Dlist_tail_insert(DLinkList& DL)
{int x;//用于臨時存放數據域的數據DL = (DLinkList)malloc(sizeof(DNode));DNode* s, * r;//r代表尾指針DL->prior = NULL;//3 4 5 6 7 9999scanf("%d", &x);while (x != 9999){s = (DLinkList)malloc(sizeof(DNode));//申請的第一個數據節點s->data = x;r->next = s;s->prior = r;r = s;//r指向新的表尾節點scanf("%d", &x);//繼續讀取新的數據}r->next = NULL;//尾節點的next指針賦值為NULLreturn DL;//返回頭指針
}

g.雙鏈表的查找節點

等同于單鏈表的查找節點

h.插入到指定位置

Ⅰ.子函數名的說明

代碼如下

bool DListFrontInsert(DLinkList DL, int i, ElemType e)

說明

返回bool類型,用于說明查找是否成功;

使用形參接收頭指針DL即可;

定義整型變量,用于記錄插入的位置;

定義相同類型的變量,用于臨時保存插入的數據。

Ⅱ.找到插入位置的前驅節點

代碼如下

DLinkList p = GetElem(DL, i - 1);//找到該位置的前驅節點,返回的是前驅節點的地址指針

說明

找前驅節點是為了修改前驅節點的next域,保證插入后仍是一條完整的鏈表。

此時的p指針,指向的是插入位置的前驅節點。

Ⅲ.判斷插入位置的前驅節點是否存在

代碼如下

if (NULL == p)//注意:插入的位置可以不存在,但是插入的前驅節點一定存在:即插在最后一個節點的后面
{return false;//若是插入位置的前驅節點不存在,才報錯
}

說明

若是插入位置的前驅節點不存在,則不能插入。插入的位置可以不存在,此時表示插入在最后一個節點的后面。

Ⅳ.申請節點空間

代碼如下

DLinkList s = (DLinkList)malloc(sizeof(DNode));

說明

此時的s指針,指向新申請的節點。

Ⅴ.插入節點

代碼如下

s->data = e;//存放數據
s->next = p->next;//實現新申請的節點指向后面的節點
p->next->prior = s;//實現原位置的節點指向新申請的節點
s->prior = p;//實現新申請的節點指向前驅節點
p->next = s;//實現前驅節點指向新申請的節點

說明

即需要完成:新申請的節點的next域存放原位置的空間地址;

改變原位置的節點的前面指向,使其指向新的節點;

此時完成新申請的節點與后面的節點相互指向。

在完成新申請的節點prior域存放前驅節點的地址;

前驅節點的next域存放新申請的節點的地址;

此時完成新申請的節點與前面的節點相互指向。

Ⅵ.返回true

代碼如下

return true

Ⅶ.整體代碼如下

bool DListFrontInsert(DLinkList DL, int i, ElemType e)
{DLinkList p = GetElem(DL, i - 1);//找到該位置的前驅節點,返回的是前驅節點的地址指針if (NULL == p)//注意:插入的位置可以不存在,但是插入的前驅節點一定存在:即插在最后一個節點的后面{return false;//若是插入位置的前驅節點不存在,才報錯}DLinkList s = (DLinkList)malloc(sizeof(DNode));s->data = e;//存放數據s->next = p->next;//實現新申請的節點指向后面的節點p->next->prior = s;//實現原位置的節點指向新申請的節點s->prior = p;//實現新申請的節點指向前驅節點p->next = s;//實現前驅節點指向新申請的節點return true;
}

Ⅷ.插入節點的說明

參考本文件中:c.插入節點的說明

i.刪除節點

Ⅰ.子函數名的說明

代碼如下

bool DListDelete(DLinkList DL, int i)

說明

返回bool類型,用于說明刪除是否成功;

使用普通形參,用于接收頭文件;

定義整型變量,用于記錄刪除的位置。

Ⅱ.找到刪除位置的前驅節點

代碼如下

DLinkList p = GetElem(DL, i - 1);//找到刪除位置的前驅節點

說明

利用GetElem()函數找到刪除位置的前驅節點,此時的p指針指向的是前驅節點

Ⅲ.判斷前驅節點是否存在

代碼如下

if (NULL == p)
{return false;
}

說明

p指針此時指向的是前驅節點的空間

Ⅳ.判斷刪除位置的節點是否存在

代碼如下

DLinkList q = p->next;//此時q指向刪除位置的空間
if (NULL == q)//判斷刪除的位置是否存在
{return false;
}

說明

定義結構體類型指針q,用于指向刪除位置的節點。因為p指針指向的是前驅節點,前驅節點的next域放的就是刪除位置的地址,直接訪問即可。所以此時的q指針,就是指向刪除位置的節點。利用if語句,判斷該節點是否存在,若是不存在直接返回false即可。

q指針,也是用于備份刪除位置的地址,否則后面修改后,無法訪問到刪除的空間地址,進而無法釋放該空間。

Ⅴ.進行斷鏈操作

代碼如下

p->next = q->next;//斷鏈
if (q->next != NULL)
{q->next->prior = p;
}

說明

q指針指向的是刪除位置的節點,p指針指向的是前驅節點。p->next=q->next:此句用于實現讓前驅節點直接訪問到后面的節點,即跳過刪除的節點。

若是后繼節點存在,即不為空,則將其的prior指向前驅節點即可,即if語句中就是用于實現此處的代碼。

Ⅵ.釋放指向該空間的指針

代碼如下

free(q);

說明

也就是釋放前面備份的空間地址

Ⅶ.將備份指針置空

代碼如下

q=NULL;

Ⅷ.返回true

代碼如下

return true;

Ⅸ.整體代碼如下

bool DListDelete(DLinkList DL, int i)
{DLinkList p = GetElem(DL, i - 1);//找到刪除位置的前驅節點if (NULL == p){return false;}DLinkList q = p->next;//此時q指向刪除位置的空間if (NULL == q)//判斷刪除的位置是否存在{return false;}p->next = q->next;//斷鏈if (q->next != NULL){q->next->prior = p;}free(q);//釋放對應節點的空間q = NULL;return true;
}

6.循環單鏈表和循環雙鏈表的概念

a.循環單鏈表

循環單鏈表就是將最后一個節點的next賦值為頭指針。

即尾指針直接訪問next域,賦值為頭指針即可。

b.循環雙鏈表

循環雙鏈表就是將最后一個節點的next域賦值為頭指針;

將頭結點的prior域賦值為尾指針。

7.靜態鏈表

即一個結構體數組,結構體包含數據域和一個整型變量,這個整型變量用于記錄后面一個節點對應的下標,通過下標訪問下一個節點。

8.總結

鏈表只有在頭插法、尾插法改變頭指針的值的時候,才需要借助引用,其他刪除、插入都不需要引用。

創建頭指針,可以初始化為NULL

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11624.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11624.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11624.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

H5嵌入原生----兼容安卓與ios

主要分UI展示&#xff0c;鍵盤&#xff0c;輸入框等等。解決bug最苦惱的問題不是沒有解決方案&#xff0c;而是你沒有找到真正的原因。再就是現象難以重現&#xff0c;每次都要發布代碼&#xff0c;然后到手機app中去測試&#xff0c;模擬。這些地方會耗費大量的精力。 一、UI…

【軟設】常見易錯題匯總

目錄 計算機系統基礎 程序語言基礎 數據結構 算法設計與分析 計算機網絡與信息安全 軟件工程基礎 開發方法&#xff08;結構化與面向對象&#xff09; 數據庫 操作系統 知識產權相關的法律法規 &#x1f92f;&#x1f92f;&#x1f92f;&#x1f92f;&#x1f92f;&#x1f9…

《系統架構設計師教程(第2版)》第10章-軟件架構的演化和維護-07-軟件架構維護

文章目錄 1. 軟件架構知識管理1.1 概念1.2 架構知識的獲取1.3 作用1.4 架構知識管理的現狀 2 軟件架構修改管理3 軟件架構版本管理4. 示例4.1 背景4.2 數據獲取4.3 數據計算4.4 結果分析4.4.1 圈復雜度 (CCN)4.4.2 扇入扇出度 (FFC)4.4.3 模塊間耦合度 (CBO)4.4.4 模塊的響應 (…

mysql group by 細節介紹

mysql中group by的用法是配合聚合函數&#xff0c;利用分組信息進行統計&#xff0c;語句如“select name,sum(id) from test group by name,number”。 先來看下表1&#xff0c;表名為test&#xff1a; 執行如下SQL語句&#xff1a; SELECT name FROM test GROUP BY name 你…

OFDM802.11a的FPGA實現(十四)data域的設計優化,擠掉axi協議傳輸中的氣泡

原文鏈接&#xff08;相關文章合集&#xff09;&#xff1a;OFDM 802.11a的xilinx FPGA實現 目錄 1.前言 2.data域的時序要求 3.Debug 1.前言 前面12篇文章詳細講述了&#xff0c;OFDM 802.11a發射部分data域的FPGA實現和驗證&#xff0c;今天對data域的設計做一個總結。在…

electron 多窗口 vuex/pinia 數據狀態同步簡易方案(利用 LocalStorage)

全局 stroe 添加 mutations 狀態同步方法 // 用于其他窗口同步 vuex 中的 DeviceTcpDataasyncDeviceTcpData(state: StateType, data: any) {state.deviceTcpData data},App.vue 里 onMounted(() > {console.log("App mounted");/*** vuex 多窗口 store 同步*//…

springboot306基于Java的民宿管理系統(源碼+包運行+配套LW+技術指導)

項目描述 臨近學期結束&#xff0c;開始畢業設計制作&#xff0c;你還在做java程序網絡編程&#xff0c;期末作業&#xff0c;老師的作業要求覺的困難嗎?不知道畢業設計該怎么辦?網頁功能的數量是否太多?沒有合適的類型或系統?等等。今天給大家介紹一篇基于Java的民宿管理…

python篇-cmd 執行pip命令失敗,但執行pyhon命令正常

當你在CMD中可以正常執行python命令&#xff0c;但執行pip命令失敗時&#xff0c;這通常意味著pip沒有被正確地添加到系統的環境變量中。這里有一些步驟來解決這個問題&#xff1a; 檢查環境變量&#xff1a; 打開系統的環境變量設置&#xff08;右擊“此電腦”>“屬性”>…

CoSeg: Cognitively Inspired Unsupervised Generic Event Segmentation

名詞解釋 1.特征重建 特征重建是一種機器學習中常用的技術&#xff0c;通常用于自監督學習或無監督學習任務。在特征重建中&#xff0c;模型被要求將輸入數據經過編碼器&#xff08;encoder&#xff09;轉換成某種表示&#xff0c;然后再經過解碼器&#xff08;decoder&#x…

c/c++對于char*的理解(聯合string容器)

在C和C中&#xff0c;char*是一個指向字符&#xff08;char&#xff09;的指針。它經常被用來處理C風格的字符串&#xff0c;這種字符串是以空字符&#xff08;\0&#xff09;結尾的字符數組。以下是關于char*的一些關鍵點&#xff1a; C風格的字符串&#xff1a; C風格的字符…

升級Microsoft 365后,SAP GUI中無法打開Excel的解決方案

最近&#xff0c;我們遇到了一個棘手的問題&#xff0c;一位客戶在升級到Microsoft 365后&#xff0c;無法在SAP GUI中打開Excel。這個問題不僅影響了工作效率&#xff0c;也給用戶的日常操作帶來了不便。在本文中&#xff0c;我們將探討問題的成因&#xff0c;并提供一種解決方…

泛微E9開發 添加多個多選框,實現單選框的效果

利用多個多選框實現單選框的效果 1、功能背景2、展示效果3、實現效果 1、功能背景 如下圖所示&#xff0c;在表單中新增四個“選擇框-復選框”類型的字段&#xff0c;并且設置其中的選項&#xff0c;每個多選框都只有一個選項&#xff0c;通過代碼塊實現單選框的效果 1.顯示模…

鄧閑小——生存、生活、生命|真北寫作

人生有三個層次∶生存、生活、生命。 生存就是做必須做的事。生存的模式是鄧&#xff0c;是交易&#xff0c;是買賣。別人需要的東西&#xff0c;你生產出來&#xff0c;賣給他。哪怕這個東西沒啥用&#xff0c;也可以賣&#xff0c;情緒也可以賣。你需要的東西&#xff0c;你花…

分布式與一致性協議之POW算法

POW算法 概述 談起比特幣&#xff0c;你應該并不陌生。比特幣是基于區塊鏈實現的&#xff0c;而區塊鏈運行在因特網上&#xff0c;這就存在有人試圖作惡的情況。有些讀者可能已經發現了&#xff0c;口信消息型拜占庭問題之解、PBFT算法雖然能防止壞人作惡&#xff0c;但只能防…

代碼隨想錄算法訓練營第二十三天 | 530.二叉搜索樹的最小絕對差、501.二叉搜索樹中的眾數、236. 二叉樹的最近公共祖先

目錄 530.二叉搜索樹的最小絕對差 思路 代碼 501.二叉搜索樹中的眾數 思路 代碼 236. 二叉樹的最近公共祖先 思路 代碼 530.二叉搜索樹的最小絕對差 需要領悟一下二叉樹遍歷上雙指針操作&#xff0c;優先掌握遞歸 題目鏈接/文章講解&#xff1a;代碼隨想錄 視頻講解…

Java Spring的定時任務的配置和使用

在Spring框架中&#xff0c;配置和使用定時任務主要涉及Scheduled注解以及Spring的異步任務執行能力。以下是詳細步驟&#xff1a; 1. 引入依賴 對于Spring Boot項目&#xff0c;通常已經包含了Spring框架&#xff0c;因此不需要額外添加定時任務的依賴。如果使用的是Spring框…

AI大模型測評系統opencompass源碼解析

1 注冊器(Registry) 為了管理功能相似的模塊,MMEngine實現了注冊器。注冊器可以被視作這些類或函數的抽象。例如注冊器 MODELS 可以被視作所有模型的抽象。 1.1 什么是注冊器 MMEngine 實現的注冊器可以看作一個映射表和模塊構建方法(build function)的組合。 映射表:…

八、e2studio VS STM32CubeIDE之內存使用情況窗口

目錄 一、概述/目的 二、STM32CubeIDE Build Analyzer 三、e2studio Memory Usage 八、e2studio VS STM32CubeIDE之內存使用情況窗口 一、概述/目的 1、嵌入開發最大特點之一就是資源受限&#xff0c;關注芯片資源使用詳情是優秀工程師的技能之一 2、Keil和IAR都不支持內存…

CTFshow 信息搜集

第一題1 進入靶場 直接看源碼發現flag 第二題 1 按右鍵沒辦法看源碼 按ctrlu可以查看源碼 第三題 0 查看源碼 發現還是什么都沒有 用bp抓包發現flag 第四題1 直接進robots.txt 訪問flagishere.txt獲得flag 第五題 0 提示了phps源碼泄露 用目錄掃描工具沒掃出來 看wp 發現有…

網絡編程套接字詳解

目錄 1. 預備介紹 2.網絡字節序 3.udp網絡程序 4.地址轉換函數 5.udp網絡編程 1.預備介紹 1.1源IP地址和目標IP地址 舉個例子: 從北京出發到上海旅游, 那么源IP地址就是北京, 目標IP地址就是上海. 1.2 端口號 作用: 標識一個進程, 告訴OS這個數據交給那個進程來處理; (1)…