码迷,mamicode.com
首页 > 其他好文 > 详细

链表概念与建立

时间:2015-12-02 18:27:17      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

 

我们知道,数组式计算机根据事先定义好的数组类型与长度自动为其分配一连续的存储单元,相同数组的 位置和距离都是固定的,也就是说,任何一个数组元素的地址都可一个简单的公式计算出来,因此这种结 构可以有效的对数组元素进行随机访问。

但若对数组元素进行插入和删除操作, 则会引起大量数据的移动, 从而使简单的数据处理变得非常复杂,低效。

为了能有效地解决这些问题,一种称为“链表”的数据结构得到了广泛应用。

 

 什么是链表:

 链表是一种动态数据结构,他的特点是用一组任意的存储单元(可以是连续的,也可以是不连续的)存放 数据元素。

链表中每一个元素成为 “结点” , 每一个结点都是由数据域指针域组成的, 每个结点中的指针域指向下一 个结点

Head 是 “头指针” , 表示链表的开始, 用来指向第一个结点, 而最后一个指针的指针域为 NULL( 空 地址 ) ,表示链表的结束。

可以看出链表结构必须利用指针才能实现,即一个结点中必须包含一个指针变量,用来存放下一个结点的 地址。 实际上,链表中的每个结点可以用若干个数据和若干个指针。

结点中只有一个指针的链表称为单链表,这 是最简单的链表结构。

在 c++ 中实现一个单链表结构比较简单。例如,可定义单链表结构的最简单形式如下

//定义的结构体
 struct LinkNode{
    int Data;
    struct LinkNode *Next;
};

这里用到了结构体类型。其中, *Next 是指针域,用来指向该结点的下一个结点; Data 是一个整形变量,用来存放结点中的数据。当然, Data 可以是任何数据类型,包括结构体类型或类类型,结构中也可以包含多个数据域,而且有且可以包含两个指针域,包含两个指针域的叫做双向链表。

链表有很多种不同的类型:单向链表双向链表以及双向循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。

链表的创建、输出步骤。单链表的创建过程有以下几步:

1 ) 定义链表的数据结构,结构的好处是能存储不同数据类型的数据;

2 ) 创建一个空表;

3 ) 利用malloc ( )函数向系统申请分配一个节点;

4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新节点接到表尾;

5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;

见实例:

//定义的结构体
 struct LinkNode{
    int Data;
    struct LinkNode *Next;
};


 typedef LinkNode Node;    //定义节点及节点的类型为结构体类型


 //建立单链表
 Node *CreateLinkTable(void){
     Node *Head, *A, *B;
     Head = NULL;           //定义一个头节点,假设它是空的,说明这是个空链表

    //下面给空链表添加节点
     A = B  = (Node*)malloc(sizeof(Node));        //利用malloc()函数向系统内存申请分配一个节点内存空间。    
     printf("请输入一个整数:");
     scanf_s("%d", &A->Data, sizeof(A->Data));   //给节点A的数据域输入数据
     if (Head == NULL){
         Head = A;      //如果是空链表,让 Head 节点指向新节点A,做头节点。A的指针域指向下一节点所在的位置         
     }

     A = (Node*)malloc(sizeof(Node));            // A 继续开辟新的节点空间
     printf("请输入一个整数:");
     scanf_s("%d", &A->Data, sizeof(A->Data));   // 给新开辟的节点A的数据域输入数据
     B->Next =A;                                  //B 的下一节点指针指向新节点 A
     B = A;                                      //旧节点 B 再指向新的节点 A


     A = (Node*)malloc(sizeof(Node));             // A 继续开辟新的节点空间
     printf("请输入一个整数:");
     scanf_s("%d", &A->Data, sizeof(A->Data));    //给新开辟的节点A的数据域输入数据
     B->Next = A;                                  //B 的下一节点指针指向新节点 A
     B = A;                                       //新的变成旧节点 B 再指向新的节点 A


     A = (Node*)malloc(sizeof(Node));             // A 继续开辟新的节点空间
     printf("请输入一个整数:");
     scanf_s("%d", &A->Data, sizeof(A->Data));    //给新开辟的节点A的数据域输入数据
     B->Next = NULL;           //节点指向为空,表示后继再无节点,头节点不再指向新节点,那输入的数据就失效了

     return Head;   // 把头节点返回
 }

单链表的输出过程有以下几步:

1) 找到表头;

2) 若是非空表,输出节点的值成员,是空表则退出;

3 ) 跟踪链表的增长,即找到下一个节点的地址;

4) 转到2 ).

void print(Node *head){     //参数为链表返回的头节点
     Node *Temp = head;      //设置一个节点指针指向头节点,
     while (Temp != NULL){   //如果这个头节点不为空,那就开始输出一个节点的信息
         printf("Temp=%d,  Temp->Data=%d,  Temp->Next=%d \n", Temp, Temp->Data, Temp->Next);
         Temp = Temp->Next;  //指针沿着 Next指针域指向下一个节点再输出
     }
 }
 
下面在源文件中进行调用输出:

int _tmain(int argc, _TCHAR* argv[])
{
    print(CreateLinkTable());

    system("Pause");
    return 0;
}

如图:

技术分享

工作原理流程如下图:

技术分享

链表概念与建立

标签:

原文地址:http://www.cnblogs.com/lfls128/p/5013534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!