两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

20211102藍橋杯培訓(xùn)

【狀態(tài):    內(nèi)部  已結(jié)束
開始時間: 2021-11-02 12:00:00
  
結(jié)束時間: 2021-11-04 00:00:00
  
服務(wù)器時間:

簡介

比賽名稱: 20211102藍橋杯培訓(xùn)

比賽類型: 內(nèi)部(受邀或輸入密碼才能參賽)

比賽狀態(tài): 已結(jié)束

比賽時間: 開始于 2021-11-02 12:00:00,至 2021-11-04 00:00:00結(jié)束。

公告


線性結(jié)構(gòu):有且只有一個根節(jié)點,且每個節(jié)點最多有一個直接前驅(qū)和一個直接后繼的非空數(shù)據(jù)結(jié)構(gòu)

非線性結(jié)構(gòu):不滿足線性結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)

鏈表(單向鏈表的建立、刪除、插入、打?。?/p>

1、鏈表一般分為: 

  單向鏈表

    雙向鏈表

    環(huán)形鏈表

2、基本概念

鏈表實際上是線性表的鏈?zhǔn)酱鎯Y(jié)構(gòu),與數(shù)組不同的是,它是用一組任意的存儲單元來存儲線性表中的數(shù)據(jù),存儲單元不一定是連續(xù)的,

且鏈表的長度不是固定的,鏈表數(shù)據(jù)的這一特點使其可以非常的方便地實現(xiàn)節(jié)點的插入和刪除操作

鏈表的每個元素稱為一個節(jié)點,每個節(jié)點都可以存儲在內(nèi)存中的不同的位置,為了表示每個元素與后繼元素的邏輯關(guān)系,以便構(gòu)成 “一個節(jié)點鏈著一個節(jié)點” 的鏈?zhǔn)酱鎯Y(jié)構(gòu),

除了存儲元素本身的信息外,還要存儲其直接后繼信息,因此,每個節(jié)點都包含兩個部分,第一部分稱為鏈表的數(shù)據(jù)區(qū)域,用于存儲元素本身的數(shù)據(jù)信息,這里用 data 表示,

它不局限于一個成員數(shù)據(jù),也可是多個成員數(shù)據(jù),第二部分是一個結(jié)構(gòu)體指針,稱為鏈表的指針域,用于存儲其直接后繼的節(jié)點信息,這里用 next 表示,

next 的值實際上就是下一個節(jié)點的地址,當(dāng)前節(jié)點為末節(jié)點時,next 的值設(shè)為空指針

1 struct link2 {3     int data;4     struct link *next;5 };

像上面這種只包含一個指針域、由 n 個節(jié)點鏈接形成的鏈表,就稱為線型鏈表或者單向鏈表,鏈表只能順序訪問,不能隨機訪問,鏈表這種存儲方式最大缺點就是容易出現(xiàn)斷鏈,

一旦鏈表中某個節(jié)點的指針域數(shù)據(jù)丟失,那么意味著將無法找到下一個節(jié)點,該節(jié)點后面的數(shù)據(jù)將全部丟失

3、鏈表與數(shù)組比較

數(shù)組(包括結(jié)構(gòu)體數(shù)組)的實質(zhì)是一種線性表的順序表示方式,它的優(yōu)點是使用直觀,便于快速、隨機地存取線性表中的任一元素,但缺點是對其進行 插入和刪除操作時需要移動大量的數(shù)組元素,同時由于數(shù)組屬于靜態(tài)內(nèi)存分配,定義數(shù)組時必須指定數(shù)組的長度,程序一旦運行,其長度就不能再改變,實際使用個數(shù)不能超過數(shù)組元素最大長度的限制,否則就會發(fā)生下標(biāo)越界的錯誤,低于最大長度時又會造成系統(tǒng)資源的浪費,因此空間效率差

4、單向鏈表的建立


1 #include


 

上面的代碼使用了三個函數(shù) AppendNode、DisplyNode、DeletMemory

struct link *AppendNode (struct link *head);(函數(shù)作用:新建一個節(jié)點并添加到鏈表末尾,返回添加節(jié)點后的鏈表的頭指針)

void DisplyNode (struct link *head);(函數(shù)功能:顯示鏈表中所有節(jié)點的節(jié)點號和該節(jié)點中的數(shù)據(jù)項的內(nèi)容)

void DeletMemory (struct link *head);(函數(shù)功能:釋放 head 所指向的鏈表中所有節(jié)點占用的內(nèi)存)

(還使用了 malloc 函數(shù)和 free 函數(shù))

 

5、malloc 函數(shù)

作用:用于分配若干字節(jié)的內(nèi)存空間,返回一個指向該內(nèi)存首地址的指針,若系統(tǒng)不能提供足夠的內(nèi)存單元,函數(shù)將返回空指針 NULL,函數(shù)原型為 void *malloc (unsigned int size)

