数据结构--链表
2013-10-22 16:29
134 查看
1、概念
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。相比于线性表顺序结构,链表比较方便插入和删除操作。
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必按顺序存储,链表在插入的时候可以达到O⑴的复杂度,比另一种线性表:顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表(顺序表是在计算机内存中以数组的形式保存的线性表,采用顺序存储结构的线性表简称为“
顺序表”)相应的时间复杂度分别是O(logn)和O⑴。链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。
链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。线性表的链式存储表示,有一个缺点就是要找一个数,必须要从头开始找起,十分麻烦。
(1)数组和链表的区别。(很简单,但是很常考,记得要回答全面)
答:C++语言中可以用数组处理一组数据类型相同的数据,但不允许动态定义数组的大小,即在使用数组之前必须确定数组的大小。而在实际应用中,用户使用数组之前有时无法准确确定数组的大小,只能将数组定义成足够大小,这样数组中有些空间可能不被使用,从而造成内存空间的浪费。链表是一种常见的数据组织形式,它采用动态分配内存的形式实现。需要时可以用new分配内存空间,不需要时用delete将已分配的空间释放,不会造成内存空间的浪费。
从逻辑结构来看:数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况,即数组的大小一旦定义就不能改变。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)。
从内存存储来看:(静态)数组从栈中分配空间(用NEW创建的在堆中), 对于程序员方便快速,但是自由度小;链表从堆中分配空间, 自由度大但是申请管理比较麻烦.
从访问方式来看:数组在内存中是连续存储的,因此,可以利用下标索引进行随机访问;链表是链式存储结构,在访问元素的时候只能通过线性的方式由前到后顺序访问,所以访问效率比数组要低。
2、建立链表
Node节点:
3、链表的插入、删除
插入
删除
4、链表反转
5、实验结果
结果如下图:
相关引用:
http://baike.baidu.com/link?url=a_O8HDsC8tCBSpA-QdULYAsSxS0XHLu62QVRfHixy_G8m-l8RMoZnOo353qwnpPo
(链表)
http://baike.baidu.com/link?url=7IhCZcwnZnE-uZOc5vE3hs6Gkc_45JUREtjWOuAQQA1Tieu_nOAmPmXK4FZVBTNv
(顺序表)
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。相比于线性表顺序结构,链表比较方便插入和删除操作。
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必按顺序存储,链表在插入的时候可以达到O⑴的复杂度,比另一种线性表:顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表(顺序表是在计算机内存中以数组的形式保存的线性表,采用顺序存储结构的线性表简称为“
顺序表”)相应的时间复杂度分别是O(logn)和O⑴。链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。
链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。线性表的链式存储表示,有一个缺点就是要找一个数,必须要从头开始找起,十分麻烦。
(1)数组和链表的区别。(很简单,但是很常考,记得要回答全面)
答:C++语言中可以用数组处理一组数据类型相同的数据,但不允许动态定义数组的大小,即在使用数组之前必须确定数组的大小。而在实际应用中,用户使用数组之前有时无法准确确定数组的大小,只能将数组定义成足够大小,这样数组中有些空间可能不被使用,从而造成内存空间的浪费。链表是一种常见的数据组织形式,它采用动态分配内存的形式实现。需要时可以用new分配内存空间,不需要时用delete将已分配的空间释放,不会造成内存空间的浪费。
从逻辑结构来看:数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况,即数组的大小一旦定义就不能改变。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)。
从内存存储来看:(静态)数组从栈中分配空间(用NEW创建的在堆中), 对于程序员方便快速,但是自由度小;链表从堆中分配空间, 自由度大但是申请管理比较麻烦.
从访问方式来看:数组在内存中是连续存储的,因此,可以利用下标索引进行随机访问;链表是链式存储结构,在访问元素的时候只能通过线性的方式由前到后顺序访问,所以访问效率比数组要低。
2、建立链表
Node节点:
private static class Node { int num; Node nextNode; public Node(int num) { this.num = num; nextNode = null; } public Node() { nextNode = null; } } static void printList(Node head) { Node temp = head.nextNode; while (temp != null) { System.out.println("node:" + temp.num); temp = temp.nextNode; } } static Node getNewList() { Node head = new Node();// head一般不存数据,方便删除操作等。 Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); head.nextNode = node1; node1.nextNode = node2; node2.nextNode = node3; node3.nextNode = node4; printList(head); return head; }
3、链表的插入、删除
插入
static void insertNode(Node head, Node data, int index) {// 将temp插入到第index个位置 int i = 0; Node pre = head; Node temp = head.nextNode; while (temp != null) { i++; if (i == index) { pre.nextNode = data; data.nextNode = temp; break; } pre = temp; temp = temp.nextNode; } printList(head); }
删除
static void delete(Node head, int delNum) {// 删除num为delNum的节点 Node pre = head; Node temp = head.nextNode; while (temp != null) { if (temp.num == delNum) { pre.nextNode = temp.nextNode; temp.nextNode = null; temp = pre.nextNode; } else { pre = temp; temp = temp.nextNode; } } printList(head); }
4、链表反转
static void reverse(Node head) {// 链表的反转 if (head == null || head.nextNode == null) { return; } Node firstNode = head.nextNode; Node preNode = head.nextNode; Node curNode = head.nextNode.nextNode; Node nextNode; while (curNode != null) { nextNode = curNode.nextNode; curNode.nextNode = preNode; preNode = curNode; curNode = nextNode; } firstNode.nextNode = null; head.nextNode = preNode; printList(head); }
5、实验结果
public static void main(String[] args) { System.out.println("----------创建链表---------"); Node head = getNewList(); System.out.println("----------将data插入到第二个位置---------"); Node data = new Node(-1); insertNode(head, data, 2); System.out.println("----------删除num为-1的节点-------"); delete(head, -1); System.out.println("----------反转链表-------"); reverse(head); }
结果如下图:
相关引用:
http://baike.baidu.com/link?url=a_O8HDsC8tCBSpA-QdULYAsSxS0XHLu62QVRfHixy_G8m-l8RMoZnOo353qwnpPo
(链表)
http://baike.baidu.com/link?url=7IhCZcwnZnE-uZOc5vE3hs6Gkc_45JUREtjWOuAQQA1Tieu_nOAmPmXK4FZVBTNv
(顺序表)
相关文章推荐
- 重写数据结构--链表
- 【数据结构】之链表(C语言描述)
- 目标:完成数组和链表创建队列,完成其余基本数据结构。
- redis 列表的底层数据结构链表
- 数据结构 线性表 建立单链表 尾插法
- 数据结构链表各种问题
- redis 系列4 数据结构之链表
- 数据结构-Java实现链表
- java数据结构链表,堆栈,队列相关专题分析与扯谈-链表
- 数据结构之链表
- 数据结构上机测试2-1:单链表操作A
- 【2015/11/21】 数据结构学习日志_Day17 双端链表
- Linux内核分析--内核中的数据结构双向链表续【转】
- linux内核数据结构之链表
- Java数据结构-线性表之循环链表
- 数据结构-双向链表-插入排序练习题
- 数据结构分析之——链表
- 【数据结构】之顺序表和链表的比较
- 简单数据结构--链表
- C语言(数据结构) - 链表的基本操作