zoukankan      html  css  js  c++  java
  • 链式线性表

    链式线性表

                                  学习了顺序线性表后,我开始有一个疑问,每一次的插入和删除都需要大量的移动数据吗,有没有一种方法可以不移动数据呢?这就是本章要学习的新的数据结构,线性表的链式存储方式,记不记得第一章就说过的,对于一种数据结构,其逻辑结构是唯一的,但是它可能对应着多种存储结构。链式结构就是线性表的另外一种存储结构

                                  链式结构是什么样子呢

                                  见过火车吧?火车就是一个车厢扣着一个车厢的,简单的说火车的车厢就相当于单链表的一个节点,这个车厢有什么特点呢,

                                   1.当前车厢的乘客

                                   2.勾着下个车厢的钩子

                                  用数据结构怎么描述火车车厢呢,如下

    1. typedef struct Node  
    2. {  
    3.  int value[MAXSIZE];//数组用来装乘客   
    4.  struct Node * next; //勾着下个车厢的钩子   
    5.    
    6. }Node;   


                                  有了这个车厢我们是不是可以来构造一列火车了

                                  先来创建个火车头,一开始后车头后面一节车厢都没有所以它勾着空气(NULL)

    1. void InitNode(Node * &node)  
    2. {  
    3.     node = (Node *)malloc(sizeof(Node));  
    4.     memset(node->value,0,sizeof(node->value));   
    5.     node->next=NULL;   
    6. }   

                                  接着一节节车厢要接入,那就得创建个插入车厢的方法

    1. void InsertNode(Node *&head,int index,Node *node )  
    2. {  
    3.       
    4.     int nodeIndex=0;  
    5.     Node *ptr=head;  
    6.     if(head->next!=NULL)  
    7.     {     
    8.         while(nodeIndex<index-1&&ptr!=NULL)  
    9.         {  
    10.             ptr=ptr->next;  
    11.             nodeIndex++;   
    12.         }   
    13.         if(ptr!=NULL)  
    14.         {   
    15.             node->next= ptr->next;   
    16.             ptr->next=node;   
    17.         }  
    18.     }  
    19.     else  
    20.     {  
    21.         head->next=node;   
    22.     }   
    23. }   

    上面的算法对于初学者可能不是那么容易看得懂:思路主要是先判断这个链表中是不是只有火车头,如果是的话,那么就直接将火车头的钩子勾住新车厢 (x),如果火车头已经有勾着车厢了,那么找到要插入车厢x的位置的前一个车厢(a),然后把(x)勾住(a)的后一个车厢(b),再让(a)勾住 (x),这样子说是不是晕了,我也晕了,我当时老师也是这么说的,所以也晕了,好吧,看个图就明白了


    x本来要插在a的后面b的前面,所以先让x->b,然后a->x,有的图话好理解多了吧!!!!

                         车厢接入完毕了,现在如果有车厢报废要撤下来呢,应该怎做?这次直接上图

                                 要删除车厢b先把a勾住c,然后把b毁掉,就是这么简单

    算法描述如下

    1. void DeleteNode(Node *&head,int index )  
    2. {  
    3.         int nodeIndex=0;  
    4.         Node *ptr=head;  
    5.         while(nodeIndex<index-1&&ptr!=NULL)  
    6.         {  
    7.             ptr=ptr->next;   
    8.             nodeIndex++;   
    9.         }   
    10.         if(ptr!=NULL)  
    11.         {   
    12.             Node *ptrBeDel=ptr->next;  
    13.             if(ptrBeDel!=NULL)  
    14.             {   
    15.                 ptr->next= ptrBeDel->next;  
    16.                 free(ptrBeDel);   
    17.             }   
    18.         }   
    19. }   


    好了下面贴出完整的代码,不过对于链表的讨论这里还是很简单,还有很多方法是没有实现的,下面的方法有兴趣可以思考下为什么插入车厢后输出的顺序是逆的,怎么让它变成顺序输出?提示:这就是头插入法和尾插入法的区别,由于篇幅有限无法全部多写出来

    1. #include <iostream>  
    2. #include <malloc.h>   
    3. #include <string.h>   
    4. #define MAXSIZE 50   
    5. typedef struct Node  
    6. {  
    7.     int value[MAXSIZE];//数组用来装乘客   
    8.     struct Node * next; //勾着下个车厢的钩子   
    9.       
    10. }Node;    
    11.   
    12. void InitNode(Node * &node)  
    13. {  
    14.     node = (Node *)malloc(sizeof(Node));  
    15.     memset(node->value,0,sizeof(node->value));   
    16.     node->next=NULL;   
    17. }   
    18.   
    19. void CreateNodeList(Node * &head)  
    20. {  
    21.     void InsertNode(Node *&head,int index,Node *node );   
    22.     Node *node;   
    23.     for(int i=1;i<10;i++)  
    24.     {  
    25.         node=(Node *)malloc(sizeof(Node));   
    26.         for(int j=0;j<MAXSIZE;j++)  
    27.         {  
    28.             node->value[j]=i;   
    29.         }   
    30.         node->next=NULL;   
    31.         InsertNode(head,1,node);   
    32.     }   
    33. }   
    34.   
    35. void InsertNode(Node *&head,int index,Node *node )  
    36. {  
    37.       
    38.     int nodeIndex=0;  
    39.     Node *ptr=head;  
    40.     if(head->next!=NULL)  
    41.     {     
    42.         while(nodeIndex<index-1&&ptr!=NULL)  
    43.         {  
    44.             ptr=ptr->next;  
    45.             nodeIndex++;   
    46.         }   
    47.         if(ptr!=NULL)  
    48.         {   
    49.             node->next= ptr->next;   
    50.             ptr->next=node;   
    51.         }  
    52.     }  
    53.     else  
    54.     {  
    55.         head->next=node;   
    56.     }   
    57. }   
    58.   
    59. void DeleteNode(Node *&head,int index )  
    60. {  
    61.         int nodeIndex=0;  
    62.         Node *ptr=head;  
    63.         while(nodeIndex<index-1&&ptr!=NULL)  
    64.         {  
    65.             ptr=ptr->next;   
    66.             nodeIndex++;   
    67.         }   
    68.         if(ptr!=NULL)  
    69.         {   
    70.             Node *ptrBeDel=ptr->next;  
    71.             if(ptrBeDel!=NULL)  
    72.             {   
    73.                 ptr->next= ptrBeDel->next;  
    74.                 free(ptrBeDel);   
    75.             }   
    76.         }   
    77. }   
    78.   
    79.   
    80.   
    81.   
    82. int main()  
    83. {  
    84.     Node *head;  
    85.     InitNode(head);  
    86.     CreateNodeList(head);   
    87.     while(head!=NULL)  
    88.     {  
    89.        std::cout<<"第"<<head->value[0]<<"车厢,"<<"乘客的票号都是"<< head->value[0]<<std::endl;  
    90.        head=head->next;   
    91.     }   
    92.       
    93.     return 0;   
    94. }   
  • 相关阅读:
    6. 数值的拓展
    5. 正则表达式的拓展
    4. 字符串的拓展
    工具篇-NotePad++/JSON格式化
    webpack3.x 学习笔记
    Javascript中的 this
    npm的使用方式
    正则表达式基础
    设计模式之观察者模式
    javascript 原型链, 面向对象
  • 原文地址:https://www.cnblogs.com/timssd/p/4790473.html
Copyright © 2011-2022 走看看