c語言鏈表升級

來源:互聯網
上載者:User

標籤:each   結構體   define   efi   com   div   header   class   指標成員   

之前的鏈表就是一個普通的帶頭的單向鏈表,我們不自覺的會發現這樣的鏈表有缺陷,有關鏈表的刪除新增尋找跟鏈表的結構體內容耦合性太強

什麼意思呢?

比如我們之前的鏈表的結構體

typedef struct _Teacher{    int age;    struct _Teacher *next;}Teacher;

我們有關鏈表所有的操作都跟這個結構體緊密的相連,如果此刻我們有另一個結構體,裡面的欄位都跟這個不一樣,那麼,我們可能還需要對這個新的結構體寫一套鏈表操作?

相當於下面的圖,呵呵,有點醜


那麼我們的解決方案是什麼呢?,我們能不能關於不同結構體的所有操作都有一套公用方法呢?

當然是可以的!

在這之前我們必須有一個概念,結構體中的第一個元素的地址就是代表結構體的地址。

我們設計一個單純代表資料結構的結構體,這個結構體只有下個對象的地址的指標成員

 

typedef struct _tag_LinkListNode{    void * next;}LinkListNode;

比如此刻我們有一個教師結構體,那麼我們只需要在結構體的第一個成員是上面的LinkListNode對象。
形成下面的資料結構:

 

typedef struct _Teacher{    LinkListNode listNode;    int age;    char name[50];}Teacher;

那麼,此刻我們只要在我們的對鏈表的操作將傳過來的Teacher * 指標強轉為LinkListNode *類型,查詢出來的LinkListNode * 指標變數再強轉為Teacher * 對象,從而對LinkListNode形成一套插入刪除查詢的api就可以了
以下是實現的代碼:

介面:

#ifndef _MYLINKLIST_H_#define _MYLINKLIST_H_typedef void LinkList;typedef struct _tag_LinkListNode{    struct _tag_LinkListNode* next;}LinkListNode;LinkList* LinkList_Create();void LinkList_Destroy(LinkList* list);void LinkList_Clear(LinkList* list);int LinkList_Length(LinkList* list);int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);LinkListNode* LinkList_Get(LinkList* list, int pos);LinkListNode* LinkList_Delete(LinkList* list, int pos);#endif

實現:

#include "stdio.h"#include "stdlib.h"#include "linklist.h"typedef struct _tag_LinkList{    //前端節點    LinkListNode header;    int length;}TLinkList;/************************************************************************//* 建立list並初始化一個前端節點                                           *//************************************************************************/LinkList* LinkList_Create(){    TLinkList *tlist = (TLinkList *)malloc(sizeof(TLinkList));    if (tlist == NULL)    {        return NULL;    }    tlist->length = 0;    tlist->header.next = NULL;    return tlist;}void LinkList_Destroy(LinkList* list){    if (list == NULL)    {        return;    }    free(list);}/************************************************************************//* 清空list鏈表                                                         *//************************************************************************/void LinkList_Clear(LinkList* list){    if (list == NULL)    {        return;    }    TLinkList *tlinkList = (TLinkList *)list;    tlinkList->length = 0;    tlinkList->header.next = NULL;}int LinkList_Length(LinkList* list){    if (list == NULL)    {        return 0;    }    TLinkList *tlinkList = (TLinkList *)list;    return tlinkList->length;}int LinkList_Insert(LinkList* list, LinkListNode* node, int pos){    LinkListNode *pre, *cur;    int i;    if (list == NULL || node == NULL)    {        return -1;    }    //校正下標    if (pos<0)    {        return -2;    }    TLinkList *tlinkList = (TLinkList *)list;    if (pos>tlinkList->length - 1)    {        pos = tlinkList->length;    }    pre = (LinkListNode *)list;//初始化指向前端節點    cur = tlinkList->header.next;//初始化指向第一個節點,如果空鏈表指向空    for (i = 0; i < pos; i++)    {        pre = cur;        cur = cur->next;//最終讓當前指標指向要插入的位置    }    pre->next = node;    node->next = cur;    tlinkList->length++;    return 0;}LinkListNode* LinkList_Get(LinkList* list, int pos){    LinkListNode *pre, *cur;    int i;    if (list == NULL)    {        return NULL;    }    TLinkList *tlinkList = (TLinkList *)list;    //校正下標    if (pos >= tlinkList->length || pos < 0)    {        return NULL;    }    cur = tlinkList->header.next;//初始化指向第一個節點,如果空鏈表指向空    for (i = 0; i < pos; i++)    {        cur = cur->next;    }    return cur;}LinkListNode* LinkList_Delete(LinkList* list, int pos){    LinkListNode *pre, *cur;    int i;    if (list == NULL)    {        return NULL;    }    TLinkList *tlinkList = (TLinkList *)list;    //校正下標    if (pos >= tlinkList->length || pos < 0)    {        return NULL;    }    pre = (LinkListNode *)list;//初始化指向前端節點    cur = tlinkList->header.next;//初始化指向第一個節點,如果空鏈表指向空    for (i = 0; i < pos; i++)    {        pre = cur;        cur = cur->next;    }    pre->next = cur->next;    LinkListNode* curnode = cur;    tlinkList->length--;    return curnode;}

 

測試代碼

#include "stdio.h"#include "stdlib.h"#include "linklist.h"typedef struct _Teacher{    LinkListNode listNode;    int age;    char name[50];}Teacher;void main(){    LinkList* linkList;    Teacher t1, t2, t3;    int len;    int i;    linkList = LinkList_Create();    t1.age = 11;    t2.age = 22;    t3.age = 33;    LinkList_Insert(linkList, (LinkListNode*)&t1, 0);    LinkList_Insert(linkList, (LinkListNode*)&t2, 0);    LinkList_Insert(linkList, (LinkListNode*)&t3, 0);    len = LinkList_Length(linkList);    for (i = 0; i < len; i++)    {        Teacher * t = (Teacher *)LinkList_Get(linkList, i);        printf("cur teacher age=%d\n", t->age);    }    LinkList_Delete(linkList, 0);    LinkList_Delete(linkList, 1);    len = LinkList_Length(linkList);    for (i = 0; i < len; i++)    {        Teacher * t = (Teacher *)LinkList_Get(linkList, i);        printf("cur teacher age=%d\n", t->age);    }    system("pause");}

接下來,如果我們有新的結構體,只要在測試代碼那邊做修改,而不需要動我們的核心代碼了。

 

c語言鏈表升級

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.