1. 程式人生 > >(C語言版)連結串列(一)——實現單向連結串列建立、插入、刪除等簡單操作(包含個人理解說明及註釋,新手跟著寫程式碼)

(C語言版)連結串列(一)——實現單向連結串列建立、插入、刪除等簡單操作(包含個人理解說明及註釋,新手跟著寫程式碼)

我學習了幾天資料結構,今天下午自己寫了一個單向連結串列的程式。我也是新手,所以剛開始學習資料結構的菜鳥們(有大牛們能屈尊看一看,也是我的榮幸)可以和我一起共同學習、討論,當然也很高興能指出我的錯誤,因為這是我們一起成長的過程。本程式碼包含我在寫程式時的一些個人理解的說明和一些註釋(如果那裡說錯了,望大家來指正),下面就進入正題了。

首先,這是個單向連結串列的程式碼,下面是我找的一張單向連結串列的示意圖。


很明顯可以看出它們是像鏈子一樣串在一起,它們是靠什麼串在一起的呢?可能有些人已經知道了——是指標,這裡的每一個方格我們叫做“節點”,每一個節點包含一個指標指向下一個節點,並且自己被上一個節點的指標指著,然後串在一起。但是這裡有一點要注意,就是頭節點(就是圖中的第一個節點)是不被其他節點指著的,尾節點(就是圖中的最後一個節點)不指向其他的節點,程式中我們讓它指向NULL,就是不指向任何東西。

SgLInkList.h   標頭檔案

這裡定義了節點的結構,包括一個數據成員和一個結構體指標,結構體指標是用來指向下一個節點用的,還包括單向連結串列的相關操作。

  1. #ifndef _SINGLY_LINKED_LIST_H_H
  2. #define _SINGLY_LINED_LIST_H_H
  3. //設計節點結構
  4. typedefstruct Node  
  5. {  
  6.     int data;  
  7.     struct Node *pNext;  
  8. }NODE, *pNODE;  
  9. //建立單向連結串列
  10. pNODE CreateSgLinkList(void);  
  11. //列印單向連結串列
  12. void TraverseSgLinkList(pNODE pHead);  
  13. //判斷單向連結串列是否為空
  14. int IsEmptySgLinkList(pNODE pHead);  
  15. //計算單向連結串列的長度
  16. int GetLengthSgLinkList(pNODE pHead);  
  17. //向單向連結串列插入節點
  18. int InsertEleSgLinkList(pNODE pHead, int pos, int data);  
  19. //從單向連結串列刪除節點
  20. int DeleteEleSgLinkList(pNODE pHead, int pos);  
  21. //刪除整個連結串列,釋放記憶體
  22. void FreeMemory(pNODE *ppHead);  
  23. #endif

SgLinkList.cpp  存放單向連結串列相關操作函式的定義,包含連結串列的建立、連結串列值的列印、判斷連結串列是否為空、計算連結串列長度、插入節點、刪除節點、刪除整個連結串列。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "SgLinkList.h"

(1)第一個函式是建立單向連結串列,這裡我首先建立了一個節點作為頭節點,但是這個頭節點不參與後面相關函式的執行,例如:頭結點不參與連結串列資料的列印;只包含頭節點不包含其他節點時,該連結串列判斷為空;計算連結串列長度時,頭結點不參與計數,刪除和插入節點函式也都是從頭節點後面的節點計數的。當然有一點,最後釋放記憶體的時候,頭節點是要跟著一起釋放的,因為給頭節點分配了記憶體所以也得釋放,要不會造成記憶體洩露,這一點很容易忽視了。

  1. //建立單向連結串列
  2. pNODE CreateSgLinkList(void)  
  3. {  
  4.     int i, length, data;  
  5.     pNODE p_new = NULL, pTail = NULL;  
  6.     //建立頭節點,頭結點是第0個節點,後面的節點從1開始計數
  7.     pNODE pHead = (pNODE)malloc(sizeof(NODE));  
  8.     if (NULL == pHead)  
  9.     {  
  10.         printf("記憶體分配失敗!\n");  
  11.         exit(EXIT_FAILURE);  
  12.     }  
  13.     pHead->data = 0;  
  14.     pHead->pNext = NULL;  
  15.     pTail = pHead;  
  16.     printf("請輸入要建立連結串列的長度:");  
  17.     scanf("%d", &length);  
  18.     for (i=1; i<length+1; i++)  
  19.     {  
  20.         p_new = (pNODE)malloc(sizeof(NODE));  
  21.         if (NULL == p_new)  
  22.         {  
  23.             printf("記憶體分配失敗!\n");  
  24.             exit(EXIT_FAILURE);  
  25.         }  
  26.         printf("請輸入第%d個節點的值:", i);  
  27.         scanf("%d", &data);  
  28.         p_new->data = data;  
  29.         p_new->pNext = NULL;  
  30.         pTail->pNext = p_new;  
  31.         pTail = p_new;  
  32.     }  
  33.     return pHead;  
  34. }  


