数据结构(2)链表的应用

链表是一种基础数据结构,它是集合类的抽象数据结构类型中表示数据的合适类型。与数字结构不同之处在于,在链表中插入元素和删除元素都更加方便。

定义:

链表表示的一列元素,由一系列的节点(Node)构成,是一种递归数据结构。节点是一个能够包含任何类型数据的抽象实体,它所包含的指向节点的应用体现了他在链表中的作用。

构造:

 private class Node
        {
            public T Data;
            public Node Next;
            public Node(T data)
            {
                Data = data;
            }
        }

上面的是单向链表,优点是简单高效,但任意删除和增加节点并不方便。这种情况下,就可以使用双向链表等数据结构了。今天我给大家演示的主要是使用单向链表实现栈和队列这两种数据结构。

应用:

1.实现一种泛型栈数据结构

栈的特点是先进后出(FILO),根据这一特点,我们设计时,Push()方法在链表头部插入新节点,Pop()方法取出链表头结点。实现起来非常简单,比起上一篇博文中使用数组来结构化存储数据,使用链表则灵活的多,不再需要我们手动调整栈容量,能够自动的灵活变化大小。

实现代码如下:

class NodeStack<T>:IEnumerable
    {
        private int N;
        private Node first;

        public T firstData()
        {
            return first.Data;
        }
        public int Size()
        {
            return N;
        }
        public void Push(T item)
        {
            N++;
            var oldFirst = first;
            first = new Node(item);
            first.Next = oldFirst;
        }
        public T Pop()
        {
            --N;
            var oldFirst = first;
            first = first.Next;
            return oldFirst.Data;
        }
        private class Node
        {
            public T Data;
            public Node Next;
            public Node(T data)
            {
                Data = data;
            }
        }

        public IEnumerator GetEnumerator()
        {
            var oldFirst = first;
            while (first!=null)
            {
                var node = first;
                first = first.Next;
                yield return node.Data;
            }
            first = oldFirst;
        }
    }

2.实现一种泛型队列

基于链表数据结构实现队列(Queue)也很简单,根据其先进先出特性,设计时,实例变量first指向它的表头,实例变量last指向它的尾节点。enqueue()方法将一个元素添加到表尾,dequeu()方法返回并删除表头。

实现代码如下:

 class NodeQueue<T>:IEnumerable
    {
        private int N;
        private Node first;
        private Node last;
        public bool isEmpty()
        {
            return first == null;
        }
        public int Size()
        {
            return N;
        }
        public void enqueue(T item)
        {
            var oldLast = last;
            last = new Node(item);
            if (isEmpty()) first = last;
            else
                oldLast.Next = last;
            N++;
        }
        public T dequeue()
        {
            N--;
            var oldFirst = first;
            first = first.Next;
            if (isEmpty()) last = null;
            return oldFirst.Data;

        }
        private class Node
        {
            public T Data;
            public Node Next;
            public Node(T data)
            {
                Data = data;
            }
        }

        public IEnumerator GetEnumerator()
        {
            var oldFirst = first;
            while (first != null)
            {
                var node = first;
                first = first.Next;
                yield return node.Data;
            }
            first = oldFirst;
        }
    }

总结:

链表这种数据结构是数组的重要替代方式,这种替代方案已由数十年的历史了。相对而言,链表数据结构更加灵活,后续随着学习的不断加深,会继续补充双向链表和树等相关内容。通过学习链表,对常见的API 类型的实现,能够理解的更灵活,这种简单但灵活高效的结构,让人映像深刻。

时间: 2024-10-29 04:42:29

数据结构(2)链表的应用的相关文章

基本数据结构:链表(list)

copy from:http://www.cppblog.com/cxiaojia/archive/2012/07/31/185760.html 基本数据结构:链表(list) 谈到链表之前,先说一下线性表.线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构. 顺序存储结构就是两个相邻的元素在内存中也是相邻的.这种存储方式的优点是

数据结构之链表单向操作总结

