C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
本文實(shí)例為大家分享了c語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表的具體代碼,供大家參考,具體內(nèi)容如下
忽然想起來(lái),大概在兩年之前學(xué)習(xí)C語(yǔ)言的時(shí)候,曾經(jīng)用C語(yǔ)言寫(xiě)過(guò)一些通用的數(shù)據(jù)結(jié)構(gòu)。主要也就實(shí)現(xiàn)了鏈表、隊(duì)列、椎、HashSet,還有HashMap。當(dāng)時(shí)只是知道標(biāo)準(zhǔn)的C語(yǔ)言中沒(méi)有這方面的類庫(kù),后來(lái)才知道有很多第三方的類似這樣的類庫(kù)。廢話不多說(shuō),先把代碼粘過(guò)來(lái)。
下面實(shí)現(xiàn)的是通用鏈表,注意鏈表中只存儲(chǔ)了指針,沒(méi)有儲(chǔ)存實(shí)際的數(shù)據(jù)。
頭文件
/*************************
*** File myList.h
**************************/
#ifndef MYLIST_H_INCLUDED
#define MYLIST_H_INCLUDED
#include <stdio.h>
typedef struct myNode
{
void * data;
struct myNode *next;
} MyNode;
typedef struct myList
{
MyNode * first;
MyNode * last;
int count;
int (*equal)(void * a, void * b);
} MyList;
typedef struct myListIterator
{
MyNode * p;
int count;
int allSize;
} MyListIterator;
//創(chuàng)建鏈表
MyList * createMyList();
//創(chuàng)建鏈表,帶有相等參數(shù),用于查找
MyList * createMySearchList(int(*equal)(void * a, void * b));
//釋放鏈表
void freeMyList(MyList * list);
//插入在尾部
void myListInsertDataAtLast(MyList* const list, void* const data);
//插入在首部
void myListInsertDataAtFirst(MyList * const list, void* const data);
//插入
void myListInsertDataAt(MyList * const list, void* const data, int index);
//刪除在尾部
void* myListRemoveDataAtLast(MyList* const list);
//刪除在首部
void* myListRemoveDataAtFirst(MyList * const list);
//刪除
void* myListRemoveDataAt(MyList* const list, int index);
//刪除對(duì)象,返回是否刪除成功
int myListRemoveDataObject(MyList* const list, void * data);
//長(zhǎng)度
int myListGetSize(const MyList * const list);
//打印
void myListOutput(const MyList * const list, void(*pt)(const void * const));
//取得數(shù)據(jù)
void* myListGetDataAt(const MyList * const list, int index);
//取得第一個(gè)數(shù)據(jù)
void* myListGetDataAtFirst(const MyList * const list);
//取得最后一個(gè)數(shù)據(jù)
void* myListGetDataAtLast(const MyList * const list);
//查找某個(gè)數(shù)據(jù)的位置,如果equal方法為空,比較地址,否則調(diào)用equal方法
//如果不存在返回-1,如果存在,返回出現(xiàn)的第一個(gè)位置
int myListFindDataIndex(const MyList * const list, void * data);
//創(chuàng)建遍歷器
MyListIterator* createMyListIterator(const MyList * const list);
//釋放遍歷器
void freeMyListIterator(MyListIterator* iterator);
//遍歷器是否有下一個(gè)元素
int myListIteratorHasNext(const MyListIterator* const iterator);
//返回遍歷器的下一個(gè)元素
void * myListIteratorNext(MyListIterator* const iterator);
#endif // MYLIST_H_INCLUDED
源文件
/*************************
*** File myList.c
**************************/
#include "myList.h"
#include <stdlib.h>
//創(chuàng)建鏈表
MyList * createMyList()
{
MyList * re = (MyList *) malloc(sizeof(MyList));
re->count = 0;
re->first = NULL;
re->last = NULL;
re->equal = NULL;
return re;
}
//釋放鏈表
void freeMyList(MyList * list)
{
MyNode * p;
while (list->first)
{
p = list->first->next;
free(list->first);
list->first = p;
}
free(list);
}
//插入在尾部
void myListInsertDataAtLast(MyList * const list, void* const data)
{
MyNode * node = (MyNode *) malloc(sizeof(MyNode));
node->data = data;
node->next = NULL;
if (list->count)
{
list->last->next = node;
list->last = node;
}
else
{
list->first = node;
list->last = node;
}
(list->count)++;
}
//插入在首部
void myListInsertDataAtFirst(MyList * const list, void* const data)
{
MyNode * node = (MyNode *) malloc(sizeof(MyNode));
node->data = data;
node->next = NULL;
if (list->count)
{
node->next = list->first;
list->first = node;
}
else
{
list->first = node;
list->last = node;
}
(list->count)++;
}
//長(zhǎng)度
int myListGetSize(const MyList * const list)
{
return list->count;
}
//打印
void myListOutput(const MyList * const list, void(*pt)(const void * const))
{
MyNode * p = list->first;
while (p)
{
(*pt)(p->data);
p = p->next;
}
}
//刪除在尾部
void* myListRemoveDataAtLast(MyList* const list)
{
if (list->count == 1)
{
return myListRemoveDataAtFirst(list);
}
MyNode * p = list->first;
while (p->next != list->last)
{
p = p->next;
}
void *re = list->last->data;
free(list->last);
p->next = NULL;
list->last = p;
(list->count)--;
return re;
}
//刪除在首部
void* myListRemoveDataAtFirst(MyList * const list)
{
MyNode *p = list->first;
list->first = p->next;
void * re = p->data;
free(p);
(list->count)--;
if (list->count == 0)
{
list->last = NULL;
}
return re;
}
//插入
void myListInsertDataAt(MyList * const list, void* const data, int index)
{
if (index == 0)
{
myListInsertDataAtFirst(list, data);
return;
}
if (index == list->count)
{
myListInsertDataAtLast(list, data);
return;
}
MyNode * node = (MyNode *) malloc(sizeof(MyNode));
node->data = data;
node->next = NULL;
MyNode * p = list->first;
for (int i = 0; i < index - 1; i++)
{
p = p->next;
}
node->next = p->next;
p->next = node;
(list->count)++;
}
//刪除
void* myListRemoveDataAt(MyList* const list, int index)
{
if (index == 0)
{
return myListRemoveDataAtFirst(list);
}
if (index == list->count - 1)
{
return myListRemoveDataAtLast(list);
}
MyNode * p = list->first;
for (int i = 0; i < index - 1; i++)
{
p = p->next;
}
MyNode *tp = p->next;
p->next = p->next->next;
void * re = tp->data;
free(tp);
(list->count)--;
return re;
}
//取得數(shù)據(jù)
void* myListGetDataAt(const MyList * const list, int index)
{
if (index == list->count - 1)
{
return myListGetDataAtLast(list);
}
MyNode * p = list->first;
for (int i = 0; i < index; i++)
{
p = p->next;
}
return p->data;
}
//取得第一個(gè)數(shù)據(jù)
void* myListGetDataAtFirst(const MyList * const list)
{
return list->first->data;
}
//取得最后一個(gè)數(shù)據(jù)
void* myListGetDataAtLast(const MyList * const list)
{
return list->last->data;
}
//查找某個(gè)數(shù)據(jù)的位置,如果equal方法為空,比較地址,否則調(diào)用equal方法
//如果不存在返回-1,如果存在,返回出現(xiàn)的第一個(gè)位置
int myListFindDataIndex(const MyList * const list, void * data)
{
MyNode * p = list->first;
int re = 0;
if (list->equal)
{
while (p)
{
if (p->data == data || (*(list->equal))(p->data, data))
{
return re;
}
re++;
p = p->next;
}
}
else
{
while (p)
{
if (p->data == data)
{
return re;
}
re++;
p = p->next;
}
}
return -1;
}
//創(chuàng)建鏈表,帶有相等參數(shù),用于查找
MyList * createMySearchList(int(*equal)(void * a, void * b))
{
MyList * re = createMyList();
re->equal = equal;
return re;
}
//創(chuàng)建遍歷器
MyListIterator* createMyListIterator(const MyList * const list)
{
MyListIterator * re = (MyListIterator *) malloc(sizeof(MyListIterator));
re->p = list->first;
re->allSize = list->count;
re->count = 0;
return re;
}
//釋放遍歷器
void freeMyListIterator(MyListIterator* iterator)
{
free(iterator);
}
//遍歷器是否有下一個(gè)元素
int myListIteratorHasNext(const MyListIterator* const iterator)
{
return iterator->count < iterator->allSize;
}
//返回遍歷器的下一個(gè)元素
void * myListIteratorNext(MyListIterator* const iterator)
{
void * re = iterator->p->data;
iterator->p = iterator->p->next;
(iterator->count)++;
return re;
}
//刪除對(duì)象,返回是否刪除成功
int myListRemoveDataObject(MyList* const list, void * data)
{
MyListIterator * it = createMyListIterator(list);
int a = 0;
while (myListIteratorHasNext(it))
{
void * ld = myListIteratorNext(it);
if (data == ld || (list->equal != NULL && (*(list->equal))(ld, data)))
{
a = 1;
break;
}
}
if (a)
{
myListRemoveDataAt(list, it->count - 1);
}
return a;
}
測(cè)試文件
/*************************
*** File main.c
*** test for MyList
**************************/
#include <stdio.h>
#include <stdlib.h>
#include "myList.h"
typedef struct a
{
int i;
char c;
} A;
void ppt(const void* const p)
{
A * pp= p;
printf("%d(%c) ", pp->i, pp->c);
}
int main()
{
const int S =10;
//創(chuàng)建并初始化數(shù)據(jù)
A * data= malloc(sizeof(A)*S);
for (int i=0; i< S; i++)
{
data[i].i=i;
data[i].c=(char)('A'+0);
}
//創(chuàng)建鏈表
MyList * list= createMyList();
//測(cè)試三種插入方法
myListInsertDataAtLast( list, &data[0]);
myListInsertDataAtFirst( list, &data[4]);
myListInsertDataAt(list, &data[1], 1 );
//測(cè)試查找
int index = myListFindDataIndex(list, &data[2]);
printf("%d\n", index);
index = myListFindDataIndex(list, &data[4]);
printf("%d\n", index);
//輸出
myListOutput(list, ppt );
puts("");
//測(cè)試使用迭代器輸出
MyListIterator * it = createMyListIterator(list);
while(myListIteratorHasNext(it))
{
A * pp = myListIteratorNext(it);
printf("%d[%c] ", pp->i, pp->c);
}
puts("");
//釋放迭代器
freeMyListIterator(it);
//釋放鏈表
freeMyList(list);
//釋放數(shù)據(jù)
free(data);
return 0;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- C語(yǔ)言 二叉樹(shù)的鏈?zhǔn)酱鎯?chǔ)實(shí)例
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之復(fù)雜鏈表的拷貝
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)單鏈表接口函數(shù)全面講解教程
- C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)帶頭雙向循環(huán)鏈表全面詳解
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)創(chuàng)建及遍歷十字鏈表
- C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)線性表之順序表和鏈表原理分析
- C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)的棧和隊(duì)列
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)
相關(guān)文章
C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
這篇文章主要介紹了C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09
讓?xiě)?yīng)用程序只運(yùn)行一個(gè)實(shí)例的實(shí)現(xiàn)方法
我們?cè)谑褂谩?60軟件管家》時(shí)發(fā)現(xiàn),在《360軟件管家》已經(jīng)運(yùn)行了的情況下,再次點(diǎn)擊《360軟件管家》的圖標(biāo),那么它不會(huì)再運(yùn)行另外一個(gè)《360軟件管家》,而是將已有的《360軟件管家》給激活,始終只能運(yùn)行一個(gè)《360軟件管家》的實(shí)例2013-05-05
C++深入探索內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字的使用
本篇文章主要包括內(nèi)聯(lián)函數(shù)和auto關(guān)鍵字。其中,內(nèi)斂函數(shù)包括概念,特性等;auto關(guān)鍵字的使用規(guī)則,使用場(chǎng)景等,接下來(lái)讓我們深入了解2022-05-05
Qt利用ImageWatch實(shí)現(xiàn)圖片查看功能
Visual Studio有專門(mén)針對(duì)OpenCV開(kāi)發(fā)的插件,名叫ImageWatch,圖片放大之后可以查看RGB的像素值。本文將利用這一查件實(shí)現(xiàn)圖片查看功能,需要的可以參考一下2022-04-04

