小白学算法1.2——链表
2015-11-17 11:18
323 查看
小白学算法1.2——链表
标签:小白学算法1.什么是链表
链表是一种递归的数据结构,它或者为空,或者指向指向下一个结点。struct node{ int data; node* next; };
看起来很抽象的感觉,就我自己的理解,可以用车链子来模拟链表在计算机中的结构。“链表结点”就是车链子上面的一个个“圆柱结点”,每个“圆柱结点”最多与两个其它“圆柱结点”相连接,如果链条不是环形的,那么头和尾“圆柱结点”只与一个其它的“圆柱结点”相连接
结点一般不仅仅包含数据,还包含指向其它结点的指针或者引用
链表是有方向的,一般分为单向链表和双向链表。单向链表中的结点就像地下党一样,只能上一个找下一个,不能下一个找上一个;双向链表中的结点就像楼梯一样,可以上可以下,但是不能跨越
单向链表一般有一个变量指向链表头,双向链表一般有两个变量指向链表头和尾
链表常见的操作有新建,添加,删除和修改
链表对于空间的利用率很高,是数组重要的替代方式
2.用单向链表实现一个栈
因为链表是动态申请内存的,所以不需要设置链表的大小。我们只需要设置一个head,用它来进行链表的操作即可,node* head = null;
2.1入栈
void push(int mydata) { node* p = (node*)malloc(sizeof(node));//动态申请内存 p->data = mydata; p->next = NULL; if (head == NULL) head = p; else { p->next = head; head = p; } }
malloc需要包含头文件stdlib.h
malloc的作用是在内存中申请一段内存空间,返回值为
void*类型,参数表示申请空间的大小,一般配合
sizeof()函数使用
sizeof()参数一般为数据类型,比如结构体
node,
int
使用
malloc函数的返回值需要强制转化为具体的类型
入栈时如果链表为空,申请一段内存空间,将其作为第一个结点;如果链表不为空,申请一段内存空间并将其放在原先链表头前面
在Java或者C++中可以使用
new来申请空间
2.2出栈
int pop() { int mydata = head->data; node* p = head; head = head->next; free(p);//释放内存 return mydata; }
C/C++语言中自己申请的内存自己释放,malloc和free一一对应,new和delete一一对应
Java不用释放内存
2.3栈是否为空
bool isEmpty() { return head == NULL; }
2.4主函数
该主函数将4~0依次入栈,然后再依次出栈。int main(int argc, char* argv[]) { printf("欢迎访问我的博客:http://blog.csdn.net/xuelabizp\n"); int n = 5; while (n--) { printf("%d\t",n); push(n); } printf("\n"); while (!isEmpty()) { printf("%d\t",pop()); } printf("\n"); return 0; }
运行结果如下:
倒序输出,OK~
3.总结
在结点元素中可以再加一个node*类型的成员,每次push新数值的时候,使得新结点可以指向头结点,头结点可以指向新结点,这就是一个双向链表,当然还需要一个始终指向链表尾巴的tail
链表的删除、插入和修改都需要遍历整个链表,找到删除或者修改的结点或者插入的位置进行操作即可,关键是删除和插入必须要处理好前后结点的关系,可以画矩形图理解
主流语言都有链表模板类,可以直接使用
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构揭秘一
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 数据结构之Treap详解
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总