学习笔记:数据结构(一)
2014-05-08 22:27
113 查看
学习数据结构有几天了,简单回顾总结一下。目前有学到单链表, 双链表, 栈, 队列, 哈希表。单链表和双链表的区别在于指针域,双链表的指针域有两个指针,分别为prev, next , prev指向它的上一个节点,next指向它的下一个节点。链表分为有头(头节点),无头(只有头指针); 循环,非循环(最后一个节点的指针是否指向头,形成环),它们只是在访问和插入上很小的差异,实际上都差不多。单链表一般定义为
链表的操作一般也就增删改查。
抽象数据类型(ADT)理解的不是很深,感觉就是一种封装, 里面有对象和方法,有点c++面类的感觉。下面是对双链表的一种封装。几个基本的方法。
方法的实现
栈(区别与内存中的栈)的特点是先进后出,队列则刚好相反,先进先出, 同现实中的排队一样。所以栈实际实现来说就是一种双链表,只是数据插入的方式只能是头插,访问的话也只能访问头节点的next节点。队列则是尾插。
typedef int elem_t; struct slist { elem_t data; struct slist *next; };双链表就是在单链表的基础上加上了一个指向前一个节点的指针,方便了同时向前向后遍历,相对单链表只能从头开始访问,提高了访问效率。双链表的定义一般为
typedef int elem_t; struct dlist { elem_t data; struct dlist *prev; struct dlist *next; };
链表的操作一般也就增删改查。
抽象数据类型(ADT)理解的不是很深,感觉就是一种封装, 里面有对象和方法,有点c++面类的感觉。下面是对双链表的一种封装。几个基本的方法。
struct node { struct node *prev; struct node *next; char data[1]; /*gcc环境下有零长数组的概念,但其他编译器一般不支持,所以data给了1,给节点申请空间的时候加上你需要的数据域大小即可*/ }; struct dlist { struct node *head; void (*add)(struct dlist *, void *, size_t); void (*add_tail)(struct dlist *, void *, size_t); void (*for_each)(struct dlist *, void (*todo)(struct node *)); /* 这里用到了回调函数,只是传了一个函数指针过来,定义则在你调用的地方即可。下面的cmp也是一样*/ void (*for_each_rev)(struct dlist *, void (*todo)(struct node *)); struct node *(*find)(struct dlist *, const void *, int (*cmp)(const struct node *, const void *)); void (*del)(struct node *); }; void init(struct dlist *); void destroy(struct dlist *);
方法的实现
/*头插*/ static void add(struct dlist *dlist, const void *data, size_t size) { assert(dlist != NULL); assert(data != NULL); struct node *pa = (struct node *)malloc(sizeof(*pa)+size); assert(pa != NULL); memcpy(pa->data, data, size); /* 将数据拷贝到节点中 */ pa->next = dlist->head->next; pa->prev = dlist->head; dlist->head->next = pa; pa->next->prev = pa; } static int is_empty(struct dlist *dlist) { return (dlist->head->next == dlist->head) && (dlist->head->prev == dlist->head); } /* 尾插 */ static void add_tail(struct dlist *dlist, const void *data, size_t size) { assert(dlist != NULL); assert(data != NULL); struct node *pa = (struct node *)malloc(sizeof(*pa) + size); assert(pa != NULL); memcpy(pa->data, data, size); pa->next = dlist->head; pa->prev = dlist->head->prev; dlist->head->prev = pa; pa->prev->next = pa; } /* 顺向遍历 */ static void for_each(struct dlist *dlist, void (*todo)(struct node *node)) { assert(dlist != NULL); struct node *cur = dlist->head->next; for(; cur != dlist->head; cur = cur->next) todo(cur); } /* 反向遍历 */ static void for_each_rev(struct dlist *dlist, void (*todo)(struct node *node)) { assert(dlist != NULL); struct node *cur = dlist->head->prev; for(; cur != dlist->head; cur = cur->prev) todo(cur); } /* 查找 */ static struct node *find(struct dlist *dlist, const void *key, int (*cmp)(const struct node *node, const void *key)) { static struct node *cur = NULL; if (cur == NULL) { cur = dlist->head; } for (cur = cur->next; cur != dlist->head; cur = cur->next) { if (cmp(cur, key)) { return cur; } } return NULL; } /* 删除 */ static void del(struct node *node) { assert(node != NULL); node->prev->next = node->next; node->next->prev = node->prev; node->next = node; node->prev = node; free(node); } /*初始化函数 */ void dlist_init(struct dlist *dlist) { assert(dlist != NULL); dlist->head = (struct node *)malloc(sizeof(*dlist->head)); /* 申请头节点空间 */ assert(dlist->head != NULL); dlist->head->next = dlist->head; /* 初始化头节点 */ dlist->head->prev = dlist->head; dlist->head->data[0] = 0; dlist->add = add; /* 挂载函数 */ dlist->add_tail = add_tail; dlist->for_each = for_each; dlist->for_each_rev = for_each_rev; dlist->find = find; dlist->is_empty = is_empty; dlist->del = del; } void dlist_destroy(struct dlist *dlist) { while(dlist->head->next != dlist->head) del(dlist->head->next); free(dlist->head); }
栈(区别与内存中的栈)的特点是先进后出,队列则刚好相反,先进先出, 同现实中的排队一样。所以栈实际实现来说就是一种双链表,只是数据插入的方式只能是头插,访问的话也只能访问头节点的next节点。队列则是尾插。
相关文章推荐
- UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构
- python 学习笔记(1) 数据结构与运算符
- Lua学习笔记 第十一章 数据结构
- 【数据结构与算法学习笔记】PART1:算法分析(计算,计算模型,大O记号,算法分析,迭代与递归,动态控制)
- 数据结构与算法学习笔记——队列
- 5Java学习笔记之数据结构——字符串String
- 数据结构与算法学习笔记--哈希表
- Redis学习笔记-Redis内部数据结构
- 从零开始系列-R语言基础学习笔记之二 数据结构(一)
- JAVA学习笔记 -- 数据结构
- 【学习笔记----数据结构09-树】
- OpenMesh学习笔记3 半边数据结构
- 【学习笔记----数据结构18-图的遍历】
- 我的OpenCV学习笔记(24):详细讨论OpenCV中的数据结构
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- [文件系统]文件系统学习笔记(四)---常用数据结构
- 2Java学习笔记之数据结构——双向链表
- 【学习笔记】数据结构顺序表,求交并集
- 数据结构基础学习笔记一——尾递归
- 深层次两张图解经典6大排序与6大基础数据结构——学完这些,妈妈再也不用担心我的排序算法与数据结构,学习笔记大放送