日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法:企业级链表实现(超详细)

發(fā)布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法:企业级链表实现(超详细) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

企業(yè)級鏈表介紹

如果我們使用原始的C語言寫鏈表的話,數(shù)據(jù)類型是被固定死的,如果業(yè)務(wù)換了 需要另一種數(shù)據(jù)類型,我們又得重新在寫一個鏈表當(dāng)然我們可以使用void* 萬能指針,因為void* 可以接受任意類型的指針,那么我們就可以接受任意類型的數(shù)據(jù)的地址了,我們只需要維護(hù)用戶提供的數(shù)據(jù)地址就可以。詳細(xì)介紹請看:數(shù)據(jù)結(jié)構(gòu)與算法:單鏈表(利用萬能指針實現(xiàn)對任意類型數(shù)據(jù)進(jìn)行操作)。今天我們介紹另外一種方法,讓我們的寫的鏈表不受業(yè)務(wù)結(jié)構(gòu)而限制,在我們用的數(shù)據(jù)類型發(fā)生改變時并不需要去改變底層的鏈表結(jié)構(gòu)。這就今天要和大家分享的企業(yè)級鏈表,感覺這種思想太贊了。我們在c語言中一般使用結(jié)構(gòu)體作為復(fù)合數(shù)據(jù)類型,可以定義我們需要的數(shù)據(jù)集。如果我們將具體的業(yè)務(wù)數(shù)據(jù)放到LinkNode 鏈表結(jié)點中去,就會遇到前面分析的問題,業(yè)務(wù)和底層代碼實現(xiàn) 耦合的太緊了。企業(yè)級鏈表就是來解決這個問題。

企業(yè)級鏈表分析

接前面分析的問題,那么為何不把業(yè)務(wù)數(shù)據(jù)域分離出來呢?鏈表結(jié)點LinkNode中只放next指針域

typedef struct LinkNode
{
struct LinkNode* next;
}LinkNode;

那我們的數(shù)據(jù)業(yè)務(wù)數(shù)據(jù)呢?放哪里呀?下面就是企業(yè)級鏈表的高明處。你定義的業(yè)務(wù)數(shù)據(jù),該怎么定義就怎么定義,只需將LinkNode 作為你定義的業(yè)務(wù)數(shù)據(jù)類型的第一個成員 就行了。比如說,下面定義一個學(xué)生數(shù)據(jù)類型。由于LinkNode 放在我們自定義的數(shù)據(jù)類型Student類型的第一個成員,那么&LinkNode和&Student 他們是一樣的!他們的起始地址是重合的。那么我們底層使用LinkNode數(shù)據(jù)類型,就不用管用戶上層怎么定義了,你只要放置一個LinkNode成員在你定義的數(shù)據(jù) 類型的第一位,你將Student數(shù)據(jù)的地址傳進(jìn)來,我們依舊可以取到LinkNode數(shù)據(jù),就行使用LinkNode 來維護(hù)鏈表之間的前驅(qū)后繼關(guān)系就如同下圖一樣,給你定義的數(shù)據(jù)類型 安裝一個鉤子,將你定義的數(shù)據(jù)像鏈表一樣鏈接起來了。

typedef struct Student
{
LinkNode node;
char name[64];
int age;
}Student;


企業(yè)級鏈表代碼實現(xiàn)

相關(guān)算法還是和正常的單鏈表差不多,只是用戶使用的時候,按照要求使用就ok,LinkNode做為用戶定義的業(yè)務(wù)數(shù)據(jù)的第一個成員,然后可以使用了。

CompanyLinkList.h

#pragma once #ifndef __COMPANY_LINKLIST_H__ #define __COMPANY_LINKLIST_H__typedef enum {TRUE,FASLE} BOOLEAN ;//成功狀態(tài) FALSE 不成功 TRUE成功 typedef enum { ERROR, OK } STATUS; //狀態(tài)信息 ERROR 發(fā)生錯誤 OK 一切正常typedef struct LinkNode {struct LinkNode* next; }LinkNode;typedef struct LinkList {LinkNode head;int size; }LinkList;//創(chuàng)建鏈表并初始化 LinkList* Create_LinkList();//插入數(shù)據(jù) 根據(jù)位置插入 int Insert_LinkList(LinkList* list,int pos, LinkNode* data);//刪除數(shù)據(jù) 根據(jù)位置刪除 int Remove_LinkList(LinkList* list, int pos);//查找數(shù)據(jù),根據(jù)數(shù)據(jù)內(nèi)容 int Find_LinkList(LinkList* list, LinkNode* data,int (*Compare_Function)(LinkNode*,LinkNode*));//遍歷鏈表 int Foreach_LinkList(LinkList* list, void(*Foreach_Function)(LinkNode*));//清空數(shù)據(jù) 鏈表仍然可用 int Clear_LinkList(LinkList* list);//銷毀鏈表 鏈表不可用 int Destroy_LinkList(LinkList* list);#endif // !__COMPANY_LINKLIST_H__