其中 size 是表示向系統(tǒng)申請空間的大小,函數(shù)調(diào)用成功將返回一個指向 void 的指針(void * 指針是 ANSIC 新標(biāo)準(zhǔn)中增加的一種指針類型,

具有一般性,通常稱為通用指針或者無類型的指針)常用來說明其基類型未知的指針,即聲明了一個指針變量,但未指定它可以指向哪一種基類型的數(shù)據(jù),

因此,若要將函數(shù)調(diào)用的返回值賦予某個指針,則應(yīng)先根據(jù)該指針的基類型,用強轉(zhuǎn)的方法將返回的指針值強轉(zhuǎn)為所需的類型,然后再進行賦值

 1 int *pi; 2 pi = (int *)malloc(4); 

其中 malloc(4)表示申請一個大小為 4 字節(jié)的內(nèi)存,將 malloc(4)返回值的 void * 類型強轉(zhuǎn)為 int * 類型后再賦值給 int 型指針變量 pi,即用 int 型指針變量 pi 指向這段存儲空間的首地址

若不能確定某種類型所占內(nèi)存的字節(jié)數(shù),則需使用 sizeof()計算本系統(tǒng)中該類型所占的內(nèi)存字節(jié)數(shù),然后再用 malloc()向系統(tǒng)申請相應(yīng)字節(jié)數(shù)的存儲空間

pi = (int *)malloc(sizeof(int));

6、free 函數(shù)

釋放向系統(tǒng)動態(tài)申請的由指針 p 指向的內(nèi)存存儲空間,其原型為:Void free (void *p); 該函數(shù)無返回值,唯一的形參 p 給出的地址只能由 malloc()和 calloc()申請內(nèi)存時返回的地址,

該函數(shù)執(zhí)行后,將以前分配的指針 p 指向的內(nèi)存返還給系統(tǒng),以便系統(tǒng)重新分配

 為什么要用 free 釋放內(nèi)存

(在程序運行期間,用動態(tài)內(nèi)存分配函數(shù)來申請的內(nèi)存都是從堆上分配的,動態(tài)內(nèi)存的生存期有程序員自己來決定,使用非常靈活,但也易出現(xiàn)內(nèi)存泄漏的問題,

為了防止內(nèi)存泄漏的發(fā)生,程序員必須及時調(diào)用 free()釋放已不再使用的內(nèi)存)

7、單向鏈表的刪除操作

刪除操作就是將一個待刪除的節(jié)點從鏈表中斷開,不再與鏈表的其他節(jié)點有任何聯(lián)系

需考慮四種情況:

  1. 若原鏈表為空表,則無需刪除節(jié)點,直接退出程序

  2. 若找到的待刪除節(jié)點 p 是頭節(jié)點,則將 head 指向當(dāng)前節(jié)點的下一個節(jié)點(p->next),即可刪除當(dāng)前節(jié)點

   3. 若找到的待刪除節(jié)點不是頭節(jié)點,則將前一節(jié)點的指針域指向當(dāng)前節(jié)點的下一節(jié)點(pr->next = p->next),即可刪除當(dāng)前節(jié)點,當(dāng)待刪除節(jié)點是末節(jié)點時,

由于 p->next 值為 NULL,因此執(zhí)行 pr->next = p->next 后,pr->next 的值也變成 NULL,從而使 pr 所指向的節(jié)點由倒數(shù)第 2 個節(jié)點變成了末節(jié)點

  4. 若已搜索到表尾(p->next == NULL),仍未找到待刪除節(jié)點,則顯示 “未找到”,注意:節(jié)點被刪除后,只是將它從鏈表中斷開而已,它仍占用著內(nèi)存,必須釋放其所占的內(nèi)存,否則將出現(xiàn)內(nèi)存泄漏

(頭結(jié)點不是頭指針,注意兩者區(qū)別)

 

8、頭節(jié)點和頭指針

頭指針存儲的是頭節(jié)點內(nèi)存的首地址,頭結(jié)點的數(shù)據(jù)域可以存儲如鏈表長度等附加信息,也可以不存儲任何信息

    參考鏈接 --- 頭指針和頭節(jié)點:https://www.cnblogs.com/didi520/p/4165486.html

                  https://blog.csdn.net/qq_37037492/article/details/78453333

                   https://www.cnblogs.com/marsggbo/p/6622962.html

                  https://blog.csdn.net/hunjiancuo5340/article/details/80671298

 


 