(2)這個是列印單向連結串列函式,可以看到是從頭結點的後面一個節點開始列印的,p=pHead->pNext。一直列印到最後一個

  1. //列印單向連結串列,不列印頭結點的值。
  2. void TraverseSgLinkList(pNODE pHead)  
  3. {  
  4.     pNODE pt = pHead->pNext;  
  5.     printf("列印連結串列:");  
  6.     while (pt != NULL)  
  7.     {  
  8.         printf("%d ", pt->data);  
  9.         pt = pt->pNext;  
  10.     }  
  11.     putchar('\n');  
  12. }  
(3)這個是判斷連結串列是否為空的函式,通過檢查頭節點的後面一個節點來判斷,所以這裡頭節點也不參與運算。
  1. //判斷連結串列是否為空
  2. int IsEmptySgLinkList(pNODE pHead)  
  3. {  
  4.     if (pHead->pNext == NULL)  
  5.         return 1;  
  6.     else
  7.         return 0;  
  8. }  
(4)這個是計算連結串列長度的函式,也是從頭節點後面的節點開始,找到節點就讓length加1,直到找到最後一個節點為止。
  1. //計算單向連結串列長度
  2. int GetLengthSgLinkList(pNODE pHead)  
  3. {  
  4.     int length = 0;  
  5.     pNODE pt = pHead->pNext;  
  6.     while (pt != NULL)  
  7.     {  
  8.         length++;  
  9.         pt = pt->pNext;  
  10.     }  
  11.     return length;  
  12. }  

