数据结构之链表

数据结构——链表

 

在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指针的位置,使其指向第一个数据结点。

 

posted @ 2017-05-31 22:32  傻蜗牛  阅读(614)  评论(0编辑  收藏  举报