(圖片出處:https://blog.csdn.net/hunjiancuo5340/article/details/80671298)

值得注意的是:

  1. 無論鏈表是否為空,頭指針均不為空。頭指針是鏈表的必要元素

  2. 鏈表可以沒有頭節(jié)點,但不能沒有頭指針,頭指針是鏈表的必要元素

   3. 記得使用 free 釋放內(nèi)存

單向鏈表的刪除操作實現(xiàn)

 


1 struct link *DeleteNode (struct link *head, int nodeData) 2 { 3     struct link *p = head, *pr = head; 4  5     if (head == NULL) 6     { 7         printf("Linked table is empty!\n"); 8         return 0; 9     }10     while (nodeData != p->data && p->next != NULL)11     {12         pr = p;            /* pr保存當(dāng)前節(jié)點 */13         p = p->next;    /* p指向當(dāng)前節(jié)點的下一節(jié)點 */14     }15     if (nodeData == p->data)16     {17         if (p == head)    /* 如果待刪除為頭節(jié)點 (注意頭指針和頭結(jié)點的區(qū)別)*/18         {19             head = p->next;20         }21         else            /* 如果待刪除不是頭節(jié)點 */22         {23             pr->next = p->next;24         }25         free(p);        /* 釋放已刪除節(jié)點的內(nèi)存 */26     }27     else            /* 未發(fā)現(xiàn)節(jié)點值為nodeData的節(jié)點 */28     {29         printf("This Node has not been found");30     }31 32     return head;33 }


 

9、單向鏈表的插入

向鏈表中插入一個新的節(jié)點時,首先由新建一個節(jié)點,將其指針域賦值為空指針(p->next = NULL),然后在鏈表中尋找適當(dāng)?shù)奈恢脠?zhí)行節(jié)點的插入操作,

此時需要考慮以下四種情況:

    1. 若原鏈表為空,則將新節(jié)點 p 作為頭節(jié)點,讓 head 指向新節(jié)點 p(head = p)

      2. 若原鏈表為非空,則按節(jié)點值的大?。僭O(shè)節(jié)點值已按升序排序)確定插入新節(jié)點的位置,若在頭節(jié)點前插入新節(jié)點,則將新節(jié)點的指針域指向原鏈表的頭節(jié)點(p->next = head),且讓 head 指向新節(jié)點(head =p)

    3. 若在鏈表中間插入新節(jié)點,則將新節(jié)點的指針域之下一節(jié)點(p->next = pr -> next),且讓前一節(jié)點的指針域指向新節(jié)點(pr->next = p)

    4. 若在表尾插入新節(jié)點,則末節(jié)點指針域指向新節(jié)點(p->next = p)

單向鏈表的插入操作實現(xiàn)

 


1 /* 函數(shù)功能:向單向鏈表中插入數(shù)據(jù) 按升序排列*/ 2 struct link *InsertNode(struct link *head, int nodeData) 3 { 4     struct link *p = head, *pr = head, *temp = NULL; 5  6     p = (struct link *)malloc(sizeof(struct link)); 7     if (p == NULL) 8     { 9         printf("No enough meomory!\n");10         exit(0);11     }12     p->next = NULL;        /* 待插入節(jié)點指針域賦值為空指針 */13     p->data = nodeData;14 15     if (head == NULL)    /* 若原鏈表為空 */16     {17         head = p;        /* 插入節(jié)點作頭結(jié)點 */18     }19     else        /* 原鏈表不為空 */20     {21         while (pr->data < nodeData && pr->next != NULL)22         {23             temp = pr;        /* 保存當(dāng)前節(jié)點的指針 */24             pr = pr->next;    /* pr指向當(dāng)前節(jié)點的下一節(jié)點 */25         }26         if (pr->data >= nodeData)27         {28             if (pr == head)        /* 在頭節(jié)點前插入新節(jié)點 */29             {30                 p->next = head;    /* 新節(jié)點指針域指向原鏈表頭結(jié)點 */31                 head = p;        /* 頭指針指向新節(jié)點 */32             }33             else34             {35                 pr = temp;36                 p->next = pr->next;        /* 新節(jié)點指針域指向下一節(jié)點 */37                 pr->next = p;            /* 讓前一節(jié)點指針域指向新節(jié)點 */38             }39         }40         else        /* 若在表尾插入新節(jié)點 */41         {42             pr->next = p;    /* 末節(jié)點指針域指向新節(jié)點*/43         }44     }45 46     return head;47 }


 

 

 (編譯器:Microsoft Visual C++ 2010 Express)

 

(tips:上面的代碼中將頭節(jié)點中的數(shù)據(jù)當(dāng)作第一個元素,大多數(shù)情況頭節(jié)點是不存儲數(shù)據(jù)的(當(dāng)時沒注意???),讀者可自行嘗試修改代碼讓頭結(jié)點不存儲數(shù)據(jù),頭節(jié)點的后一個節(jié)點作為第一個元素)

下面附上頭結(jié)點不存儲數(shù)據(jù)的代碼(區(qū)別不是很大,就是多用了一個子函數(shù)來初始化頭結(jié)點)