城市链表c语言,c语言实现通用数据结构(一):通用链表

这篇博客展示了如何使用C语言从头实现通用链表数据结构,包括链表的创建、插入、删除、查找等功能,并提供了相应的测试案例。此外,还实现了链表迭代器以方便遍历操作。博客内容涵盖了链表的基本操作和内存管理,对于理解C语言数据结构和算法有很好的实践意义。

忽然想起来,大概在两年之前学习C语言的时候,曾经用C语言写过一些通用的数据结构。主要也就实现了链表、队列、椎、HashSet,还有HashMap。当时只是知道标准的C语言中没有这方面的类库,后来才知道有很多第三方的类似这样的类库。废话不多说,先把代码粘过来。

下面实现的是通用链表,注意链表中只存储了指针,没有储存实际的数据。

头文件

/*************************

*** File myList.h

**************************/

#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

源文件

/*************************

*** File myList.c

**************************/

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

}

测试文件

/*************************

*** File main.c

*** test for MyList

**************************/

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

}

/*带头结点头文件 hlinklist.h*/ #include <stdio.h> typedef int datatype; typedef struct link_node { datatype data; struct link_node *next; }node; /*初始化链表*/ node *init() { node *head; head=(node *)malloc(sizeof(node)); head->next=0; return head; } /*尾插法创建个带头结点链表*/ node *creat(node *head) { node *r,*s; int x; r=head; printf("在新链表中输入数据以0结束:"); scanf("%d",&x); while(x) { s=(node*)malloc(sizeof(node)); s->data=x; r->next=s; r=s; scanf("%d",&x); } r->next=0; return head; } /*打印链表的结点值*/ void print(node *head) { node *p; p=head->next; if(!p) printf("链表内容为空!"); else while(p) { printf("%5d",p->data); p=p->next; } printf("\n"); } /*在单链表中查找第i个结点的地址*/ node *find(node *head,int i) { node *p=head; int j=0; if(i<0) {printf("不存在!");return 0;} if(i==0) return head; while(p&&i!=j) { p=p->next; j++; } return p; } /*在带头结点的单链表第i个位置后插入个数*/ node *insert(node *head,int i,datatype x) { node *p,*q; q=find(head,i); if(!q) { printf("插入的位置不存在!\n");return head;} else { p=(node *)malloc(sizeof(node)); p->data=x; p->next=q->next; q->next=p; } return head; } /*在带头结点的单链表中删除个为x的值*/ node *dele(node *head,datatype x) { node *pre=head,*p; p=head; while(p&&p->data!=x) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } return head; } /*把带头结点的单链表倒置(以结点形式 )*/ node *Dao_zhi(node *head) { node *p,*s; p=head->next; head->next=NULL; while(p) { s=p; p=p->next; s->next=head->next; head->next=s; } return head; } /*删除链表中重复的结点 */ node *dele1(node *head) { node *pre,*p,*q; if(head->next==0||!head->next->next) { printf("链表为空!"); return head; } //pre=head->next; q=head->next; while(q) { pre=q; p=q->next; while(p) { while(p&&q->data!=p->data) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } p=pre->next; } q=q->next; } return head; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值