• 数据结构之链表


    数据结构——链表

    在c++中,数组对应着一个连续存储的内存块,将同类型的元素一个一个地排列起来,是组织数据的很好的方法。声明数组的同时我们需要告诉编译器数组的大小,以便开辟足够大小的内存。但是,在解决实际问题时,元素的个数通常是不确定的,此时该如何声明数组呢?接下来,我将讲一下链表这个数据结构,它很好的解决了数组大小不易控制的问题。

     

    链表元素通常称为链表结点,每个节点是一个结构体,包含数据域和指针域。指针域链接结点的下一个结点。如果将链表比作一串珠子,头结点head就是绳头,找珠子就要从头结点开始,头结点指向的结点1是链表的第一个数据结点。

    提示:链表的存取 必须 从头指针开始进行,最后一个结点的指针域为空(NULL);头结点的数据域可以不包含任何信息,也可以存储诸如元素个数等附加信息,或者干脆用一个指针代替头结点,如果链表为空,头结点为空。

    链表与结构数组存在很大差别

    1:结构数组中的各元素是连续存放的,而链表中的结点可以不连续存放;

    2:结构数组元素可以通过下标运算或相应指针变量的“移动”进行顺序或随机访问;而链表中结点不便于随机访问,只能从头结点一个一个的顺序访问。

    3:结构数组在定义时就能确定其元素,不能动态增长,链表可以动态的增长。

    下面是最简单的一个结构体的示例

    1 struct student
    2 {
    3     int score;
    4     struct student*next;//指向另一个结构体的指针 
    5 };

    从内存申请结点空间的语句为:

    head=(struct student*)malloc(sizeof(student));

    下面是实现一个最简单的动态单链表的源代码

     1 #include <iostream>
     2 #include <stdlib.h>
     3 #include <string>
     4 using namespace std;
     5 //创建一个结构体 
     6 struct student
     7 {
     8     int score;
     9     struct student*next;//指向另一个结构体的指针 
    10 };
    11 struct student* List_create()
    12 {
    13     struct student *head;
    14     struct student *pnew=NULL;//创建的新结点的地址 
    15     struct student *tail=NULL;//原链最后一个结点的地址
    16     
    17     head=(struct student*)malloc(sizeof(student));
    18     //良好的编程习惯,创建一个指针后转而判断该指针是否为空 
    19     if(head==NULL)
    20     {
    21         cout<<"cannot create it";
    22     }
    23     
    24     head->next=NULL;
    25     tail=head;//先将头结点尾结点设置为一点 
    26     
    27     int s;
    28     
    29     while(1)
    30     {
    31         cin>>s;//输入数据 
    32         if(s)//当数据不为零 
    33         {
    34             pnew=(struct student*)malloc(sizeof(student));//创建一个新结点 
    35             if(pnew==NULL)
    36             {
    37                 cout<<" create error";
    38             }
    39             pnew->score=s;
    40             pnew->next=    NULL;
    41             
    42             tail->next=pnew;//将尾结点的指针指向新结点 
    43             tail=pnew;//将新结点设置为尾结点 
    44         }
    45         else break;
    46     }
    47     //因为到目前为止head中并没有数据,所以我们需要先将head设置为head->next,然后释放 
    48     pnew=head 
    49     head=head->next;
    50     
    51     free(pnew);
    52     return head;
    53 } 
    54 
    55 int main()
    56 {
    57     struct student*a=List_create();
    58     while(1)
    59     {
    60         if(a==NULL)break;
    61         else
    62         {
    63                 cout<<a->score<<endl;
    64         a=a->next;
    65         
    66         }
    67         
    68     }
    69     return 0;
    70 }

    代码分析:首先用head指针动态申请内存创建一个头结点,让头结点的指针域为NULL;而后在while结构中为实际数据申请内存创建结点,用指针pnew指向它,并将用户输入的数据放入该结点的数据域内,设置其指针为NULL,时刻保持尾结点tail指向链表尾部。最后修正head指针的位置,使其指向第一个数据结点。

    每一篇博客,不为别的,证明我的成长。每一次发文,不为别的,证明我严阵以待。蜗牛爬得很慢,却终有一日登上参天大树。因为它热爱。
  • 相关阅读:
    Python笔记 #17# Pandas: Merge
    MVC相关资料收集
    Python笔记 #16# Pandas: Operations
    Least slack time scheduling
    Python笔记 #15# Pandas: Missing Data
    Python笔记 #14# Pandas: Selection
    C++中const引用的是对象的时候只能调用该对象的f()const方法
    模板与泛型编程
    c++中的单例模式
    C/C++异常处理机制
  • 原文地址:https://www.cnblogs.com/agui521/p/6926222.html
Copyright © 2020-2023  润新知