C語言實現單鏈表(不帶頭結點)的基本操作

來源:互聯網
上載者:User

       鏈表在資料結構和演算法中的重要性不言而喻。這裡我們要用C來實現鏈表(單鏈表)中的基本操作。對於鏈表的基本概念請參考《資料結構與演算法之鏈表》這篇部落格。範例程式碼上傳至 https://github.com/chenyufeng1991/LinkedList 。在本案例中的單鏈表,都是沒有頭結點的,頭指標直接指向第一個節點。帶頭結點的執行個體我會在之後進行講解。

(1)定義單鏈表的節點類型

typedef int elemType ;// 定義單鏈表結點類型typedef struct ListNode{    elemType element;      //資料域    struct ListNode *next;   //地址域}Node;

(2)初始化線性表

// 1.初始化線性表,即置單鏈表的表頭指標為空白void initList(Node *pNode){    pNode = NULL;    printf("%s函數執行,初始化成功\n",__FUNCTION__);}
當聲明一個頭結點後,把該頭結點設定為空白,即把資料域和地址域都設為空白,即可完成該鏈表的初始化。

(3)建立線性表

// 2.建立線性表,此函數輸入負數終止讀取資料Node *creatList(Node *pHead){    Node *p1;//表前端節點,始終指向頭結點    Node *p2;//表尾節點,始終指向鏈表的最後一個元素    p1 = p2 = (Node *)malloc(sizeof(Node)); //申請新節點,分配空間    if(p1 == NULL || p2 == NULL){        printf("記憶體配置失敗\n");        exit(0);    }    memset(p1,0,sizeof(Node));    scanf("%d",&p1->element);    //輸入新節點的值    p1->next = NULL;         //新節點的指標置為空白    while(p1->element > 0){        //輸入的值大於0則繼續,直到輸入的值為負        if(pHead == NULL){       //空表,接入表頭            pHead = p1;          //直接把p1作為頭結點,也可以理解為把pHead頭結點指向p1        }else{            p2->next = p1;       //非空表,接入表尾        }        p2 = p1;                //p1插入後,p1就是尾結點,所以p2要指向尾結點        p1 = (Node *)malloc(sizeof(Node));    //再重申請一個節點        if(p1 == NULL || p2 == NULL){            printf("記憶體配置失敗\n");            exit(0);        }        memset(p1,0,sizeof(Node));        scanf("%d",&p1->element);        p1->next = NULL;    }    printf("%s函數執行,鏈表建立成功\n",__FUNCTION__);    return pHead;           //返回鏈表的頭指標}

我這裡使用手動的方式輸入元素,直到輸入0或者負數停止。


(4)列印鏈表

// 3.列印鏈表,鏈表的遍曆void printList(Node *pHead){    if(NULL == pHead){   //鏈表為空白        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);    }else{        while(NULL != pHead){                        printf("%d ",pHead->element);            pHead = pHead->next;        }        printf("\n");    }}

使用地址域順序列印即可。


(5)清空鏈表

// 4.清除線性表L中的所有元素,即釋放單鏈表L中所有的結點,使之成為一個空表void clearList(Node *pHead){    Node *pNext;            //定義一個與pHead相鄰節點,理解為當前節點的下一個節點    if(pHead == NULL){        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);    }    while(pHead->next != NULL){        pNext = pHead->next;//儲存下一結點的指標        free(pHead);   //釋放當前節點        pHead = pNext;      //指向下一個節點    }    printf("%s函數執行,鏈表已經清除\n",__FUNCTION__);}

想要檢驗是否清空成功,可以使用(4)中的鏈表列印檢驗即可。

(6)計算鏈表長度

// 5.返回單鏈表的長度int sizeList(Node *pHead){    int size = 0;    while(pHead != NULL){        size++;        pHead = pHead->next;    }    printf("%s函數執行,鏈表長度 %d \n",__FUNCTION__,size);    return size;    //鏈表的實際長度}

也就是計算有多少個節點。

(7)判斷鏈表是否為空白

// 6.檢查單鏈表是否為空白,若為空白則返回1,否則返回0int isEmptyList(Node *pHead){    if(pHead == NULL){        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);        return 1;    }    printf("%s函數執行,鏈表非空\n",__FUNCTION__);    return 0;}

(8)尋找鏈表某個位置元素