CompanyLinkList.c

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include "CompanyLinkList.h"//創(chuàng)建鏈表并初始化 LinkList* Create_LinkList() {LinkList* list = (LinkList*)malloc(sizeof(LinkList));list->size = 0;list->head.next = NULL;return list; }//插入結(jié)點數(shù)據(jù)的地址 根據(jù)位置插入,pos從1開始 int Insert_LinkList(LinkList* list, int pos, LinkNode* data) {if (NULL == list || NULL==data){return ERROR;}//位置太小插入到 第一個位置if (pos < 1){pos = 1;}//位置太大插入到 尾部if (pos > list->size){pos = list->size + 1;}//找到插入位置的前驅(qū)結(jié)點LinkNode* pre = &list->head;for (int i = 1; i < pos; i++){pre = pre->next;}data->next = pre->next;pre->next = data;list->size++;return OK; }//刪除數(shù)據(jù) 根據(jù)位置刪除 pos 從1 開始 int Remove_LinkList(LinkList* list, int pos) {//list為NULL 或者位置非法 直接返回if (NULL == list || pos < 1 || pos > list->size){return ERROR;}LinkNode* pre = &list->head;//同樣找到刪除結(jié)點的前驅(qū)for (int i = 1; i < pos; i++){pre = pre->next;}//將不要的元素略過,因為我們只維護(hù)用戶提供的數(shù)據(jù)的地址,釋放內(nèi)存不歸我們管pre->next = pre->next->next;list->size--;return OK; }//查找數(shù)據(jù),根據(jù)數(shù)據(jù)內(nèi)容,返回時鏈表中的第幾個元素,從1開始計數(shù) ,沒找到返回-1 //Compare_Function 用戶提供 結(jié)點元素比較的回調(diào)函數(shù) int Find_LinkList(LinkList* list, LinkNode* data, int(*Compare_Function)(LinkNode*, LinkNode*)) {if (NULL == list || NULL == data || NULL == Compare_Function){return ERROR;}LinkNode* node = list->head.next;int flag = 0;// 是否查找到的標(biāo)志int index = 1;while (node!=NULL){if (Compare_Function(node, data)){flag = 1;break;}node = node->next;index++;}return flag ? index : -1; }//遍歷鏈表 //Foreach_Function 用戶提供的遍歷鏈表元素的回調(diào)函數(shù) int Foreach_LinkList(LinkList* list, void(*Foreach_Function)(LinkNode*)) {if (NULL == list || NULL == Foreach_Function){return ERROR;}LinkNode* node = list->head.next;while (NULL!=node){Foreach_Function(node);node = node->next;}return OK; }//清空數(shù)據(jù) 鏈表仍然可用 int Clear_LinkList(LinkList* list) {if (NULL == list){return ERROR;}list->size = 0;list->head.next = NULL;return OK; }//銷毀鏈表 鏈表不可用 int Destroy_LinkList(LinkList* list) {if (NULL == list){return ERROR;}free(list);list = NULL;return OK; }//用戶使用 企業(yè)級鏈表,只需要在自己定義的類型中將LinkNode 作為第一個成員即可使用 //這樣就將 具體的業(yè)務(wù)和底層鏈表算法 進(jìn)行分離了 typedef struct Student {LinkNode node;char name[64];int age; }Student; //用戶定義遍歷的回調(diào)函數(shù) void Print_Student(LinkNode* node) {Student* stu = (Student*)node;printf("姓名:%s,年齡%d\n",stu->name,stu->age);return; } //用戶定義結(jié)點的比較回調(diào)函數(shù) int Compare_Student(LinkNode* node1, LinkNode* node2) {Student* stu1 = (Student*)node1;Student* stu2 = (Student*)node2;//年齡和名字相同才相同if (stu1->age == stu2->age && 0 == strcmp(stu1->name, stu2->name)){return 1;}return 0; }int main(int argc, char *argv[]) {//企業(yè)鏈表使用Student s1, s2, s3, s4, s5;s1.age = 11;s2.age = 12;s3.age = 13;s4.age = 14;s5.age = 15;strcpy(s1.name, "aaa");strcpy(s2.name, "bbb");strcpy(s3.name, "ccc");strcpy(s4.name, "ddd");strcpy(s5.name, "eee");//創(chuàng)建鏈表LinkList* list = Create_LinkList();//插入Insert_LinkList(list, 1, (LinkNode*)&s1);Insert_LinkList(list, 2, (LinkNode*)&s2);Insert_LinkList(list, 3, (LinkNode*)&s3);Insert_LinkList(list, 4, (LinkNode*)&s4);Insert_LinkList(list, 5, (LinkNode*)&s5);printf("插入5條數(shù)據(jù)后遍歷:\n");Foreach_LinkList(list, Print_Student);//查找Student s6;s6.age = 15;strcpy(s6.name, "eee");int index = Find_LinkList(list,(LinkNode*)&s6, Compare_Student);printf("查找的元素name=eee,age=15,是鏈表中第%d個元素\n",index);//刪除元素Remove_LinkList(list, 1);printf("刪除第1個結(jié)點后遍歷:\n");Foreach_LinkList(list, Print_Student);return 0; }

企業(yè)級鏈表運(yùn)行驗證


總結(jié)

以上是生活随笔為你收集整理的数据结构与算法:企业级链表实现(超详细)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。