(5)這個是向單向連結串列插入節點的函式,這裡我定義位置值是從1開始,到連結串列長度加1結束(當然也可以自己定義從什麼數值開始),這裡位置要比刪除節點函式多一個,為什麼呢?例如:一個連結串列包含三個節點(頭節點除外),它們的元素值分別為1、2、3,那麼我們可以插入節點的地方就有4個位置了,4個位置夾住了三個節點。但是如果是刪除節點函式的話呢,操作的是實際的節點,所以位置值就只能是這三個節點了。說到這裡大家應該明白了吧。這裡附一張插入節點的示意圖:


  1. //向單向連結串列插入一個節點,位置從1開始,到連結串列長度加1結束。
  2. int InsertEleSgLinkList(pNODE pHead, int pos, int data)  
  3. {  
  4.     pNODE pt = NULL, p_new = NULL;  
  5.     if (pos > 0 && pos < GetLengthSgLinkList(pHead) + 2)  
  6.     {  
  7.         p_new = (pNODE)malloc(sizeof(NODE));  
  8.         if (NULL == p_new)  
  9.         {  
  10.             printf("記憶體分配失敗!\n");  
  11.             exit(EXIT_FAILURE);  
  12.         }  
  13.         p_new->data = data;  
  14.         while (1)  
  15.         {  
  16.             pos--;        
  17.             if (0 == pos)  
  18.                 break

    相關推薦

    C語言連結串列——實現單向連結串列建立插入刪除簡單操作包含個人理解說明註釋新手跟著程式碼

    我學習了幾天資料結構,今天下午自己寫了一個單向連結串列的程式。我也是新手,所以剛開始學習資料結構的菜鳥們(有大牛們能屈尊看一看,也是我的榮幸)可以和我一起共同學習、討論,當然也很高興能指出我的錯誤,因為這是我們一起成長的過程。本程式碼包含我在寫程式時的一些個人理解的說

    資料結構——有序連結串列合併C語言

    有序連結串列合併 兩個有序的連結串列,要求將其合併為一個連結串列,並且該連結串列保持有序!! 這裡所講的是連結串列升序! 這裡我們的實驗資料,以及思路如圖所示!! 實驗資料: 連結串列1:1, 3, 5, 7 連結串列2:1, 2, 4 ,5

    帶頭節點連結串列插入排序C語言

    主要是對插入排序進行復習,先寫一個數組的插入排序。 #include <stdio.h> void traverse(int *arr, int len); void insert_sort(int *arr, int len); int ma

    連結串列-遊標實現C語言

    如果用C/C++寫連結串列的話,用指標會比較方便,但很多語言都沒有指標,那麼怎麼實現比較好呢?遊標是個不錯的選擇。 在用指標實現的連結串列中,有這樣兩個特點: 1.資料存在一組結構體中,並且每個結構體都有指向下一個結構體的指標。 2.一個新

    C語言連結串列——實現雙向迴圈連結串列建立插入刪除釋放記憶體簡單操作

    雙向迴圈連結串列是基於雙向連結串列的基礎上實現的,和雙向連結串列的操作差不多,唯一的區別就是它是個迴圈的連結串列,通過每個節點的兩個指標把它們扣在一起組成一個環狀。所以呢,每個節點都有前驅節點和後繼節點(包括頭節點和尾節點)這是和雙向連結串列不同的地方。我們看下雙向迴圈連結

    如何在串列埠除錯助手上使用printf()函式顯示十進位制的資料漢字說明c語言

    估計很多人和我一樣,很想直接在串列埠除錯助手上顯示十進位制資料,我最近在做一個專案,當然本人也是小白,但這個問題已經被我解決了,希望幫助需要的人。 我們都知道,串列埠助手一般都只能顯示十六進位制資料和字元,如果我們想將控制器的實時資料通過串列埠傳送到上位機,方便監測,最好直接顯示十進位制資料。廢

    資料結構C語言第三 基礎實驗二

    1、編寫函式slnklist delx(linklist head, datatype x),刪除不帶頭結點單鏈表head中第一個值為x 的結點。 並構造測試用例進行測試。 2、假設線性表(a1,a2,a3,…an)採用不帶頭結點的單鏈表儲存, 請設計演算法函式linklist reverse1

    資料結構C語言第三基礎實驗

    1、基於sequlist.h中定義的順序表,編寫演算法函式reverse(sequence_list *L),實現順序表的就地倒置。 2、編寫一個演算法函式void sprit( sequence_list *L1,sequence_list *L2,sequence_list *L3), 將順

    資料結構C語言讀書筆記1(基本概念和術語)

    資料: 所有輸入到計算機中,並被計算機程式處理的符號的總稱。 資料元素: 資料的基本單位,在計算機程式中經常被當做一個整體進行考慮和處理 資料物件: 性質相同的資料元素的集合,是資料的一個子集。 資料結構: 相互之間存在一種或多種特定關係的資料元素的集合。這種資料元素之間

    LeetCode -- 50 Pow(x, n)C語言

    題目描述: 程式碼如下(附有詳解): double myPow(double x, int n) //如果n為零,表明冪數為0,直接返回1 if(n == 0) return 1; //如果n為零,表明冪數為0,直接返回x

    資料結構c語言中線性表的單鏈表儲存結構

    本文轉自:https://blog.csdn.net/prlhnxx/article/details/79174782 /* run this program using the console pauser or add your own getch, system("pause") or i

    初夏小談:斐波那契三種實現方法C語言第三種相信你沒見過

    斐波那契數列(Fibonaccisequnce),又稱黃金分割數列。研究斐波那契數列有相當重要的價值,例在現代物理、準晶體結構、化學等領域都有直接的應用。因此研究斐波那契數列也是很有必要的。 今天初夏將為大家帶來計算斐波那契數列第n位的三種方法 第一種利用遞迴的方法計算,程式碼相當簡單,但其

    關於嚴蔚敏老師《資料結構C語言》書中程式碼的誤解

    清華大學嚴蔚敏老師的《資料結構(C語言版)》以其嚴謹被奉為經典,我是從其Pascal版一路追著買到C語言版,一直覺得這本書理論功力深厚,是不可多得的資料結構教材。但其編寫過程中為避免太過拘泥於具體語言細節,使用了ADT描述,具體演算法中使用了偽碼描述,對於新手直接把程式碼原樣照抄是沒法直接在電腦

    排序演算法C語言

    交換類 氣泡排序(Bubble Sort) O(n2)O(n^2)O(n2) 最簡單的一種排序演算法。先從陣列中找到最大值(或最小值)並放到陣列最左端(或最右端),然後在剩下的數字中找到次大值(或次小值),以此類推,直到陣列有序排列。 void Bubble

    L1-028 判斷素數C語言

    L1-028 判斷素數 (10 分) 本題的目標很簡單,就是判斷一個給定的正整數是否素數。 輸入格式: 輸入在第一行給出一個正整數N(≤ 10),隨後N行,每行給出一個小於2 ^​31 的需要判斷的正整數。 輸出格式: 對每個需要判斷的正整數,如果它是素數,則在

    LeetCode--153 尋找旋轉排序陣列中的最小值 Find Minimum in Rotated Sorted ArrayC語言

    題目描述: 解題思路:可以使用順序遍歷,將最小值記錄下來,時間複雜度為O(n),但是根據題目描述,該陣列為旋轉排序陣列,這裡就可以聯想到二分查詢,試著用二分查詢的思想,首先使用Lindex和Rindex記錄左右區間的下標,然後再用Mindex表示區間中間元素的下標,根據

    C語言實現線性表歸併_含原始碼和執行結果_資料結構C語言

    採用動態分配順序儲存結構實現 採用單鏈表結構實現 1.採用動態分配實現 #include<stdio.h> #include<stdlib.h> #define LIST_INIT_SIZE 100 #define LISTINCREM

    7-2 組個最小數C語言

    7-2 組個最小數 (20 分) 給定數字0-9各若干個。你可以以任意順序排列這些數字,但必須全部使用。目標是使得最後得到的數儘可能小(注意0不能做首位)。例如:給定兩個0,兩個1,三個5,一個8,我們得到的最小的數就是10015558。 現給定數字,請編寫程式

    7-1 最大子列和問題C語言

    7-1 最大子列和問題 (20 分) 給定K個整陣列成的序列{ N1, N2, …, NK },“連續子列”被定義為{ Ni, Ni+1, …, Nj },其中 1 <= i <= j <= K。“最大子列和”則被定義為所有連續子列元素的和中最

    作業系統程序排程實現演算法c語言

    #include <stdio.h>#include <stdlib.h>#include <windows.h>   //包含sleep函式#define TRUE 1#define FALSE 0#define OK 1#define