// 7.返回單鏈表中第pos個結點中的元素,若pos超出範圍,則停止程式運行void getElement(Node *pHead, int pos){    int i = 0;    if(pos < 1){        printf("%s函數執行,pos值非法\n",__FUNCTION__);    }    if(pHead == NULL){        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);    }    while(pHead != NULL){        i++;        if(i == pos){            break;        }        pHead = pHead->next;    //移到下一結點    }    if(i < pos){                  //pos值超過鏈表長度        printf("%s函數執行,pos值超出鏈表長度\n",__FUNCTION__);    }    printf("%s函數執行,位置 %d 中的元素為 %d\n",__FUNCTION__,pos,pHead->element);}

(9)返回某元素值在鏈表中的記憶體位址

// 8.從單鏈表中尋找具有給定值x的第一個元素,若尋找成功則返回該結點data域的儲存地址,否則返回NULLelemType* getElemAddr(Node *pHead, elemType x){    if(NULL == pHead){        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);        return NULL;    }    while((pHead->element != x) && (NULL != pHead->next)) {//判斷是否到鏈表末尾,以及是否存在所要找的元素        pHead = pHead->next;    }    if((pHead->element != x) && (pHead != NULL)){        //當到達最後一個節點        printf("%s函數執行,在鏈表中未找到x值\n",__FUNCTION__);        return NULL;    }    if(pHead->element == x){        printf("%s函數執行,元素 %d 的地址為 0x%x\n",__FUNCTION__,x,&(pHead->element));    }    return &(pHead->element);//返回元素的地址}

(10)修改某個節點的值

// 9.把單鏈表中第pos個結點的值修改為x的值,若修改成功返回1,否則返回0int modifyElem(Node *pNode,int pos,elemType x){    int i = 0;    if(NULL == pNode){        printf("%s函數執行,鏈表為空白\n",__FUNCTION__);        return 0;    }    if(pos < 1){        printf("%s函數執行,pos值非法\n",__FUNCTION__);        return 0;    }    while(pNode != NULL){        i++;        if(i == pos){            break;        }        pNode = pNode->next; //移到下一結點    }    if(i < pos) {                 //pos值大於鏈表長度        printf("%s函數執行,pos值超出鏈表長度\n",__FUNCTION__);        return 0;    }    pNode->element = x;    printf("%s函數執行\n",__FUNCTION__);    return 1;}

(11)表頭插入一個節點

// 10.向單鏈表的表頭插入一個元素int insertHeadList(Node **pNode,elemType insertElem){    Node *pInsert;    pInsert = (Node *)malloc(sizeof(Node));    memset(pInsert,0,sizeof(Node));    pInsert->element = insertElem;    pInsert->next = *pNode;    *pNode = pInsert;          //前端節點*pNode指向剛插入的節點,注意和上一行代碼的前後順序;    printf("%s函數執行,向表頭插入元素成功\n",__FUNCTION__);    return 1;}

(12)表尾插入一個節點

// 11.向單鏈表的末尾添加一個元素int insertLastList(Node **pNode,elemType insertElem){    Node *pInsert;    Node *pHead;    pHead = *pNode;    pInsert = (Node *)malloc(sizeof(Node)); //申請一個新節點    memset(pInsert,0,sizeof(Node));    pInsert->element = insertElem;    while(pHead->next != NULL){        pHead = pHead->next;    }    pHead->next = pInsert;   //將鏈表末尾節點的下一結點指向新添加的節點    printf("%s函數執行,向表尾插入元素成功\n",__FUNCTION__);        return 1;}

(13)測試函數

int main(int argc, const char * argv[]) {    Node *pList;            //聲明頭結點    initList(pList);       //鏈表初始化    printList(pList);       //遍曆鏈表,列印鏈表    pList = creatList(pList); //建立鏈表    printList(pList);    sizeList(pList);        //鏈表的長度    printList(pList);    isEmptyList(pList);     //判斷鏈表是否為空白鏈表    getElement(pList,3);  //擷取第三個元素,如果元素不足3個,則返回0    printList(pList);    getElemAddr(pList,5);   //獲得元素5的記憶體位址    modifyElem(pList,4,1);  //將鏈表中位置4上的元素修改為1    printList(pList);    insertHeadList(&pList,5);   //表頭插入元素5    printList(pList);    insertLastList(&pList,10);  //表尾插入元素10    printList(pList);    clearList(pList);       //清空鏈表    printList(pList);    return 0;}

本文參考:http://www.cnblogs.com/renyuan/archive/2013/05/21/3091506.html


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.