zoukankan      html  css  js  c++  java
  • 链表

    有三种链表,单向链表、双向链表、循环链表

      循环链表分为单向和双向两种。没有结束,也没有头和尾。主要遍历问题是避免产生循环:如果没有记住从哪里开始,就会在链表中无限循环下去。

      链表的基本操作:遍历链表、插入删除链表元素。这些问题总是使用单向链表。

      单向链表的重要的一点:维护头指针head和尾指针tail。head丢失会导致链表在内存中丢失。这意味着在进行插入、删除元素操作的时候,如果有必要,必须及时更新链表的head和tail指针。

      C语言实现的链表基本操作中,需要注意更新的是否是“本地拷贝”的问题。如下两个方法,只有后者恰当更新了头指针。在C++中,除了本例中采用的传递指向链表头指针的指针方法外,还可以采用传递引用。

    形参和头指针的更新
     1 bool insertInFront(IntElement *head, int data);
     2 {
     3    IntElement *newElem = new IntElement;
     4    if(!newElem)  return false;
     5    newElem->data = data;
     6    newElem->next = head;
     7    head = newElem;        //Incorrect, head is not update
     8    return true;
     9 }
    10 
    11 bool insertInFront(IntElement **head, int data);
    12 {
    13    IntElement *newElem = new IntElement;
    14    if(!newElem)  return false;
    15    newElem->data = data;
    16    newElem->next = *head;
    17    *head = newElem;        //Correctly updates head
    18    return true;
    19 }
    20 

    栈的链表实现和数组实现

      动态数组:动态数组实现的栈必须能根据需要改变大小。优点在于,数组提供对元素的随机访问。但是栈的操作总是在数据结构的一端进行(栈顶),所以数组的随机访问并不能带来好处。另外数组的动态增长导致的数据迁移可能非常耗时。但是如果采用比较良好的方式来减少数组大小的改变次数,较之链表实现的栈速度更快。

      链表:链表为每个元素动态分配内存,在处理小规模元素时开销可能很大。链表实现的栈比较简单,面试时候应当选择。

    C语言实现基于链表的栈的时候,考虑2个问题:

      1. push、pop函数返回值表征操作是否成功,还是push、和pop的data?

      2. 本地拷贝的问题,更新head,也就是栈指针,也就是指向链表头元素的指针。

    对于第一个问题,C语言实现中,倾向于选择始终让方法返回此操作是否成功。返回的数据则采用这样的方法:传入一个变量的指针。方法可以通过这个指针改变变量的值,从而实现返回数据。

    1 // void *类型泛指栈存储的数据类型,具体可以为int等其他
    2 typedef struct Element{
    3    struct Element *next;
    4    void *data;
    5 }
    6 
    7 bool push(Element **stack, void *data);
    8 bool pop(Element **stack, void **data);
    9 

      另外,栈的实现一般还需要2个函数: bool createStack(Element **stack) 和 bool deleteStack(Element **stack)。createStack只需要简单讲*stack=NULL 既可。后者则需要遍历栈,释放每一个空间。

      在面向对象的语言,如C++中,栈的借口设计就更为简单。creatStack和deleteStack变成了构造函数和析构函数。push和pop也和栈对象绑定,不需要将栈作为传入参数,也不需要返回操作是否成功的错误代码,可以让pop直接返回栈中的数据。因为错误都可以通过抛出异常来实现。struct Element则作为类Stack的类型成员。具体代码参考相关资料。

    链表中插入、删除元素(C语言)

      bool remove ( Element *elem);

      bool insertAfter ( Element *elem, int data);

      后者能够以NULL作为参数调用,实现在链表头前插入。这些函数成功返回true,失败返回false。编写这两个函数的难点是:保证头指针和尾指针都是当前的。

      解决思路是:先写出处理一般链表的代码,之后逐个考虑是否可以满足特殊情况。比如特殊情况有:NULL指针参数,三种可能的链表长度:空、1、2、大于等于3。当链表长度为2时候,remove操作删除第一个元素和删除第二个元素时候head和tail指针的更新。具体参考相关资料。 

  • 相关阅读:
    ASP.NET MVC5+EF6+EasyUI 后台管理系统--任务调度系统解析
    ueditor插入自定义内容和样式
    PHP跨页面传递时session失效
    apache 错误:The system cannot find the file specified.
    Thinkphp5 使用odbc连接到sqlserver
    thinkphp5在URL地址里隐藏模块名
    wamp设置自定义域名访问php网站
    wamp因配置错误而导致apache无法启动的问题
    Jquery 实现input回车时跳转到下一个input元素
    PHP ERROR : Call to undefined function curl_init()
  • 原文地址:https://www.cnblogs.com/younes/p/1675944.html
Copyright © 2011-2022 走看看