链表是数据结构的基础内容之一,下面就链表操作中的创建链表.打印链表.求取链表长度.判断链表是否为空.查找结点.插入结点.删除结点.逆转链表.连接链表.链表结点排序等进行总结. 1.创建表示结点的类,因为链表操作中需要比较结点,因此结点需要实现comparable接口. public class Node implements Comparable<Node> { private Object data; private Node next; //构造函数 public Node() { thi

数据结构-复杂链表的复杂

题目:请实现函数ComplexListNode*  Clone(ComplexListNode* pHead),复杂一个复杂链表.在复杂链表中,每个节点除了有一个Next指针指向下一个节点外,还有一个Sibling指向链表中的任意节点或者NULL. 分析:第一反应是先复制Next,再复制Sibling.但是这种方式需要两次遍历.时间性不是很好.所以利用一个长链表方式解决时间效率. /* 剑指offer面试题26 */ #include <iostream> #include <cstri

AT&amp;T汇编语言与GCC内嵌汇编,Linux内核数据结构之链表

最近在看<Linux内核源代码情景分析>,作者毛德操.书中刚开始介绍了AT&T汇编语言与GCC内嵌汇编,以及Linux内核数据结构之链表.可惜书中介绍的不够全面.因为推荐大家阅读下面两篇文章.很不错. AT&T汇编语言与GCC内嵌汇编:http://grid.hust.edu.cn/zyshao/Teaching_Material/OSEngineering/Chapter2.pdf. Linux内核数据结构之链表:http://www.cnblogs.com/Anker/p/

数据结构:链表的基本操作(创建,删除,插入,逆序,摧毁)

代码注释比较详细: #include <iostream> #include <cstdlib> using namespace std; struct Node{ int data; Node* next; }; Node* head = NULL; bool create() { head = (Node*)malloc(sizeof(Node)); if(NULL == head) return false; head->data = 0; head->next

数据结构--单向链表

C语言中,我们在使用数组时,会需要对数组进行插入和删除的操作,这时就需要移动大量的数组元素,但在C语言中,数组属于静态内存分配,数组在定义时就必须指定数组的长度或者初始化.这样程序一旦运行,数组的长度就不能再改变,若想改变,就只能修改源代码.实际使用中数组元素的个数也不能超过数组元素的最大长度,否则就会发生下标越界的错误(这是新手在初学C语言时肯定会遇到的问题,相信老师也会反复强调!!!但这种问题肯定会遇到,找半天找不到错误在哪,怪我咯???).另外如果数组元素的使用低于最大长度,又会造成系统资

python实现数据结构单链表

#python实现数据结构单链表 # -*- coding: utf-8 -*- class Node(object): """节点""" def __init__(self, elem): self.elem = elem self.next = None # 节点一开始初始化的时候并不知道下一个元素的地址,所以先设置为空 class SingLinkList(object): """单链表""

数据结构之链表(LinkedList)(三)

数据结构之链表(LinkedList)(二) 环形链表 顾名思义 环形列表是一个首尾相连的环形链表 示意图 循环链表的特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活. 看一样著名的应用场景 我们就可以用环形单链表解决这个问题. 首先我们怎么构建一个环形链表 分析: 1. 先创建第一个节点, 让 first 指向该节点,并形成环形 2. 后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可. 示意图: 代码: // 创建一个Boy类,表示一个节点 cla

数据结构:单向链表系列6--交换相邻两个节点1(交换数据域)

给定一个单向链表,编写函数交换相邻 两个元素 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 7 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 通过观察发现:当输入的与元素个数是单数的时候,最后一位不参与交换

垃圾回收机制和数据结构栈链表

1.垃圾回收机制: (1)没有引用变量指向的对象,就是垃圾. 举例: Test t = new Test(); t=null; 那么之前创建的对象就是垃圾. (2)对象没有被使用是另外一种垃圾. new Test(); new Test().toString(); 区别在于第一个对象很明显没有指向,是垃圾.但是第二个不是,因为他被使用了. 2.回收时机. 通常情况下,要在满了的时候回收. 其次在调用 System.gc();//通常情况下会立刻回收.等效于Runtime.getRuntime.g