天天看點

城市連結清單c語言,c語言實作通用資料結構(一):通用連結清單

忽然想起來,大概在兩年之前學習C語言的時候,曾經用C語言寫過一些通用的資料結構。主要也就實作了連結清單、隊列、椎、HashSet,還有HashMap。當時隻是知道标準的C語言中沒有這方面的類庫,後來才知道有很多第三方的類似這樣的類庫。廢話不多說,先把代碼粘過來。

下面實作的是通用連結清單,注意連結清單中隻存儲了指針,沒有儲存實際的資料。

頭檔案

#ifndef MYLIST_H_INCLUDED

#define MYLIST_H_INCLUDED

#include 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;

//建立連結清單

MyList * createMyList();

//建立連結清單,帶有相等參數,用于查找

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);

//删除對象,傳回是否删除成功

int myListRemoveDataObject(MyList* const list, void * data);

//長度

int myListGetSize(const MyList * const list);

//列印

void myListOutput(const MyList * const list, void(*pt)(const void * const));

//取得資料

void* myListGetDataAt(const MyList * const list, int index);

//取得第一個資料

void* myListGetDataAtFirst(const MyList * const list);

//取得最後一個資料

void* myListGetDataAtLast(const MyList * const list);

//查找某個資料的位置,如果equal方法為空,比較位址,否則調用equal方法

//如果不存在傳回-1,如果存在,傳回出現的第一個位置

int myListFindDataIndex(const MyList * const list, void * data);

//建立周遊器

MyListIterator* createMyListIterator(const MyList * const list);

//釋放周遊器

void freeMyListIterator(MyListIterator* iterator);

//周遊器是否有下一個元素

int myListIteratorHasNext(const MyListIterator* const iterator);

//傳回周遊器的下一個元素

void * myListIteratorNext(MyListIterator* const iterator);

#endif // MYLIST_H_INCLUDED

源檔案

#include "myList.h"

#include //建立連結清單

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)++;

}

//長度

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;

}

//取得資料

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;

}

//取得第一個資料

void* myListGetDataAtFirst(const MyList * const list)

{

return list->first->data;

}

//取得最後一個資料

void* myListGetDataAtLast(const MyList * const list)

{

return list->last->data;

}

//查找某個資料的位置,如果equal方法為空,比較位址,否則調用equal方法

//如果不存在傳回-1,如果存在,傳回出現的第一個位置

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;

}

//建立連結清單,帶有相等參數,用于查找

MyList * createMySearchList(int(*equal)(void * a, void * b))

{

MyList * re = createMyList();

re->equal = equal;

return re;

}

//建立周遊器

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);

}

//周遊器是否有下一個元素

int myListIteratorHasNext(const MyListIterator* const iterator)

{

return iterator->count < iterator->allSize;

}

//傳回周遊器的下一個元素

void * myListIteratorNext(MyListIterator* const iterator)

{

void * re = iterator->p->data;

iterator->p = iterator->p->next;

(iterator->count)++;

return re;

}

//删除對象,傳回是否删除成功

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;

}

測試檔案

#include #include #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;

//建立并初始化資料

A * data= malloc(sizeof(A)*S);

for (int i=0; i< S; i++)

{

data[i].i=i;

data[i].c=(char)('A'+0);

}

//建立連結清單

MyList * list= createMyList();

//測試三種插入方法

myListInsertDataAtLast( list, &data[0]);

myListInsertDataAtFirst( list, &data[4]);

myListInsertDataAt(list, &data[1], 1 );

//測試查找

int index = myListFindDataIndex(list, &data[2]);

printf("%d\n", index);

index = myListFindDataIndex(list, &data[4]);

printf("%d\n", index);

//輸出

myListOutput(list, ppt );

puts("");

//測試使用疊代器輸出

MyListIterator * it = createMyListIterator(list);

while(myListIteratorHasNext(it))

{

A * pp = myListIteratorNext(it);

printf("%d[%c] ", pp->i, pp->c);

}

puts("");

//釋放疊代器

freeMyListIterator(it);

//釋放連結清單

freeMyList(list);

//釋放資料

free(data);

return 0;

}